教练,我还想用IO
IO的利用在现在的pwn题里越来越常见夜越来越多了,虽然house of orange已经是angelboy大神在hitcon 2016里提出的了,但是现在还是很常用,这里吐槽一下hitcon2019还是很变态2333,鉴于现在的使用越来越多,这里打算重新学习一下IO,鉴于水平问题,所不及之处或错误之处还望海涵并与我联系,因为之前已经写过一篇IO的,所有对IO不了解的可以先看一下我之前的文章
_IO_FILE结构体利用
这里贴两个链接,以表自己对angelboy师傅的膜拜
1 |
|
house of orange再浅析
house of orange的使用条件
- 可以泄露heap和libc基址
- 可以触发unsorted bin attack
- 有空间让我们伪造FILE结构体
而条件一可以使用unsortedbin和small bin来泄露
原题的难点在于没有提供free函数,而在这种情况下我们该如何制造一个unsorted bin就是难以解决的问题了
解决方法
关于第一个其实有一个小trick,也是一个小机制
我们知道我们malloc块的时候,一般都是在top chunk处切一小块下来给我们,但是当我们申请的大小大于top chunk的size且不会使用mmap拓展(即仅仅是brk)的时候,就会把现在的top chunk变成unsorted bin chunk,此时我们就可以利用这个unsorted bin来泄露了
剩下的就是我们该如何伪造FILE结构体了
而我们知道通过unsorted bin attack 可以向任意地址写如main_arena结构体中的top对应地址值
struct main_arena:
1 |
|
这里就先到此为止,下面我们进入正题,IO的利用
IO来了
我们知道我们日常使用的一个代码比如:
1 |
|
此时系统并不会直接给fd分配一个_IO_FILE指针,其实他分配给FD的是_IO_FILE_plus结构体,
这里也贴一下方便查看
1 |
|
而我们的vtable虚表的结构是这样的
1 |
|
这里要特地提一下,house of orange这道题的环境还是libc2.23,也就意味着我们可以直接更改vtable来改变程序的执行流程hhh
而我们如何跳到vtable_IO_jump_t执行呢,这也很简单,只要构造一个错误就好,我们可以通过unsorted bin attack 来使得malloc出错,从而调用malloc_printerr,然后的调用链如下所示:
1 |
|
此时就可以完成整个调用链来获得shell
而且此时有两种绕过check的构造方式
1 |
|
libc>2.23
方法一
之前的文章也有提及,在libc>2.23之后,glibc就添加了一个新的check函数(_IO_vtable_check)
虽然我们不能随意伪造一个新的结构了,但是libc段上的__libc_IO_vtables还是可以用的,那么我们,而我们只需要更改_IO_str_jumps的虚表_IO_str_overflow即可,然后如下构造即可:
1 |
|
方法二
这个方法来自V神的思考:即修改(_IO_str_finish)链接
1 |
|
利用stdout泄露地址
在没有输出函数的情况下,我们该如何泄露地址呢?
我们只需要劫持stdout指针即可
一般来说是通过UAF,接着改FD的main_arena+88的末位
如果没有则利用攻击global_max_fast的方式去做,然后利用fastbin attack,变成stdout-xx的位置(得有0x7f或者0xff的size,0x7f在0x43的位置,0xff在0x51的位置),下一次申请时就可以从上往下写,改写flag标志位为0xfbad1800固定值,同时修改IO_Write_base末尾为’\x00’,在flag位和IO_Write_base位之间填写的东西可以为任意值,我们的目的是下溢改写IO_Write_base
写到这里就差的不多结束了,因为发现了一篇写的更优秀的文章,为了避免重复造轮子,这里贴出来https://www.anquanke.com/post/id/168802#h2-9