返回博客
RESEARCH NOTE 001GLIBC / FSOP

house_of_snake:
一条高版本 Glibc IO 调用链

分析 glibc 2.37 中 _IO_printf_buffer_as_file_jumps 如何重新抵达 obstack 的关键调用路径。

01

前言

glibc 2.37 删除了 _IO_obstack_jumps 这个 vtable,但 obstack 结构体仍然存在。沿着新加入的 printf buffer 路径继续追踪,仍然可以抵达这条调用链的关键部分。

house of snake 调用链调试结果
FIG. 01 在 GDB 中验证伪造结构体后的控制流
02

利用概览

这条链与 house of apple、house of cat 等利用思路类似,核心仍是伪造相关结构体,并将虚表指针修改为 _IO_printf_buffer_as_file_jumps。

FSOPOVERFLOWBUFFER FLUSHOBSTACK
03

调用链分析

在 glibc 2.24 之后,虚函数调用前会验证 vtable 是否位于合法的 _IO_vtable 段中。glibc 2.37 新增的合法虚表给出了新的入口:

C / GLIBC 2.37
static const struct _IO_jump_t _IO_printf_buffer_as_file_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, NULL), JUMP_INIT(overflow, __printf_buffer_as_file_overflow), JUMP_INIT(underflow, NULL), JUMP_INIT(xsputn, __printf_buffer_as_file_xsputn), // ... };

当 FSOP 触发 _IO_overflow,控制流进入 __printf_buffer_as_file_overflow。满足 buffer mode 与指针约束后,flush 分支最终抵达 _obstack_newchunk。

GDB 中 vtable 偏移与调用位置
FIG. 02 vtable 指针 +0x18 对应的 overflow 调用位置
04

完成调用链的必要条件

  • 01

    file->next->mode 必须设置为 __printf_buffer_mode_obstack。

  • 02

    stream 与 next buffer 的 write base、write ptr 和 write end 需要保持一致。

  • 03

    控制 obstack 的 chunkfun 与 extra_arg,最终获得目标调用。

INDEXED ENTRY / 012023.04.09house_of_snake:一条高版本 Glibc IO 调用链