Pwntools 的安装及使用

记录一下安装 pwntools 的过程和基本使用

Pwntools 安装

1
pip install pwntools

如果出现下面的 warning

WARNING: The scripts asm, checksec, common, constgrep, cyclic, debug, disablenx, disasm, elfdiff, elfpatch, errno, hex, main, phd, pwn, pwnstrip, scramble, shellcraft, template, unhex, update and version are installed in '/home/yahu/.local/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
1
2
3
4
# 在 .bashrc 文件添加
export PATH=~/.local/bin:$PATH
# 然后 source 相应的文件即可
source ~/.bashrc

这样就可以直接使用 pwntools 自带的工具,如 checksec、cyclic 等

Pwntools 使用

常用工具

checksec

用于查看文件的保护机制、架构信息等

1
2
3
4
5
6
7
$ checksec test

Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)

cyclic

用于随机生成一串有序字符串

1
2
$ cyclic 50
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama

常用 python 模块

环境设置

1
2
# 设置 系统、架构、日志输出等级
context(os='linux', arch='i386/amd64', log_level='debug')

引入程序

1
2
3
4
5
6
7
8
from pwn import * 
# 远程
r = remote('8.8.8.8', 8888)
# 本地
p = process('./test')
# 最终进行交互
r.interactive()
p.interactive()

ELF文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 引入程序文件
def ELF(path : str)
elf = ELF('./test')
= p.elf

# 获取函数地址
addr_func = elf.sym['func_name']
# 获取函数 plt 地址
plt_func = elf.plt['func_name']
# 获取函数 got 地址
got_func = elf.got['func_name']

>>> elf.sym['main']
134514548

发送数据

1
2
3
4
def send(data : bytes)
def sendafter(delim : bytes, data : bytes)
p.sendline(bytes)
p.sendlineafter(bytes, bytes)

接受数据

1
2
3
4
5
p.recv()
p.recv(int)
p.recvline()
p.recvuntil(bytes)
p.recvafter(bytes)

数据处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 将数据打包成 n 位的二进制包
def p8(number : bytes) -> int
p16(bytes)
p32(bytes)
p64(bytes)

>>> p32(114514)
b'R\xbf\x01\x00'

# 将 n 位的二进制包解包成数据
def u8(number : int) -> bytes
u16(int)
u32(int)
u64(int)

>>> u32(b'R\xbf\x01\x00')
114514

其他常用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 格式化字符串漏洞利用
def fmtstr_payload(offset : int , writes : map) -> bytes

# 偏移为1,将地址为2的值修改成3,将地址为6的值修改成7
>>> fmtstr_payload(1, {2 : 3, 6 : 7})
b'%3c%6$lln%4c%7$hhnaa\x02\x00\x00\x00\x06\x00\x00\x00'

# 生成 shellcode 字符串,会随架构设置而生成对应的 shellcode
shellcraft.sh()
shellcraft.i386.sh()
shellcraft.amd64.sh()
shellcraft.arm.sh()

# 将字符串形式的汇编转成机器码
asm()

>>> asm(shellcraft.sh())
b'jhh///sh/bin\x89\xe3h\x01\x01\x01\x01\x814$ri\x01\x011\xc9Qj\x04Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80'

一般流程

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
context(os='linux', arch='i386', log_level='debug')
# r = remote('8.8.8.8', 8888)
p = process('./test')
elf = ELF('./test')

...

p.send(payload)

p.interactive()
作者

Humoooor

发布于

2022-02-05

更新于

2023-10-04

许可协议

评论