一些vmpwn的详细总结
字数 1757 2025-08-20 18:17:07

VMPWN 漏洞利用技术详解

前言

在 CTF 比赛中,VM PWN 题目中的"VM"不是指 VMware 或 VirtualBox 这类传统虚拟机,而是一种解释执行系统或模拟器。这类题目近年来出现频率越来越高,本文将详细总结 VMPWN 中常见的漏洞类型和利用技术,并结合两道典型例题进行深入讲解。

基础知识

VM 结构分析

典型的 VM 题目通常包含以下几个关键部分:

  1. 内存区域划分

    • Stack 段:模拟程序栈
    • Text 段:存储指令代码
    • Data 段:存储数据
  2. 核心功能

    • 指令解析与执行
    • 寄存器操作
    • 内存读写
    • 栈操作
  3. 常见指令

    • 算术运算(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段中的值个数
};

漏洞分析

  1. load 功能

    • 从 data[num] 读取任意地址数据到 data[0]
    • 实现任意地址读
  2. save 功能

    • 将可控值写入 data[num]
    • 实现任意地址写

攻击思路

  1. 利用 save 覆盖 data 段指针为 GOT 表附近地址
  2. 通过 load 泄露 puts 地址
  3. 计算 system 地址并修改 puts@got
  4. 通过可控的 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 表)

关键功能

  • 寄存器操作
  • 内存读写
  • 算术运算

漏洞分析

  1. 内存读取

    reg[v4] = memory[reg[v2]];  // v2可控导致越界读
    
  2. 内存写入

    memory[reg[v2]] = reg[v4];  // v2可控导致越界写
    

攻击思路

  1. 通过越界读泄露 libc 地址:

    • 计算 memory 到 GOT 表的偏移(0x68 = 4*26)
    • 通过寄存器运算得到负索引
  2. 绕过 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 开启:需先泄露地址

调试技巧

  1. 结构体分析

    • 在初始化阶段下断点
    • 观察内存布局和关键指针
  2. 指令跟踪

    • 单步执行每条虚拟指令
    • 观察寄存器和内存变化
  3. 边界检查

    • 测试极端输入值
    • 验证索引范围检查

防御建议

  1. 输入验证

    • 严格检查所有索引值
    • 限制数值范围
  2. 内存隔离

    • 不同段之间添加保护页
    • 使用独立内存空间
  3. 权限控制

    • 只读区域设为不可写
    • 关键数据区域额外保护

总结

VMPWN 题目的核心在于理解虚拟机的架构和指令集,通过逆向分析找出关键漏洞点。常见漏洞包括越界读写、算术运算错误和指令解析问题。利用时通常需要结合信息泄露和内存破坏两个阶段,根据不同的保护机制采取相应的绕过策略。

解题关键步骤:

  1. 逆向分析 VM 结构和指令集
  2. 定位存在漏洞的指令/功能
  3. 设计利用链实现信息泄露
  4. 构造最终的内存破坏payload
  5. 根据保护机制调整利用策略

通过系统性地掌握这些技术,能够有效应对各类 VMPWN 题目挑战。

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 关键结构体 漏洞分析 load 功能 : 从 data[ num] 读取任意地址数据到 data[ 0 ] 实现任意地址读 save 功能 : 将可控值写入 data[ num ] 实现任意地址写 攻击思路 利用 save 覆盖 data 段指针为 GOT 表附近地址 通过 load 泄露 puts 地址 计算 system 地址并修改 puts@got 通过可控的 puts(s) 实现 getshell EXP 关键代码 例题2:OVM 程序保护 开启 FULL RELRO(无法修改 GOT 表) 关键功能 寄存器操作 内存读写 算术运算 漏洞分析 内存读取 : 内存写入 : 攻击思路 通过越界读泄露 libc 地址: 计算 memory 到 GOT 表的偏移(0x68 = 4* 26) 通过寄存器运算得到负索引 绕过 FULL RELRO: 修改 comment 指针(位于 memory 附近) 通过 comment 实现任意地址写 最终劫持 free_ hook EXP 关键代码 通用攻击模式 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 题目挑战。