论坛首页 蓝队防御建设区 阅读主题

[原创]一条新的glibc IO_FILE利用链:__printf_buffer_as_file_overflow利用分析

279 浏览 11 回复
#1 楼主 2026-06-01 21:09:20
之前听说glibc2.37删除了_IO_obstack_jumps这个vtable。但是在源码里还看到obstack结构体存在,那么glibc2.37真的不能再调用_IO_obstack_jumps的那条链吗?看完本文就知道还可以调用_IO_obstack_jumps那条链的关键部分。但目前这条链只存在glibc2.37,所以现在可能还没有利用场景。在此结合源码和自己的理解和大家分享一下,也感谢roderick师傅和whiter师傅的指导与支持。如果有哪里不对恳请师傅们斧正!在此,我称这条链为house of snake,此利用链与house of apple、house of cat、house of emma等利用一样,利用了修改虚表指针的方法。主要思路就是伪造相关结构体并且修改虚表指针为_IO_printf_buffer_as_file_jumps实现攻击。1.能修改stdout、stdin、stderr其中一个_IO_FILE_plus结构(fastbin attack或tcachebin attack)或劫持 _IO_list_all。(如large bin attack、tcache stashing unlink attack、fastbin reverse into tcache)2.能够触发IO流,执行IO相关函数。3.能够泄露堆地址和libc基址。在 2.24 版本的 glibc 以后,加入了针对 IO_FILE_plus 的 vtable 劫持的检测措施,glibc 会在调用虚函数之前首先检查 vtable 地址的合法性。首先会验证 vtable 是否位于_IO_vtable 段中,如果满足条件就正常执行,否则会调用_IO_vtable_check 做进一步检查。简单来说,如果 vtable 地址是非法的,那么会引发 abort。源码如下:该结构体应该不难理解,不过多赘述。当我们对一个文件对象fp进行操作时,往往会使用到_IO_jump_t结构体内某一函数。源码如下:也就是在_IO_FILE追加了个指向_IO_jump_t结构体的指针。了解存在这个结构体即可。其中FILE就是_IO_FILE_plus,就是在_IO_FILE_plus结构体后追加了个指向__printf_buffer结构体的指针。这个结构体是关键结构体之一,因为本文提及的调用链离不开这个结构体。简单总结一下,就是一个常见的_IO_FILE_plus后面追加了一个结构体指针,我们只要认识到这一点就行了。在此,我们只需要知道有这个结构体即可,不需要过多的探究每个成员的意义。就是在__printf_buffer结构体后追加了一个obstack结构体指针和一个char类型的变量,这个结构体也是关键结构体之一。由上可知,vtable必须合法,在glibc2.37中有一个新的vtable,源码如下:可知,该vtable内只存在两个函数,分别为__printf_buffer_as_file_overflow,__printf_buffer_as_file_xsputn接下来我们先对__printf_buffer_as_file_overflow进行分析。笔者对该利用链分析只关注调用过程,要绕过的条件先按下不表,最后再总结!源码如下:该函数首先堆传入的第一个参数强制类型转换为__printf_buffer_as_file并赋给变量file,然后调用__printf_buffer_as_file_commit函数,该函数源码如下:可以看出该函数通过断言对file结构体中的stream结构体与next结构体中的成员进行一系列判断,然后做一个赋值的操作。可以看到若ch != EOF就调用__printf_buffer_putc,源码如下:可知__printf_buffer_putc只是做了一些指针记录的数值加减的操作,对此我们不用过多关注。然后有判断:if (!__printf_buffer_has_failed (file->next) && file->next->write_ptr == file->next->write_end)就是判断__printf_buffer_as_file结构体中的mode成员是不是__printf_buffer_mode_failed以及file->next->write_ptr == file->next->write_end,我们假设满足这两个条件,会调用__printf_buffer_flush (file->next)这个函数笔者无法直接在源码中找到,但是配合gdb,笔者还是发现了它的蛛丝马迹。
评论区有师傅(id:我超啊)指出该函数其实是__printf_buffer_flush => Xprintf_buffer_flush => Xprintf (buffer_do_flush) (buf) => __printf_buffer_do_flush这样的!事实确实如此。但是我们只需要关注__printf_buffer_do_flush,源码如下:在这里我们关注进入__printf_buffer_flush_obstack函数的这一分支假设满足所有条件进入obstack_1grow宏定义。可以看到里面还有个宏定义,然后又_obstack_newchunk这一个函数。假设满足所有条件,进入CALL_CHUNKFUN这个宏定义,该宏定义的源码如下:可以看到当(((h)->use_extra_arg)不为0时,会调用(*(h)->chunkfun),它的参数是(h)->extra_arg和(size),而我们可以控制(*(h)->chunkfun)与(h)->extra_arg,从而执行system('/bin/sh')。如果各位跟着本文分析到这,估计就豁然开朗了,因为后半部分与_IO_obstack_xsputn的调用链一样。回顾一下整个分析过程并将所有相关结构体,并都看成__printf_buffer_as_file结构体,有以下条件:在__printf_buffer_as_file_overflow函数中:在__printf_buffer_as_file_commit函数中:在__printf_buffer_flush函数中:file->next->mode =__printf_buffer_mode_obstack在__printf_buffer_flush_obstack函数中:buf->base.write_ptr == &buf->ch + 1 <==> file->next.write_ptr == &(file->next) + 0x30 + 1在obstack_1grow宏定义中:本文分析基于amd64下通过FSOP触发。我们知道FSOP 的核心思想就是劫持_IO_list_all 的值来伪造链表和其中的_IO_FILE 项,但是单纯的伪造只是构造了数据还需要某种方法进行触发。FSOP 选择的触发方法是exit函数调用_IO_flush_all_lockp,这个函数会刷新_IO_list_all 链表中所有项的文件流,相当于对每个 FILE 调用 fflus

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-276471.htm
#2 2026-06-01 21:09:20
不是...怎么就只有一行..啊,原来是emoji表情会截断...


最后于 2023-3-14 17:06
被7resp4ss编辑

,原因:
#3 2026-06-01 21:09:20
没有7od一半
#4 2026-06-01 21:09:20
7god
#5 2026-06-01 21:09:20
2.37的关键是增加了Xprintf相关内容,
__printf_buffer_flush => Xprintf_buffer_flush => Xprintf (buffer_do_flush) (buf);  => __printf_buffer_do_flush
#6 2026-06-01 21:09:20
我超啊


2.37的关键是增加了Xprintf相关内容,
__printf_buffer_flush => Xprintf_buffer_flush => Xprintf (buffer_do_f ...

谢谢师傅指出不足点,我修改一下
#7 2026-06-01 21:09:20
师傅,可以教下2.37下调试符号解决方案吗
#8 2026-06-01 21:09:20
sky_123


好牛!给跪了!!
#9 2026-06-01 21:09:20
sky_123


binsh偏移是0x110+0x18,是不是应该下移一格?
#10 2026-06-01 21:09:20
7大,POC.c没了,能重新分享一下吗?
#11 2026-06-01 21:09:20
7resp4ss


好牛!给跪了!!

 7大,POC.c没了,能重新分享一下吗?
#12 2026-06-01 21:09:20
Eagle丶


7大,POC.c没了,能重新分享一下吗?

hello,当初我共享的应该是这个: 27dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6K6K9r3q4J5k6g2)9J5k6i4N6W2K9i4W2#2L8W2)9J5k6h3y4G2L8g2)9J5c8Y4N6p5K9f1W2E0c8$3W2H3

请登录后参与讨论

立即登录 注册账号