PicoCTF 2025 - PWN & RE 方向全解
字数 2384 2025-08-29 08:30:06

PicoCTF 2025 PWN & RE方向全解教学文档

PIE TIME - 75 pts

题目分析

  • 题目给出源码,允许用户输入一个地址,然后执行该地址的代码
  • 程序存在PIE保护,但泄露了main函数地址
  • 可以通过泄露的main地址计算出PIE基址,进而计算出win函数地址

解题思路

  1. 接收程序泄露的main函数地址
  2. 计算PIE基址:pie_base = leaked_main_addr - main_offset
  3. 计算win函数地址:win_addr = pie_base + win_offset
  4. 输入计算出的win函数地址

关键点

  • PIE保护下函数地址是随机的,但相对偏移固定
  • 通过泄露的地址可以计算出基址

hash-only-1 - 100 pts

题目分析

  • 无源码,提供SSH访问
  • 反编译发现调用system执行md5sum /root/flag.txt
  • 程序有SUID权限

解题思路

  1. 利用环境变量PATH修改命令查找优先级
  2. 创建恶意md5sum脚本:
    #!/bin/sh
    cat /root/flag.txt
    
  3. 添加当前目录到PATH最前面:
    export PATH=/tmp:$PATH
    
  4. 将恶意脚本放在/tmp下并赋予执行权限

关键点

  • SUID程序继承用户环境变量
  • PATH环境变量控制命令查找顺序

hash-only-2 - 200 pts

题目分析

  • flaghasher位于/usr/local/bin
  • 系统路径优先级:sbin > bin > usr/local/bin
  • /sbin和/bin目录下没有md5sum

解题思路

  1. 检查系统路径:
    which -a md5sum
    
  2. 在可写目录(如/tmp)创建符号链接:
    ln -s /bin/cat /tmp/md5sum
    
  3. 修改PATH:
    export PATH=/tmp:$PATH
    

关键点

  • 利用系统路径优先级
  • 符号链接欺骗程序执行其他命令

PIE TIME 2 - 200 pts

题目分析

  • 需要通过格式化字符串漏洞泄露地址
  • 泄露PIE基址后计算win函数地址

解题步骤

  1. 利用格式化字符串泄露栈上PIE地址
  2. 计算PIE基址
  3. 计算win函数地址
  4. 输入win函数地址

关键点

  • 格式化字符串漏洞读取栈数据
  • 计算相对偏移

Echo Valley - 300 pts

题目分析

  • 提供打印flag的函数
  • 存在无限次触发的格式化字符串漏洞
  • 保护全开(ASLR, NX, Stack Canary等)

解题思路

  1. 利用格式化字符串泄露PIE地址
  2. 修改返回地址指向print_flag函数

详细步骤

  1. 发送格式化字符串泄露栈数据:
    payload = b"%p."*20
    
  2. 从泄露数据中识别PIE地址
  3. 计算print_flag函数地址
  4. 构造ROP链覆盖返回地址

关键点

  • 格式化字符串漏洞利用
  • 无直接溢出情况下的控制流劫持

handoff - 400 pts

题目分析

  • 选项2输入idx时使用int接收
  • 检查idx > v1[0]时存在整数溢出漏洞
  • 输入负数可覆盖fgets返回地址

漏洞利用

  1. 输入负数idx(如-1)绕过检查
  2. 覆盖fgets返回地址:
    • 前40字节填充NOP和shellcode
    • 返回地址设置为jmp rax gadget地址

关键点

  • 整数溢出导致缓冲区越界
  • 利用现有gadget(jmp rax)执行shellcode

Flag Hunters - 75 pts

题目分析

  • Python代码分析题
  • 程序逐行读取文本,遇到REFRAIN跳转到指定行
  • 默认refrain=8

解题思路

  1. 在CROWD输入行添加;RETURN 0
  2. 程序split(';')时会先遇到RETURN
  3. 从第0行开始输出而非默认的第8行

关键点

  • 利用字符串分割改变程序流程
  • 注入RETURN指令控制输出顺序

Binary Instrumentation 1 - 200 pts

题目分析

  • 程序调用Sleep API暂停执行
  • Hint建议使用Frida工具

