vm_pwn
字数 1423 2025-08-30 06:50:12

AVM虚拟机PWN技术分析文档

1. 题目概述

本文档以CISCN 2025 PWN题目"avm"为例,详细分析虚拟机类PWN题的解题思路和技术要点。该题目实现了一个自定义指令集的虚拟机,与普通虚拟机逆向不同,它虚拟出了一套完整的32位指令集架构。

2. 虚拟机架构分析

2.1 指令格式

  • 指令长度为32位固定长度
  • 指令指针(IP)每次执行后增加4字节
  • 指令高4位(31-28位)为操作码(opcode)
  • 剩余28位(27-0位)为操作数

2.2 关键指令分析

2.2.1 算术运算指令

格式:reg1 = reg2 + reg3(加减乘除、异或、与等操作格式相同)

2.2.2 特殊指令

  1. mov_out指令

    • 功能:将寄存器reg1的值写入内存(基址 + reg2 + offset)
    • 特点:offset为12位,可访问0x1000内存空间
    • 漏洞:内存范围检查只取一个字节(BYTE2(v3)),存在栈溢出
  2. mov_in指令

    • 功能:从内存(基址 + reg2 + offset)读取值到寄存器reg1
    • 特点:同样存在栈溢出漏洞

2.3 指令结构体

在IDA中可导入以下结构体表示指令格式:

struct instruction {
    unsigned int opcode : 4;  // 高4位
    unsigned int reg1 : 4;    // 寄存器1
    unsigned int reg2 : 4;    // 寄存器2
    unsigned int reg3 : 4;    // 寄存器3
    unsigned int offset : 12; // 12位偏移量
    unsigned int unused : 4;  // 未使用
};

3. 漏洞利用分析

3.1 漏洞点

  • mov_out和mov_in指令存在栈溢出漏洞
  • 可利用这两个指令进行越界读写

3.2 利用思路

由于题目没有提供put函数泄漏libc,且缺少pop_rdi_ret指令,因此采用以下策略:

  1. 利用栈上已有的libc相关地址计算基址
  2. 通过越界读写控制程序执行流

3.3 详细利用步骤

3.3.1 获取libc基址

  1. 内存高地址处存在libc相关地址,固定偏移为0x3cf211
  2. 计算目标地址偏移:0x7fffffffd528 - 0x7fffffffd090 = 0x498
  3. 使用mov_in指令指定offset为0x498,将该地址读入寄存器
  4. 通过减法指令减去固定偏移0x3cf211得到libc_base

3.3.2 写入固定偏移值

  1. 输入opcode对应内存偏移:0x7fffffffd1b0 - 0x7fffffffd090 = 0x120
  2. 利用溢出将固定偏移值0x3cf211传入寄存器

3.3.3 劫持执行流

  1. 确定run函数返回地址偏移:0x7fffffffd1a8 - 0x7fffffffd090 = 0x118
  2. 使用mov_out指令覆盖返回值
  3. 也可覆盖main函数返回值(0x7fffffffddc8)

4. EXP编写

4.1 利用步骤

  1. 使用mov_in指令越界读取输入值到寄存器
  2. 使用sub/add指令计算所需值
  3. 使用mov_out指令越界写入,将pop_rdi和system地址写入返回地址
  4. 等待指令执行完毕(报错)退出run函数时劫持执行流

4.2 关键代码逻辑

# 伪代码示例

# 1. 读取libc地址到寄存器
payload += mov_in(reg1, reg2, offset=0x498)

# 2. 减去固定偏移得到libc_base
payload += sub(reg1, reg1, offset=0x3cf211)

# 3. 计算system地址并写入返回地址
payload += add(reg2, reg1, offset=system_offset)
payload += mov_out(reg2, reg3, offset=0x118)

# 4. 写入"/bin/sh"字符串地址
payload += add(reg3, reg1, offset=binsh_offset)
payload += mov_out(reg3, reg4, offset=0x120)

