记一次IO_FILE结构体attack
字数 1345 2025-08-29 08:30:05

IO_FILE结构体攻击技术详解

1. IO_FILE结构体概述

IO_FILE是glibc中用于处理文件输入输出的核心结构体,它定义了标准I/O流的所有属性和操作。在Linux系统中,标准输入(stdin)、标准输出(stdout)和标准错误(stderr)都是通过IO_FILE结构体实现的。

1.1 关键结构体成员

struct _IO_FILE {
    int _flags;           // 文件流状态标志
    char* _IO_read_ptr;   // 当前读取位置指针
    char* _IO_read_end;   // 读取缓冲区结束位置
    char* _IO_read_base;  // 读取缓冲区起始位置
    char* _IO_write_base; // 写入缓冲区起始位置
    char* _IO_write_ptr;  // 当前写入位置指针
    char* _IO_write_end;  // 写入缓冲区结束位置
    char* _IO_buf_base;   // 缓冲区起始位置
    char* _IO_buf_end;    // 缓冲区结束位置
    // ... 其他成员
    struct _IO_jump_t *vtable; // 虚函数表指针
};

1.2 标准I/O流的内存位置

在64位系统中,标准I/O流通常位于.bss段:

  • stdout: 0x6020C0
  • stdin: 0x6020D0
  • stderr: 0x6020E0

2. IO_FILE利用原理

通过修改IO_FILE结构体的关键指针,可以控制程序的输入输出行为,实现信息泄露或代码执行。

2.1 利用条件

  1. 能够越界访问到IO_FILE结构体
  2. 能够修改IO_FILE结构体的关键字段
  3. 程序后续会使用被修改的I/O流

2.2 常见利用方式

  1. 修改_IO_read_ptr指向敏感数据区域实现信息泄露
  2. 修改_IO_write_ptr控制写入位置
  3. 伪造vtable实现控制流劫持

3. 实例分析:log_file攻击

3.1 漏洞分析

  1. 存在数组越界漏洞,可通过负数索引访问log_file结构体
  2. log_file是一个IO_FILE结构体,位于wizards数组前两个位置(wizards[-2])
  3. 可以修改log_file+40处(_IO_write_ptr)的位置

3.2 利用步骤

第一步:定位log_file地址

  1. 通过越界访问泄露log_file地址
  2. 计算关键指针的偏移量

第二步:控制IO_FILE结构体

  1. 修改_IO_buf_base指向目标区域
  2. 确保_IO_read_ptr > _IO_read_end以绕过检查
  3. 设置_IO_write_base和_IO_write_end覆盖目标区域

第三步:实现GOT表覆盖

  1. 将_IO_buf_base指向GOT表附近
  2. 通过写入操作修改GOT表项
  3. 本例中将atoi的GOT表项修改为system地址

第四步:触发shell

  1. 输入"sh"字符串
  2. 程序调用atoi("sh")实际执行system("sh")

4. 关键点总结

  1. 结构体布局:必须清楚IO_FILE结构体各字段的偏移量
  2. 指针关系:需要满足_IO_read_ptr < _IO_read_end等条件才能触发特定代码路径
  3. 写入控制:注意_IO_write_ptr会在写入后自动更新,需要精心设计写入位置
  4. 利用链构造:通常需要结合信息泄露和写原语完成完整利用

5. 防御措施

  1. 避免数组越界漏洞
  2. 对IO_FILE结构体关键字段进行保护
  3. 启用RELRO保护防止GOT表被修改
  4. 使用最新的glibc版本(修复了部分IO_FILE相关漏洞)

6. 扩展思考

  1. 如何在没有信息泄露的情况下利用IO_FILE结构体?
  2. 除了修改GOT表,还有哪些利用IO_FILE结构体的方式?
  3. 如何检测和防御IO_FILE结构体攻击?

通过深入理解IO_FILE结构体的内部机制,可以更好地防御此类攻击,同时在CTF比赛中能够快速识别和利用相关漏洞。

IO_ FILE结构体攻击技术详解 1. IO_ FILE结构体概述 IO_ FILE是glibc中用于处理文件输入输出的核心结构体,它定义了标准I/O流的所有属性和操作。在Linux系统中,标准输入(stdin)、标准输出(stdout)和标准错误(stderr)都是通过IO_ FILE结构体实现的。 1.1 关键结构体成员 1.2 标准I/O流的内存位置 在64位系统中,标准I/O流通常位于.bss段: stdout: 0x6020C0 stdin: 0x6020D0 stderr: 0x6020E0 2. IO_ FILE利用原理 通过修改IO_ FILE结构体的关键指针,可以控制程序的输入输出行为,实现信息泄露或代码执行。 2.1 利用条件 能够越界访问到IO_ FILE结构体 能够修改IO_ FILE结构体的关键字段 程序后续会使用被修改的I/O流 2.2 常见利用方式 修改_ IO_ read_ ptr指向敏感数据区域实现信息泄露 修改_ IO_ write_ ptr控制写入位置 伪造vtable实现控制流劫持 3. 实例分析:log_ file攻击 3.1 漏洞分析 存在数组越界漏洞,可通过负数索引访问log_ file结构体 log_ file是一个IO_ FILE结构体,位于wizards数组前两个位置(wizards[ -2 ]) 可以修改log_ file+40处(_ IO_ write_ ptr)的位置 3.2 利用步骤 第一步:定位log_ file地址 通过越界访问泄露log_ file地址 计算关键指针的偏移量 第二步:控制IO_ FILE结构体 修改_ IO_ buf_ base指向目标区域 确保_ IO_ read_ ptr > _ IO_ read_ end以绕过检查 设置_ IO_ write_ base和_ IO_ write_ end覆盖目标区域 第三步:实现GOT表覆盖 将_ IO_ buf_ base指向GOT表附近 通过写入操作修改GOT表项 本例中将atoi的GOT表项修改为system地址 第四步:触发shell 输入"sh"字符串 程序调用atoi("sh")实际执行system("sh") 4. 关键点总结 结构体布局 :必须清楚IO_ FILE结构体各字段的偏移量 指针关系 :需要满足_ IO_ read_ ptr < _ IO_ read_ end等条件才能触发特定代码路径 写入控制 :注意_ IO_ write_ ptr会在写入后自动更新,需要精心设计写入位置 利用链构造 :通常需要结合信息泄露和写原语完成完整利用 5. 防御措施 避免数组越界漏洞 对IO_ FILE结构体关键字段进行保护 启用RELRO保护防止GOT表被修改 使用最新的glibc版本(修复了部分IO_ FILE相关漏洞) 6. 扩展思考 如何在没有信息泄露的情况下利用IO_ FILE结构体? 除了修改GOT表,还有哪些利用IO_ FILE结构体的方式? 如何检测和防御IO_ FILE结构体攻击? 通过深入理解IO_ FILE结构体的内部机制,可以更好地防御此类攻击,同时在CTF比赛中能够快速识别和利用相关漏洞。