HCTF2018_the_end
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 | #注释头 |
所以我们伪造的_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 | from pwn import * |
(2)_IO_FILE_plus结构体位于libc数据段上可读可写内存处,可以直接修改,但是修改字节数只有5个,按照第一种方法:
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/