2025鹏城杯初赛两道pwn
字数 1651 2025-12-17 12:31:07

2025鹏城杯初赛PWN题解析:myZoo与Pivoting

题目一:pcb5-myZoo

程序概述

myZoo是一个包含多个目录(动物)的PWN题,主要考察格式化字符串漏洞利用和寄存器控制技术。程序提供了bird、dog、cat三个目录功能,每个目录都有特定的执行流程。

关键函数分析

main函数

  • 程序入口点,初始化基本环境
  • 提供了PIE基址信息(gift)

sub_15CE()

  • 显示程序目录结构

sub_1997() - bird()

; 关键汇编代码
mov rax, [rdi]        ; rdi指向ptr1
call rax              ; 关键调用点
  • 控制rax寄存器即可控制程序执行流

sub_1642() - dog()

  • 包含格式化字符串漏洞
  • 漏洞函数:sub_134B(),参数为ptr1+8

sub_180B() - cat()

  • 主要输入点:在ptr1+8位置进行输入
  • 执行:(*((void (__fastcall **)(char *))ptr1 + 6))((char *)ptr1 + 8)
  • 等价于调用sub_13DA((char *)ptr1+8)

漏洞利用分析

1. 格式化字符串漏洞

  • 位置:dog()函数中的sub_134B()
  • 参数:ptr1+8
  • 利用:通过cat()中的输入控制ptr1+8附近内存

2. 执行流控制

  • 每个目录都会执行call rax
  • 通过控制rax和rdx寄存器实现system("/bin/sh")
  • 需要rax=system地址,rdx="/bin/sh"字符串地址

3. 关键挑战

  • 进入cat()后,进入dog()会触发call rax,导致程序退出
  • 需要精心构造payload维持程序稳定

利用步骤

阶段一:泄露libc地址

  1. 进入cat()目录

    • 在ptr1+8处布置格式化字符串payload
    • 精心构造避免程序崩溃
  2. 进入dog()目录

    • 触发格式化字符串漏洞
    • 泄露libc基址
    • 注意:会接收到gift的地址信息
  3. 维持程序稳定

    • 在call rax位置放置ret指令
    • 避免使用leave;ret(会导致目录退出)

阶段二:获取shell

  1. 计算关键地址

    • system函数地址 = libc_base + system_offset
    • "/bin/sh"字符串地址 = libc_base + binsh_offset
  2. 控制寄存器

    • 通过精心构造的payload控制rax为system地址
    • 控制rdx为"/bin/sh"字符串地址
  3. 触发执行

    • 通过合适的目录调用触发system("/bin/sh")

调试技巧

  1. 使用patchelf设置正确的libc版本
  2. 详细记录所有ptr1相关的重要数据
  3. 重点关注内存布局和函数指针变化

题目二:pcb5-Pivoting

程序概述

相对简单的栈迁移题目,主要考察栈溢出和栈迁移技术。

关键函数分析

main函数

  • 程序标准入口

Business函数

  • 存在栈溢出漏洞
  • 溢出长度:0x10字节
  • 函数退出时有leave;ret指令序列

漏洞利用

栈迁移原理

  • 利用leave;ret指令序列:
    • leave = mov rsp, rbp; pop rbp
    • ret = pop rip

利用步骤

  1. 构造溢出payload

    • 填充正常缓冲区
    • 覆盖rbp:指向可控内存区域
    • 覆盖返回地址:leave;ret gadget地址
  2. 布置ROP链

    • 在可控内存区域布置ROP链
    • 实现最终的攻击目标
  3. 触发迁移

    • 通过溢出的leave;ret触发栈迁移
    • 将栈迁移到布置好的ROP链位置

攻击脚本框架

from pwn import *

# 连接设置
context.log_level = 'debug'
p = process('./pivoting')

# 计算偏移
offset = 0x10

# 构造payload
payload = b'A' * offset          # 填充缓冲区
payload += p64(fake_rbp)         # 覆盖rbp
payload += p64(leave_ret_addr)   # 覆盖返回地址

# 发送payload
p.sendline(payload)
p.interactive()

总结与学习要点

