劫持vtable修改程序执行流——pwnable seethefile

前置知识

vtable

劫持方法https://www.jianshu.com/p/2e00afb01606
源代码分析https://ray-cp.github.io/archivers/IO_FILE_fclose_analysis
vtable是和file结构体并列的一段内容,是函数指针数组,其中包含了对file的一些操作函数。
以下来自ctf-wiki
在 libc2.23 版本下,32 位的 vtable 偏移为 0x94,64 位偏移为 0xd8
在这里插入图片描述
以下是vtable的实际结构,如图所示,我们需要关注的是close部分。也就是关闭文件时将会调用的函数。
在这里插入图片描述## 劫持原理
以下内容摘自https://www.jianshu.com/p/2e00afb01606
分析close函数,最关键的利用点在这里
在这里插入图片描述
注意到_IO_FINISH(fp)是vtable中的一个函数,而参数又是我们可以控制的,因此可以通过劫持函数和参数来控制执行流。但是前提是通过前面的if,这里检查的是

fp->_IO_file_flags & _IO_IS_FILEBUF

其中_IO_IS_FILEBUF被定义为0x2000.
因此,只需要在file指针的flag位置放上0xffffdfff即可(或者是别的,只要满足fp->_IO_file_flags & _IO_IS_FILEBUF=0来绕过判断都可以)所以程序接下来会执行_IO_FINISH。
因此,总的来说就是布置fp("/bin/sh"地址),fp->flags(0xffffdfff),vtable->finish(system)这三个参数,来实现最终的getshell。

seethefile

这里可以看到的是,程序可以实现读写除了flag之外的其他文件,参考了别人的wp.知道了原来/proc/self/maps可以输出自己虚拟空间的映射方式,从而获得libc基地址。这里注意要输出两次,第一次输出不完。
在最后有个明显的scanf漏洞,注意到fp指针也在bss段上,因此可以考虑溢出劫持fp。具体的布置方法如下
在这里插入图片描述
简单分析下流程:先调用fclose,发现fp->flag & 0x2000不满足上述if条件,就调用finish函数,现在全是system,其中的参数是fp,被我们布置为指向fp->flags的地址,怎么不是/bin/sh啊?因为没办法,第一位必须是flags位,接下来因为分号截断,就成功调用/sh来作为system参数,拿到shell。
在这里插入图片描述
这里比较无语的是为了防止奇奇怪怪的拿到flag,还必须用他的seethefile文件夹下的程序打开才能行…自己探索吧!

<think>好的,用户的问题是关于pwn中vtable利用技术,特别是在C++或二进制漏洞利用中的方法。我需要先回忆一下vtable的基本概念以及它在漏洞利用中的常见攻击方式。 首先,vtable是C++中虚函数表,每个包含虚函数的类都会有这样一个表,其中存储了指向各个虚函数的指针。当对象被创建时,会有一个指向该vtable的指针(vptr)存放在对象的内存布局中。攻击者如果能够篡改这个vptr,就可能控制程序执行程,比如跳转到恶意代码。 接下来,常见的利用方法包括覆盖vptr指向攻击者控制的地址,从而执行任意代码。或者利用内存泄漏获取vtable地址,绕过ASLR。此外,虚函数调用时的索引越界也可能被利用,比如修改索引使其指向非预期的函数。 需要注意,不同编译器(如GCC和MSVC)在vtable布局上可能有差异,这会影响利用方式。缓解措施方面,地址空间布局随机化(ASLR)、控制完整性(CFI)等技术会增加利用难度。 用户可能需要具体的例子,比如如何通过堆溢出修改vptr,或者如何构造fake vtable。此外,引用中的信息提到文件操作的函数指针,可能和IO相关的vtable利用有关,比如篡改FILE结构体中的函数指针,这属于更广泛的vtable利用范畴。 在回答时,应该分点说明技术原理、步骤、示例代码(如果有的话),以及相关的缓解措施。同时,确保使用正确的中文术语,并引用提供的参考资料中的例子,比如引用[1]中的函数指针结构,可以联系到IO vtable的利用。</think>### Pwn中vtable利用技术分析 #### 一、技术原理 虚函数表(vtable)是C++实现多态的核心数据结构,每个包含虚函数的类在内存中拥有对应的虚函数表。对象实例通过虚表指针(vptr)访问虚函数表。攻击者可通过以下漏洞进行利用: 1. **内存破坏漏洞**:堆溢出、UAF(Use-After-Free)等漏洞可篡改vptr 2. **类型混淆漏洞**:错误的对象类型转换导致虚函数调用异常 3. **虚函数表伪造**:构造虚假vtable控制程序 #### 二、利用方法详解 1. **vptr覆盖攻击**(以堆溢出为例) - 步骤: (1) 通过堆溢出覆盖对象的vptr (2) 构造虚假vtable指向攻击者控制的内存 (3) 触发虚函数调用实现控制劫持 - 示例内存布局: ``` | 对象数据区 | vptr(被覆盖) | 堆元数据 | ``` 2. **IO_FILE结构体利用** 标准I/O库的FILE结构体包含函数指针表(类似vtable),如引用[1]所示的: ```c struct _IO_jump_t { _IO_read_t __read; // 如: ssize_t (*)(FILE *, void *, ssize_t) _IO_write_t __write; // ...其他函数指针 }; ``` 通过伪造FILE结构体可劫持`fread`/`fwrite`等操作,常用于FSOP(File Stream Oriented Programming)攻击。 3. **类型混淆攻击** ```c++ class Base { virtual void func(); }; class Derived : public Base { int data; }; // 若将Derived对象强制转换为Base类后删除 Base* obj = new Derived; delete obj; // 可能产生未定义行为的内存布局 ``` #### 三、缓解措施 1. **地址随机化**:ASLR使vtable地址难以预测 2. **虚表保护**:编译器选项(如GCC的`-fvtable-verify`) 3. **内存保护**:DEP/NX防止执行堆栈中的代码 4. **控制完整性**:CFI验证函数调用目标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值