技术社区
安全培训
技术社群
积分商城
先知平台
漏洞库
历史记录
清空历史记录
相关的动态
相关的文章
相关的用户
相关的圈子
相关的话题
注册
登录
记一次IO_FILE结构体attack
BabyShark
二进制安全
95浏览 · 2025-03-20 13:20
返回文档
记一次IO_FILE结构体attack
平常做题的时候有没有注意到bss段上的这几个数据
这些是标准输出,标准输入,还有一个错误输出,分别对应的文件描述符1,0,2
我们可以看看这个结构体
那么可以看见现在是
未初始化的状态
,这个跟前面的house of orange 的file结构体是同一个,不过我们当时伪造的是vtable的虚函数表,现在我们重点来看前9个字段
_flags
:
这是一个标志位,用于保存文件流的状态信息。它可以包含多个标志,比如文件是以文本模式还是二进制模式打开的,流是可读、可写还是处于错误状态等。
26018464
这个值表示了一组特定的状态标志。
_IO_read_ptr
:
这是一个指针,指向当前从文件流中读取数据的位置。如果文件流是以读取模式打开的,这个指针会在流中向前移动,指示已经读取到哪里。
_IO_read_end
:
这是一个指针,指向文件流中可读缓冲区的末尾。读取操作不能超过这个位置,否则就需要刷新缓冲区或者读取更多的数据。
0x18d0480 "\\300\\004\\215\\001"
表示这个缓冲区末尾的位置和包含的内容。
_IO_read_base
:
这是一个指针,指向文件流中可读缓冲区的开始位置。每次读取操作从这个位置开始,并在
_IO_read_ptr
位置结束。
_IO_write_base
:
这是一个指针,指向文件流中可写缓冲区的开始位置。写操作将数据从这个位置开始写入文件流。
_IO_write_ptr
:
这是一个指针,指向文件流中当前写入数据的位置。它随着写入操作向前移动,指示已经写入的数据位置。
_IO_write_end
:
这是一个指针,指向文件流中可写缓冲区的末尾。写入操作不能超过这个位置,否则就需要刷新缓冲区或者扩展缓冲区。
_IO_buf_base
:
这是一个指针,指向用于文件流的缓冲区的开始位置。这个缓冲区可以用来存储读或写的数据。
_IO_buf_end
:
这是一个指针,指向用于文件流的缓冲区的末尾位置。缓冲区的数据不能超过这个位置。
例题演示
2.35本地
知道了这些我们现在来看一道题目
首先查看一下保护
64位ida载入
两个功能
create函数会创建一个对象并加入到wizards数组中
另一个函数会存在数组越界的问题,当我们输入负数的时候数组就会越界,我们可以看见wizards[-2]的位置就是log_file
这个函数还会把读入的数据打印出来
我们可以修改到log_file + 40处的位置,我们可以看一下log_file结构体
是不是很眼熟,对就是前面说的那个结构体,而他+40处的位置正好是_IO_write_ptr 的位置,也就是我们可以修改这个指针,如果我们能修改到这个结构体,那么我们就可以像打io_stout 一样泄露数据,比如我们可以修改 _IO_read_ptr 为got表,那么下次就会从这里读取数据,并打印出来,那么就可以泄露出libc地址了,当然此时的 _IO_read_end的地址要比 _IO_read_ptr 大,刚刚我们看见的是未初始化的结构体,现在我们给他创建一个对象,进行初始化
那么我们现在修改 _IO_write_ptr 指针指向 这个结构体附近
可以看见两者还是挺近的,我们可以把下标输入为-2那么 _IO_write_ptr指针减去的字节数就是 -50 + 我们输入的字节数
这样之后我们再次看看结构体的内容
那么现在我们就可以修改结构体内容了
注意此时下标用的是0,这样的话 _IO_write_ptr 就不会再减去50,而且因为此时是因为读取完毕了所以 _IO_read_ptr 又加上了0x20
那么我们如法炮制,修改 _IO_write_ptr 为 atoi的got表
虽然想的没问题,但是在实际操作中,会发现, _IO_write_ptr 会保持不变,原因是我们写入完数据之后, _IO_write_ptr 会再次更新,那么就会导致, _IO_write_ptr 再次被覆盖变成 原来的地址+输入的长度。因此直接修改是行不通的。
在glibc源码里面我们可以分析一下
当 _IO_read_ptr < _IO_read_end 的时候就会直接返回,不会执行我们下面的对 _IO_write_ptr 赋值的要求,下面会把 _IO_write_ptr 等一系列指针指向 _IO_buf_base,那么我们控制到 _IO_buf_base即可以控制 _IO_write_ptr了,那么我们就要保证修改完 _IO_buf_base 之后 _IO_read_ptr < _IO_read_end 这个条件不满足,为了能修改到 _IO_buf_base,除此之外,我们还要保证 [ _IO_write_ptr _IO_write_end] _IO_buf_base 位于这两者之间,我们需要知道 _IO_write_ptr 的值那么我们还要泄露 log_file 的地址。
这个login_file + 0x50 中的 0x50 是一个大概,每次加0x20,只要保证第三次修改之后 _IO_read_ptr > _IO_read_end,就行了
得到log_file的真实地址之后,我们就可以修改 _IO_write_base _IO_write_ptr _IO_write_end 了,因为之后 _IO_write_ptr 会被覆盖,所以这里使用 0xdeadbeef 来覆盖
当然现在 _IO_buf_base 的地址不能为 atoi的got表,而是要往下去一点,不然覆盖不到 atoi的got表,而且 _IO_write_end需要取大一点,保证能够正确修改
可以看见我们成功把 _IO_buf_base 处的地址赋值给这些指针
那么接下来继续使 _IO_write_ptr 修改到 atio的got表位置,之后修改atoi got表为system
最后输入 sh就可以拿到shell
EXP
0
人收藏
0
人喜欢
转载
分享
0
条评论
某人
表情
可输入
255
字
评论
发布投稿
热门文章
1
2025ISCC练武区域赛和决赛pwn以及擂台pwn合集
2
通过Elastic EDR看smbexec并进行二次开发Bypass
3
php代码审计篇 - 信呼OA 前台注入分析一
4
D3CTF-d3kshrm(预期&非预期)题解
5
Tomcat解析XML引入的新颖webshell构造方式
近期热点
一周
月份
季度
1
2025ISCC练武区域赛和决赛pwn以及擂台pwn合集
2
通过Elastic EDR看smbexec并进行二次开发Bypass
3
php代码审计篇 - 信呼OA 前台注入分析一
4
D3CTF-d3kshrm(预期&非预期)题解
5
Tomcat解析XML引入的新颖webshell构造方式
暂无相关信息
暂无相关信息
优秀作者
1
T0daySeeker
贡献值:28700
2
一天
贡献值:24800
3
1674701160110592
贡献值:18000
4
1174735059082055
贡献值:15000
5
Yale
贡献值:14000
6
LeeH
贡献值:10000
7
MeteorKai
贡献值:9000
8
姓*户
贡献值:8600
9
Arcueid
贡献值:8000
10
熊猫正正
贡献值:8000
目录
记一次IO_FILE结构体attack
例题演示
2.35本地
EXP
转载
标题
作者:
你好
http://www.a.com/asdsabdas
文章
转载
自
复制到剪贴板