理解程序
checksec:
开启了全保护 64位
IDA64查看,标记函数:
add函数:
正常的malloc
edit:
未限制编辑字节数,存在堆溢出
show:
正常的show出来
delete:
将free指针给清零,也没有什么漏洞
同时:
输入5会跳转到一个函数
这道题的libc版本为2.39,版本较高,存在一个堆溢出,想法是先利用堆溢出泄露堆地址,再用堆地址得到unsorted bin泄露libc 再借助libc的environ泄露栈地址修改返回的函数 获得shell
先是利用堆溢出泄露堆地址:
1 | add(0, 0x18) |
利用堆溢出修改chunk1的size位 利用堆块重叠把位于tcache的chunk2的加密堆地址泄露出来 再解密
得到了堆地址,也相当于得到了tcache_perthread_struct的位置,接下来就再利用堆溢出修改chunk2的fd指向,来申请到该位置的chunk:
1 | payload = b'a' * (0x20) + p64(0) + p64(0xf1) + p64(((heap_base) >> 12) ^ (heap_base + 0x10)) |
此时chunk6为tcache_perthread_struct的地址
接下来是泄露libc的环节,通过chunk6修改0x80的tcache bin为满并且将0x90大小的堆地址设置为一个空区域,方便接下来泄露
1 | payload2 = flat({8:0x0007000000000000,0x80+(9-2)*8:heap_base+0x500},filler=b'\x00') |
然后是利用environ泄露栈地址,直接再次修改chunk6的entries为environ一块就行:
1 | payload3 = flat({8:0x0001000000000000,0x80+(9-2)*8:libc.sym['environ']-0x6678},filler=b'\x00') |
顺便找出泄露的栈地址和要修改的退出函数的偏移
最后是利用得到的栈地址偏移再次改entries,往其中写入rop链(注意堆地址申请要求16字节对齐,要补齐)
总exp:
1 | from pwn import * |