解题步骤

  1. 编写Frida脚本拦截Sleep调用:
    Interceptor.attach(Module.findExportByName("kernel32.dll", "Sleep"), {
        onEnter: function(args) {
            args[0] = ptr(0);
        }
    });
    
  2. 运行程序并注入脚本

关键点

  • Frida动态二进制插桩
  • API函数拦截和参数修改

Tap into Hash - 200 pts

题目分析

  • 提供源码和加密文件
  • 加密流程:
    1. 将flag拼接到区块链字符串中间
    2. 对已知key进行SHA256哈希
    3. 取前16字节作为密钥进行异或加密

解密步骤

  1. 读取加密文件内容
  2. 使用相同key生成SHA256哈希
  3. 取前16字节作为密钥
  4. 异或解密数据

关键代码

def decrypt(encrypted, key):
    sha = hashlib.sha256(key.encode()).digest()
    xor_key = sha[:16]
    return bytes([a ^ b for a, b in zip(encrypted, xor_key)])

ChronoHack - 200 pts

题目分析

  • 基于时间种子的随机数问题
  • 有50次猜测机会
  • 需要预测服务器生成的随机数

解题思路

  1. 利用低延迟连接减少时间差
  2. 同步本地时间与服务器时间
  3. 生成相同种子预测随机数

关键点

  • 伪随机数生成的可预测性
  • 时间同步的重要性

Quantum Scrambler - 200 pts

题目分析

  • "量子纠缠"编码的flag
  • 每个列表的第一个和最后一个元素拼接即为flag内容

解题步骤

  1. 分析编码脚本逻辑
  2. 提取每个列表的首尾元素
  3. 拼接得到原始flag

关键代码

flag = ""
for lst in encoded_data:
    flag += lst[0] + lst[-1]

Binary Instrumentation 2 - 300 pts

题目分析

  • 程序应创建文件并写入flag
  • 使用Windows API函数

解题思路

  1. 使用Frida hook文件操作API:
    Interceptor.attach(Module.findExportByName("kernel32.dll", "WriteFile"), {
        onEnter: function(args) {
            console.log("Writing:", Memory.readUtf16String(args[1]));
        }
    });
    
  2. 拦截WriteFile调用获取flag

关键点

  • Windows API函数拦截
  • 内存数据读取

perplexed - 400 pts

题目分析

  • 输入要求27字符(216位)
  • 校验流程:
    1. 前23字节(184位)与v3循环右移1位比较
    2. 全部匹配且长度正确则成功

解题方法

  1. 使用angr符号执行:
    import angr
    proj = angr.Project("./perplexed")
    state = proj.factory.entry_state()
    simgr = proj.factory.simulation_manager(state)
    simgr.explore(find=lambda s: b"Success" in s.posix.dumps(1))
    
  2. 自动求解满足条件的输入

关键点

  • 符号执行自动化逆向
  • 复杂校验条件的自动化求解

总结

本系列题目涵盖了多种PWN和RE技术:

  • 地址泄露与PIE绕过
  • 环境变量利用
  • 格式化字符串漏洞
  • 整数溢出漏洞
  • 二进制插桩技术
  • 加密算法逆向
  • 符号执行自动化

每种技术都有其独特的应用场景和利用方法,掌握这些技术对于CTF竞赛和二进制安全研究至关重要。