5. 总结

  1. 该题目展示了完整虚拟机逆向分析的流程
  2. 关键点在于理解自定义指令集格式和内存布局
  3. 利用思路依赖于对越界读写漏洞的精准控制
  4. 在没有直接泄漏函数的情况下,利用已有内存信息计算关键地址
  5. 最终通过覆盖返回地址获得shell

6. 扩展思考

  1. 如何防御此类虚拟机漏洞?

    • 严格检查内存访问边界
    • 对指令格式进行更严格的验证
    • 使用地址随机化增加利用难度
  2. 类似题目可能的变种:

    • 增加指令集复杂度
    • 引入更多保护机制
    • 改变内存布局方式
  3. 进一步研究方向:

    • 自动化分析虚拟机指令集
    • 通用化漏洞利用技术
    • 虚拟机逃逸技术
AVM虚拟机PWN技术分析文档 1. 题目概述 本文档以CISCN 2025 PWN题目"avm"为例,详细分析虚拟机类PWN题的解题思路和技术要点。该题目实现了一个自定义指令集的虚拟机,与普通虚拟机逆向不同,它虚拟出了一套完整的32位指令集架构。 2. 虚拟机架构分析 2.1 指令格式 指令长度为32位固定长度 指令指针(IP)每次执行后增加4字节 指令高4位(31-28位)为操作码(opcode) 剩余28位(27-0位)为操作数 2.2 关键指令分析 2.2.1 算术运算指令 格式: reg1 = reg2 + reg3 (加减乘除、异或、与等操作格式相同) 2.2.2 特殊指令 mov_ out指令 : 功能:将寄存器reg1的值写入内存(基址 + reg2 + offset) 特点:offset为12位,可访问0x1000内存空间 漏洞:内存范围检查只取一个字节(BYTE2(v3)),存在栈溢出 mov_ in指令 : 功能:从内存(基址 + reg2 + offset)读取值到寄存器reg1 特点:同样存在栈溢出漏洞 2.3 指令结构体 在IDA中可导入以下结构体表示指令格式: 3. 漏洞利用分析 3.1 漏洞点 mov_ out和mov_ in指令存在栈溢出漏洞 可利用这两个指令进行越界读写 3.2 利用思路 由于题目没有提供put函数泄漏libc,且缺少pop_ rdi_ ret指令,因此采用以下策略: 利用栈上已有的libc相关地址计算基址 通过越界读写控制程序执行流 3.3 详细利用步骤 3.3.1 获取libc基址 内存高地址处存在libc相关地址,固定偏移为0x3cf211 计算目标地址偏移:0x7fffffffd528 - 0x7fffffffd090 = 0x498 使用mov_ in指令指定offset为0x498,将该地址读入寄存器 通过减法指令减去固定偏移0x3cf211得到libc_ base 3.3.2 写入固定偏移值 输入opcode对应内存偏移:0x7fffffffd1b0 - 0x7fffffffd090 = 0x120 利用溢出将固定偏移值0x3cf211传入寄存器 3.3.3 劫持执行流 确定run函数返回地址偏移:0x7fffffffd1a8 - 0x7fffffffd090 = 0x118 使用mov_ out指令覆盖返回值 也可覆盖main函数返回值(0x7fffffffddc8) 4. EXP编写 4.1 利用步骤 使用mov_ in指令越界读取输入值到寄存器 使用sub/add指令计算所需值 使用mov_ out指令越界写入,将pop_ rdi和system地址写入返回地址 等待指令执行完毕(报错)退出run函数时劫持执行流 4.2 关键代码逻辑 5. 总结 该题目展示了完整虚拟机逆向分析的流程 关键点在于理解自定义指令集格式和内存布局 利用思路依赖于对越界读写漏洞的精准控制 在没有直接泄漏函数的情况下,利用已有内存信息计算关键地址 最终通过覆盖返回地址获得shell 6. 扩展思考 如何防御此类虚拟机漏洞? 严格检查内存访问边界 对指令格式进行更严格的验证 使用地址随机化增加利用难度 类似题目可能的变种: 增加指令集复杂度 引入更多保护机制 改变内存布局方式 进一步研究方向: 自动化分析虚拟机指令集 通用化漏洞利用技术 虚拟机逃逸技术