一些vmpwn的详细总结
字数 1757 2025-08-20 18:17:07
VMPWN 漏洞利用技术详解
前言
在 CTF 比赛中,VM PWN 题目中的"VM"不是指 VMware 或 VirtualBox 这类传统虚拟机,而是一种解释执行系统或模拟器。这类题目近年来出现频率越来越高,本文将详细总结 VMPWN 中常见的漏洞类型和利用技术,并结合两道典型例题进行深入讲解。
基础知识
VM 结构分析
典型的 VM 题目通常包含以下几个关键部分:
-
内存区域划分:
- Stack 段:模拟程序栈
- Text 段:存储指令代码
- Data 段:存储数据
-
核心功能:
- 指令解析与执行
- 寄存器操作
- 内存读写
- 栈操作
-
常见指令:
- 算术运算(add/sub/mul/div)
- 逻辑运算(and/or/xor)
- 栈操作(push/pop)
- 内存操作(load/save)
- 控制流(jmp/call)
漏洞类型
1. 越界读写漏洞
特征:
- 缺乏对内存/寄存器索引的边界检查
- 可通过精心构造的索引访问任意内存
利用方法:
- 通过越界读泄露关键地址(如 libc 地址)
- 通过越界写覆盖关键数据(如 GOT 表)
2. 算术运算漏洞
特征:
- 整数溢出
- 符号处理错误
- 运算结果未正确截断
利用方法:
- 构造特殊数值绕过检查
- 利用运算结果实现越界访问
3. 指令解析漏洞
特征:
- 指令解析不严谨
- 操作数检查不充分
利用方法:
- 构造非法指令实现非预期行为
- 通过指令混淆绕过保护
例题分析
例题1:ciscn_2019_qual_virtual
程序保护
- 未开启 PIE
- 仅开启 Partial RELRO
关键结构体
struct segment_chunk {
char *segment; // 段指针
unsigned int size; // 段大小
int nop; // stack段中的值个数
};
漏洞分析
-
load 功能:
- 从 data[num] 读取任意地址数据到 data[0]
- 实现任意地址读
-
save 功能:
- 将可控值写入 data[num]
- 实现任意地址写
攻击思路
- 利用 save 覆盖 data 段指针为 GOT 表附近地址
- 通过 load 泄露 puts 地址
- 计算 system 地址并修改 puts@got
- 通过可控的 puts(s) 实现 getshell
EXP 关键代码
# 初始化
rl("Your program name:\n")
sl(b'/bin/sh\x00')
# 构造payload
payload = b'push push save push load push add push save'
sl(payload)
# 栈数据布局
content = b'4210896 -3 -21 -193680 -21'
sl(content)
例题2:OVM
程序保护
- 开启 FULL RELRO(无法修改 GOT 表)
关键功能
- 寄存器操作
- 内存读写
- 算术运算
漏洞分析
-
内存读取:
reg[v4] = memory[reg[v2]]; // v2可控导致越界读 -
内存写入:
memory[reg[v2]] = reg[v4]; // v2可控导致越界写
攻击思路
-
通过越界读泄露 libc 地址:
- 计算 memory 到 GOT 表的偏移(0x68 = 4*26)
- 通过寄存器运算得到负索引
-
绕过 FULL RELRO:
- 修改 comment 指针(位于 memory 附近)
- 通过 comment 实现任意地址写
- 最终劫持 free_hook
EXP 关键代码
# 泄露libc地址
opcode(0x10, 0, 0, 26) # mov reg[0],26
opcode(0x80, 2, 1, 0) # reg[2]=reg[1]-reg[0]
opcode(0x30, 4, 0, 2) # mov reg[4],memory[reg[2]]
# 修改comment指针
opcode(0x10, 0, 0, 8)
opcode(0x80, 2, 1, 0)
opcode(0x40, 4, 0, 2) # memory[reg[2]] = reg[4]
# 最终劫持
rl("HOW DO YOU FEEL AT OVM?")
s(b'/bin/sh\x00' + p64(system))
通用攻击模式
1. 信息泄露阶段
- 通过越界读获取关键地址
- 常用目标:
- libc 地址(通过 GOT 表)
- heap 地址
- stack 地址
2. 内存破坏阶段
- 通过越界写修改关键数据
- 常用目标:
- GOT 表(Partial RELRO)
- hook 函数(__malloc_hook, __free_hook)
- 函数返回地址
3. 控制流劫持
- 根据保护机制选择不同策略:
- Partial RELRO:直接修改 GOT 表
- FULL RELRO:通过其他可写区域间接控制
- PIE 开启:需先泄露地址
调试技巧
-
结构体分析:
- 在初始化阶段下断点
- 观察内存布局和关键指针
-
指令跟踪:
- 单步执行每条虚拟指令
- 观察寄存器和内存变化
-
边界检查:
- 测试极端输入值
- 验证索引范围检查
防御建议
-
输入验证:
- 严格检查所有索引值
- 限制数值范围
-
内存隔离:
- 不同段之间添加保护页
- 使用独立内存空间
-
权限控制:
- 只读区域设为不可写
- 关键数据区域额外保护
总结
VMPWN 题目的核心在于理解虚拟机的架构和指令集,通过逆向分析找出关键漏洞点。常见漏洞包括越界读写、算术运算错误和指令解析问题。利用时通常需要结合信息泄露和内存破坏两个阶段,根据不同的保护机制采取相应的绕过策略。
解题关键步骤:
- 逆向分析 VM 结构和指令集
- 定位存在漏洞的指令/功能
- 设计利用链实现信息泄露
- 构造最终的内存破坏payload
- 根据保护机制调整利用策略
通过系统性地掌握这些技术,能够有效应对各类 VMPWN 题目挑战。