基本只记录思路,不贴exp
更多PWN基础知识笔记可能在这里
hitcon2016 houoforange
思路:2.23,unsortedbin attack伪造IO_FILE和vtable,要libc.symbols[’_IO_list_all’]
程序可以无限制溢出,从而修改unsorted bin内容,直接把unsortbin的size修改为0x60(small bin),同时修改bk位置为IO_list_all-0x10,从而往任意地址写unsortednom本身地址,因为
unsorted_chunks (av)->bk = bck;#bck即target
bck->fd = unsorted_chunks (av);
然后在这个smallbin中伪造IO_FILE和vtable。IO_FILE需要伪造fp->_mode <= 0,fp->_IO_write_ptr > fp->_IO_write_base,vtable指针地址(chunk_base+???)和vtable中的__overflow地址
当程序再次malloc时,经过unsorted bin第一个chunk(smallbin)不符合,把其放到main_arena对应位置(main_arena+88+0x68,即bin[10],即0x60对应位置),IO_list_all被修改为main_arena+88,因为该_IO_FILE_plus结构有问题,所以会从对应_chain位置(0x68)找到下一个FILE结构体,刚好是0x60 small bin的位置,接着触发malloc corruption(__libc_message->abort->_IO_flush_all_lockp->vtable._overflow)。
[为什么要伪造0x60][https://www.cnblogs.com/shangye/p/6268981.html]
IO_FILE伪造模板2.23:
paylaod=p64(0)*4
payload+=p64(0)+p64(1)#_IO_write_base<_IO_write_ptr
payload+=p64(0)*21
payload+=p64(chunk_base+下面的地址偏移)#vatable
payload+=p64(0)*3+p64(one_gadget+libc_base)
反思:malloc free的过程还不够熟练,IO_FILE不知道找哪个符号
SCTF08 bufoverflow_a
难点:如何泄露heap基址,存在限制时的offbynull,2.24版本vtable劫持(与2.23不同)
libc基址:如果malloc delete时没有特殊操作,通过从unsortedbin拿出可泄露libc基址
heap基址:heap基址一般只在fd_nextsize出现,通过free一个largebin chunk1到unsortedbin里,再申请大于该chunk的chunk,即可把chunk1放到largebin中。然后通过free掉所有chunk,申请一个chunk刚好到chunk1的size位置,再申请一个chunk时,fd_nextsize刚好在这个chunk的data域。
存在限制的offbynull:该题当malloc超过三个堆块时,会使用calloc进型初始化。使用offbynull的向前合并方案一时需要伪造好第一个chunk的fdbk以绕过unlink检查。此时虽成功overlap,但是因为程序存在限制,最终程序记录了三个堆块需要删除一个,还需进行一些操作。参考这里面,最终构成unsortedbin的overlap
vtable劫持:2.24新增检查vtable指针必须在__stop___IO_vtables 和 __start___libc_IO_vtables范围之内参考堆利用unsortedbin方案二,利用__IO_str_jumps这个vtable来绕过。
需要知道elf.symbols[’_IO_list_all’]、elf.symbols[’_IO_file_jumps’]
2.24利用模板:(原理reference未找到)
payload=p64(0)*3+p64(0x61)
payload+=p64(0)+p64(_IO_list_all+libc_base-0x10)#bk
payload+=p64(0)+p64(1)#_IO_write_base < _IO_write_ptr
payload+=p64(0)*21+p64(_IO_file_jumps+libc_base+0xc0)
payload+=p64(one_gadget+libc_base)
2.24不用onegadget
fake_file = p64(0) + p64(0x60)
fake_file += p64(0) + p64(_IO_list_all_addr-0x10) #unsorted bin attack,修改_IO_list_all为main_arena+88
fake_file += p64(0) + p64(1) #_IO_write_base < _IO_write_ptr
fake_file += p64(0) + p64(binsh_addr) #_IO_write_end 、IO_buf_base
fake_file = fake_file.ljust(0xD8,'\x00')
fake_file += p64(_IO_str_jumps_addr - 8)#vtable指针,同时,也作为fake_vtable的__dummy
fake_file += p64(0) + p64(system_addr) #__dummy2、__finish
reference:
反思:
该题构建unsortedbin overlap的过程非常巧妙,有空多点开理解;
heap基址泄露一般要用到largebin,add和delete时不对chunk进行操作时可直接show(不用大块拆小块等技巧),不用进行overlap等操作。
houseoforange多多理解
XCTF 4th-QCTF-2018——Noleak
难点:2.23无回显信息,但是该题不用IO_FILE技术
程序:只有add edit delete,delete存在UAF,edit中存在无限制溢出
考点:通过unlink修改bss段堆指针为shellcode段地址和bss地址,shellcode也写在bss段中;通过unsorted bin attack修改目标地址为unsortbin的地址(main_arena+0x58);再进行部分写获得malloc_hook地址,在该地址上填上shellcode的地址
解决:因为malloc_hook和unsortbin地址相近,通过unsorted bin attack获取到unsortbin地址,其中的0x3c4b20就是main_arena的地址,而__maloc_hook在libc中的地址为0x3c4b10.把低地址修改为\x10,即可获得malloc_hook,对该地址任意写
reference:
纵横杯 wind_farm_panel
难点:无
程序:任意改堆块头数据,造成溢出,无free,与hitcon2016 houoforange基本一样
直接houseof orange改topchunk->size让他进入unsorted bin chunk,然后套路2.23利用IO_FILE即可
DASCTFxBJD Π
难点:plt表破坏(和XCTF华为云专场那个cpp一样),溢出如何用16进制表示3.1415926
程序:程序有一个scanf(“llu”,(float)a),llu可输入八字节,float为四字节,可溢出到隔壁数据
解决:plt破坏,用Ghidra反汇编打开会有更好的观感。但是cpp那道题不可以……
16进制表示float 3.1415926==》0x40490fda