『CTF』IO_FILE 利用入门

admin 2024年5月16日20:14:09评论12 views字数 4988阅读16分37秒阅读模式

点击蓝字,关注我们

日期:2024-05-16
作者:H4y0
介绍:Linux_io_FILE 基础知识。

0x00 前言

_IO_FILE利用已成为CTFPWN题的常规利用思路,逐渐成为基础知识,本文将介绍_IO_FILE的结构及标准I/O流相关内容。

『CTF』IO_FILE 利用入门

0x01 IO_FILE结构

libio.h文件中有如下定义:

struct _IO_FILE {  int _flags;       /* High-order word is _IO_MAGIC; rest is flags. */#define _IO_file_flags _flags  /* The following pointers correspond to the C++ streambuf protocol. */  /* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */  char* _IO_read_ptr;   /* Current read pointer */  char* _IO_read_end;   /* End of get area. */  char* _IO_read_base;  /* Start of putback+get area. */  char* _IO_write_base; /* Start of put area. */  char* _IO_write_ptr;  /* Current put pointer. */  char* _IO_write_end;  /* End of put area. */  char* _IO_buf_base;   /* Start of reserve area. */  char* _IO_buf_end;    /* End of reserve area. */  /* The following fields are used to support backing up and undo. */  char *_IO_save_base; /* Pointer to start of non-current get area. */  char *_IO_backup_base;  /* Pointer to first valid character of backup area */  char *_IO_save_end; /* Pointer to end of non-current get area. */  struct _IO_marker *_markers;  struct _IO_FILE *_chain;  int _fileno;#if 0  int _blksize;#else  int _flags2;#endif  _IO_off_t _old_offset; /* This used to be _offset but it's too small.  */#define __HAVE_COLUMN /* temporary */  /* 1+column number of pbase(); 0 is unknown. */  unsigned short _cur_column;  signed char _vtable_offset;  char _shortbuf[1];  /*  char* _save_gptr;  char* _save_egptr; */  _IO_lock_t *_lock;#ifdef _IO_USE_OLD_IO_FILE#endif#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001  _IO_off64_t _offset;# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T  /* Wide character stream stuff.  */  struct _IO_codecvt *_codecvt;  struct _IO_wide_data *_wide_data;  struct _IO_FILE *_freeres_list;  void *_freeres_buf;# else  void *__pad1;  void *__pad2;  void *__pad3;  void *__pad4;# endif  size_t __pad5;  int _mode;  /* Make sure we don't get into trouble again.  */  char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];#endif};

int _flags; :流的状态标志,例如是否到达文件末尾(EOF),是否出现错误等。

char* _IO_xxxx_xxx; :当前的指针位置,包括读、写、缓冲区。

struct _IO_marker *_markers; :标记链表,用于记录文件位置等信息。

struct _IO_FILE *_chain; :指向下一个文件流结构体的指针,用于维护所有打开文件流的链表。

_IO_FILE 结构体是用于表示一个文件流的基本结构。各种文件结构采用单链表的形式连接起来,通过_IO_list_all访问。_IO_list_all_IO_FILE_plus类型的一个指针。

extern struct _IO_FILE_plus *_IO_list_all;

glibc_IO_list_all指向程序中所有打开的文件流的链表的头部。每个节点都是一个_IO_FILE_plus结构,这个结构扩展了 _IO_FILE 结构,并可能包含一些额外的信息,如虚函数表(vtable)的指针。同时这个链表用于库函数间的通信和管理文件流,例如在程序结束时关闭所有打开的文件流。

struct _IO_FILE_plus{  FILE file;  const struct _IO_jump_t *vtable;};

其中vtable为虚表函数指针,它指向_IO_jump_t_IO_jump_t是一个包含多种IO相关的函数指针的虚函数表。许多函数在调用过程中会调用虚表中的子函数,这也是某些利用方式中用到的点。

借用一张图片:

『CTF』IO_FILE 利用入门

可以更直观地了解其结构。

0x02 标准I/O

_IO_FILE是用于文件操作的核心数据结构,进行文件流的管理并进行文件的I/O操作。在初始情况下存在stdin、stdout、stderr即标准输入流、标准输出流、标准错误流。实际上,在libc中存在3个全局指针stdinstdoutstderr 分别指向_IO_2_1_stdin__IO_2_1_stdout__IO_2_1_stderr_

FILE *stdin = (FILE *) &_IO_2_1_stdin_;FILE *stdout = (FILE *) &_IO_2_1_stdout_;FILE *stderr = (FILE *) &_IO_2_1_stderr_;

也就是说初始情况下存在_IO_2_1_stderr__IO_2_1_stdout__IO_2_1_stdin_ 这三个IO_FILE

# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS)   static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer;  定义了一个锁,用于同步文件流的访问  static struct _IO_wide_data _IO_wide_data_##FD  定义了一个 _IO_wide_data结构体用于宽字符    = { ._wide_vtable = &_IO_wfile_jumps };  _IO_wfile_jumps 是一个函数指针表,用于宽字符操作的函数集合。  struct _IO_FILE_plus NAME     = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD),        &_IO_file_jumps}DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES);DEF_STDFILE(_IO_2_1_stdout_, 1, &_IO_2_1_stdin_, _IO_NO_READS);DEF_STDFILE(_IO_2_1_stderr_, 2, &_IO_2_1_stdout_, _IO_NO_READS+_IO_UNBUFFERED);struct _IO_FILE_plus *_IO_list_all = &_IO_2_1_stderr_;libc_hidden_data_def (_IO_list_all)

重点介绍一下struct _IO_FILE_plus NAME = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), &_IO_file_jumps}:这行代码定义了一个 struct _IO_FILE_plus 类型的变量。这个结构体可能包含 _IO_FILE 结构体和一些附加的数据。FILEBUF_LITERAL 是一个宏,用于初始化 _IO_FILE 结构体。_IO_file_jumps 是另一个函数指针表,用于标准字符操作的函数集合。