PicoCTF 2025 PWN & RE方向全解教学文档 PIE TIME - 75 pts 题目分析 题目给出源码,允许用户输入一个地址,然后执行该地址的代码 程序存在PIE保护,但泄露了main函数地址 可以通过泄露的main地址计算出PIE基址,进而计算出win函数地址 解题思路 接收程序泄露的main函数地址 计算PIE基址: pie_base = leaked_main_addr - main_offset 计算win函数地址: win_addr = pie_base + win_offset 输入计算出的win函数地址 关键点 PIE保护下函数地址是随机的,但相对偏移固定 通过泄露的地址可以计算出基址 hash-only-1 - 100 pts 题目分析 无源码,提供SSH访问 反编译发现调用system执行 md5sum /root/flag.txt 程序有SUID权限 解题思路 利用环境变量PATH修改命令查找优先级 创建恶意md5sum脚本: 添加当前目录到PATH最前面: 将恶意脚本放在/tmp下并赋予执行权限 关键点 SUID程序继承用户环境变量 PATH环境变量控制命令查找顺序 hash-only-2 - 200 pts 题目分析 flaghasher位于/usr/local/bin 系统路径优先级:sbin > bin > usr/local/bin /sbin和/bin目录下没有md5sum 解题思路 检查系统路径: 在可写目录(如/tmp)创建符号链接: 修改PATH: 关键点 利用系统路径优先级 符号链接欺骗程序执行其他命令 PIE TIME 2 - 200 pts 题目分析 需要通过格式化字符串漏洞泄露地址 泄露PIE基址后计算win函数地址 解题步骤 利用格式化字符串泄露栈上PIE地址 计算PIE基址 计算win函数地址 输入win函数地址 关键点 格式化字符串漏洞读取栈数据 计算相对偏移 Echo Valley - 300 pts 题目分析 提供打印flag的函数 存在无限次触发的格式化字符串漏洞 保护全开(ASLR, NX, Stack Canary等) 解题思路 利用格式化字符串泄露PIE地址 修改返回地址指向print_ flag函数 详细步骤 发送格式化字符串泄露栈数据: 从泄露数据中识别PIE地址 计算print_ flag函数地址 构造ROP链覆盖返回地址 关键点 格式化字符串漏洞利用 无直接溢出情况下的控制流劫持 handoff - 400 pts 题目分析 选项2输入idx时使用int接收 检查 idx > v1[0] 时存在整数溢出漏洞 输入负数可覆盖fgets返回地址 漏洞利用 输入负数idx(如-1)绕过检查 覆盖fgets返回地址: 前40字节填充NOP和shellcode 返回地址设置为jmp rax gadget地址 关键点 整数溢出导致缓冲区越界 利用现有gadget(jmp rax)执行shellcode Flag Hunters - 75 pts 题目分析 Python代码分析题 程序逐行读取文本,遇到REFRAIN跳转到指定行 默认refrain=8 解题思路 在CROWD输入行添加 ;RETURN 0 程序split(';')时会先遇到RETURN 从第0行开始输出而非默认的第8行 关键点 利用字符串分割改变程序流程 注入RETURN指令控制输出顺序 Binary Instrumentation 1 - 200 pts 题目分析 程序调用Sleep API暂停执行 Hint建议使用Frida工具 解题步骤 编写Frida脚本拦截Sleep调用: 运行程序并注入脚本 关键点 Frida动态二进制插桩 API函数拦截和参数修改 Tap into Hash - 200 pts 题目分析 提供源码和加密文件 加密流程: 将flag拼接到区块链字符串中间 对已知key进行SHA256哈希 取前16字节作为密钥进行异或加密 解密步骤 读取加密文件内容 使用相同key生成SHA256哈希 取前16字节作为密钥 异或解密数据 关键代码 ChronoHack - 200 pts 题目分析 基于时间种子的随机数问题 有50次猜测机会 需要预测服务器生成的随机数 解题思路 利用低延迟连接减少时间差 同步本地时间与服务器时间 生成相同种子预测随机数 关键点 伪随机数生成的可预测性 时间同步的重要性 Quantum Scrambler - 200 pts 题目分析 "量子纠缠"编码的flag 每个列表的第一个和最后一个元素拼接即为flag内容 解题步骤 分析编码脚本逻辑 提取每个列表的首尾元素 拼接得到原始flag 关键代码 Binary Instrumentation 2 - 300 pts 题目分析 程序应创建文件并写入flag 使用Windows API函数 解题思路 使用Frida hook文件操作API: 拦截WriteFile调用获取flag 关键点 Windows API函数拦截 内存数据读取 perplexed - 400 pts 题目分析 输入要求27字符(216位) 校验流程: 前23字节(184位)与v3循环右移1位比较 全部匹配且长度正确则成功 解题方法 使用angr符号执行: 自动求解满足条件的输入 关键点 符号执行自动化逆向 复杂校验条件的自动化求解 总结 本系列题目涵盖了多种PWN和RE技术: 地址泄露与PIE绕过 环境变量利用 格式化字符串漏洞 整数溢出漏洞 二进制插桩技术 加密算法逆向 符号执行自动化 每种技术都有其独特的应用场景和利用方法,掌握这些技术对于CTF竞赛和二进制安全研究至关重要。