myZoo题目关键

  1. 格式化字符串漏洞的定位和利用
  2. 函数指针和寄存器控制技术
  3. 复杂程序流程的逆向分析能力
  4. 维持程序稳定的技巧

Pivoting题目关键

  1. 栈迁移基本原理和技术
  2. leave;ret指令序列的利用
  3. 简单的ROP链构造

通用技能

  1. 使用调试工具(GDB)分析程序
  2. 内存布局的理解和利用
  3. 不同保护机制的绕过思路

这两道题目从简单到复杂,涵盖了PWN题的基本考点,是很好的学习材料。建议在实际环境中复现这些漏洞,加深理解。

2025鹏城杯初赛PWN题解析:myZoo与Pivoting 题目一:pcb5-myZoo 程序概述 myZoo是一个包含多个目录(动物)的PWN题,主要考察格式化字符串漏洞利用和寄存器控制技术。程序提供了bird、dog、cat三个目录功能,每个目录都有特定的执行流程。 关键函数分析 main函数 程序入口点,初始化基本环境 提供了PIE基址信息(gift) sub_ 15CE() 显示程序目录结构 sub_ 1997() - bird() 控制rax寄存器即可控制程序执行流 sub_ 1642() - dog() 包含格式化字符串漏洞 漏洞函数:sub_ 134B(),参数为ptr1+8 sub_ 180B() - cat() 主要输入点:在ptr1+8位置进行输入 执行: (*((void (__fastcall **)(char *))ptr1 + 6))((char *)ptr1 + 8) 等价于调用sub_ 13DA((char * )ptr1+8) 漏洞利用分析 1. 格式化字符串漏洞 位置:dog()函数中的sub_ 134B() 参数:ptr1+8 利用:通过cat()中的输入控制ptr1+8附近内存 2. 执行流控制 每个目录都会执行 call rax 通过控制rax和rdx寄存器实现system("/bin/sh") 需要rax=system地址,rdx="/bin/sh"字符串地址 3. 关键挑战 进入cat()后,进入dog()会触发call rax,导致程序退出 需要精心构造payload维持程序稳定 利用步骤 阶段一:泄露libc地址 进入cat()目录 在ptr1+8处布置格式化字符串payload 精心构造避免程序崩溃 进入dog()目录 触发格式化字符串漏洞 泄露libc基址 注意:会接收到gift的地址信息 维持程序稳定 在call rax位置放置ret指令 避免使用leave;ret(会导致目录退出) 阶段二:获取shell 计算关键地址 system函数地址 = libc_ base + system_ offset "/bin/sh"字符串地址 = libc_ base + binsh_ offset 控制寄存器 通过精心构造的payload控制rax为system地址 控制rdx为"/bin/sh"字符串地址 触发执行 通过合适的目录调用触发system("/bin/sh") 调试技巧 使用patchelf 设置正确的libc版本 详细记录 所有ptr1相关的重要数据 重点关注 内存布局和函数指针变化 题目二:pcb5-Pivoting 程序概述 相对简单的栈迁移题目,主要考察栈溢出和栈迁移技术。 关键函数分析 main函数 程序标准入口 Business函数 存在栈溢出漏洞 溢出长度:0x10字节 函数退出时有leave;ret指令序列 漏洞利用 栈迁移原理 利用leave;ret指令序列: leave = mov rsp, rbp; pop rbp ret = pop rip 利用步骤 构造溢出payload 填充正常缓冲区 覆盖rbp:指向可控内存区域 覆盖返回地址:leave;ret gadget地址 布置ROP链 在可控内存区域布置ROP链 实现最终的攻击目标 触发迁移 通过溢出的leave;ret触发栈迁移 将栈迁移到布置好的ROP链位置 攻击脚本框架 总结与学习要点 myZoo题目关键 格式化字符串漏洞的定位和利用 函数指针和寄存器控制技术 复杂程序流程的逆向分析能力 维持程序稳定的技巧 Pivoting题目关键 栈迁移基本原理和技术 leave;ret指令序列的利用 简单的ROP链构造 通用技能 使用调试工具(GDB)分析程序 内存布局的理解和利用 不同保护机制的绕过思路 这两道题目从简单到复杂,涵盖了PWN题的基本考点,是很好的学习材料。建议在实际环境中复现这些漏洞,加深理解。