#define libio_vtable __attribute__ ((section ("__libc_IO_vtables")))#define JUMP_INIT(NAME, VALUE) VALUE#define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT (dummy2, 0)const struct _IO_jump_t _IO_file_jumps libio_vtable ={  JUMP_INIT_DUMMY,  JUMP_INIT(finish, _IO_file_finish),  JUMP_INIT(overflow, _IO_file_overflow),  JUMP_INIT(underflow, _IO_file_underflow),  JUMP_INIT(uflow, _IO_default_uflow),  JUMP_INIT(pbackfail, _IO_default_pbackfail),  JUMP_INIT(xsputn, _IO_file_xsputn),  JUMP_INIT(xsgetn, _IO_file_xsgetn),  JUMP_INIT(seekoff, _IO_new_file_seekoff),  JUMP_INIT(seekpos, _IO_default_seekpos),  JUMP_INIT(setbuf, _IO_new_file_setbuf),  JUMP_INIT(sync, _IO_new_file_sync),  JUMP_INIT(doallocate, _IO_file_doallocate),  JUMP_INIT(read, _IO_file_read),  JUMP_INIT(write, _IO_new_file_write),  JUMP_INIT(seek, _IO_file_seek),  JUMP_INIT(close, _IO_file_close),  JUMP_INIT(stat, _IO_file_stat),  JUMP_INIT(showmanyc, _IO_default_showmanyc),  JUMP_INIT(imbue, _IO_default_imbue)};libc_hidden_data_def (_IO_file_jumps)

_IO_file_jumps_IO_jump_t结构体的具体实例,每个 JUMP_INIT 宏调用都对应_IO_jump_t中的一个字段,每个字段都代表一个特定的文件操作函数。利用方法中有很多都用到_IO_file_jumps中的函数,实际利用还需要进一步了解函数的具体内容。

『CTF』IO_FILE 利用入门

如图,stderrstdoutstdin分别指向_IO_2_1_stderr__IO_2_1_stdout__IO_2_1_stdin_ 三个结构体。各结构之间通过_chain连接为链表,并通过_IO_list_all访问,若有通过fread等方式创建新的结构体,也会链接到_IO_list_all链表上。

0x03 总结

_IO_FILE的利用方法相对模板化,学会利用方法背后的原理及结构可以事半功倍。

希望这篇文章可以帮助大家看懂IO_FILE结构及原理。

『CTF』IO_FILE 利用入门

免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。

点此亲启

原文始发于微信公众号(宸极实验室):『CTF』IO_FILE 利用入门

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月16日20:14:09
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   『CTF』IO_FILE 利用入门https://cn-sec.com/archives/2747754.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息