2017-10-11 17:22:24 +07:00
|
|
|
|
# 2.7 Pwntools
|
2017-08-17 21:36:23 +07:00
|
|
|
|
|
2017-10-11 17:22:24 +07:00
|
|
|
|
- [安装](#安装)
|
|
|
|
|
- [模块简介](#模块简介)
|
|
|
|
|
- [使用 Pwntools](#使用-pwntools)
|
|
|
|
|
- [Pwntools 在 CTF 中的运用](#pwntools-在-ctf-中的运用)
|
|
|
|
|
- [参考资料](#参考资料)
|
2017-08-17 21:36:23 +07:00
|
|
|
|
|
2017-10-11 17:22:24 +07:00
|
|
|
|
|
|
|
|
|
Pwntools 是一个 CTF 框架和漏洞利用开发库,用 Python 开发,由 rapid 设计,旨在让使用者简单快速的编写 exp 脚本。包含了本地执行、远程连接读写、shellcode 生成、ROP 链的构建、ELF 解析、符号泄露众多强大功能。
|
2017-08-17 21:36:23 +07:00
|
|
|
|
|
|
|
|
|
## 安装
|
|
|
|
|
|
|
|
|
|
1. 安装binutils:
|
|
|
|
|
```shell
|
|
|
|
|
git clone https://github.com/Gallopsled/pwntools-binutils
|
|
|
|
|
sudo apt-get install software-properties-common
|
|
|
|
|
sudo apt-add-repository ppa:pwntools/binutils
|
|
|
|
|
sudo apt-get update
|
|
|
|
|
sudo apt-get install binutils-arm-linux-gnu
|
|
|
|
|
```
|
|
|
|
|
2. 安装capstone:
|
|
|
|
|
```shell
|
|
|
|
|
git clone https://github.com/aquynh/capstone
|
|
|
|
|
cd capstone
|
|
|
|
|
make
|
|
|
|
|
sudo make install
|
|
|
|
|
```
|
|
|
|
|
3. 安装pwntools:
|
|
|
|
|
```shell
|
|
|
|
|
sudo apt-get install libssl-dev
|
|
|
|
|
sudo pip install pwntools
|
|
|
|
|
```
|
|
|
|
|
|
2017-10-11 17:22:24 +07:00
|
|
|
|
如果你在使用 Arch Linux,则可以通过 AUR 直接安装,这个包目前是由我维护的,如果有什么问题,欢迎与我交流:
|
|
|
|
|
```
|
|
|
|
|
$ yaourt -S python2-pwntools
|
2017-08-17 21:36:23 +07:00
|
|
|
|
|
2017-10-11 17:22:24 +07:00
|
|
|
|
或者
|
|
|
|
|
|
|
|
|
|
$ yaourt -S python2-pwntools-git
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
测试安装是否成功:
|
2017-08-17 21:36:23 +07:00
|
|
|
|
```python
|
|
|
|
|
>>> import pwn
|
2017-10-11 17:22:24 +07:00
|
|
|
|
>>> pwn.asm("xor eax,eax")
|
2017-08-17 21:36:23 +07:00
|
|
|
|
'1\xc0'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2017-10-11 17:22:24 +07:00
|
|
|
|
## 模块简介
|
|
|
|
|
Pwntools 分为两个模块,一个是 `pwn`,简单地使用 `from pwn import *` 即可将所有子模块和一些常用的系统库导入到当前命名空间中,是专门针对 CTF 比赛的;而另一个模块是 `pwnlib`,它更推荐你仅仅导入需要的子模块,常用于基于 pwntools 的开发。
|
|
|
|
|
|
|
|
|
|
下面是 pwnlib 的一些子模块(常用模块和函数加粗显示):
|
|
|
|
|
- `adb`:安卓调试桥
|
|
|
|
|
- `args`:命令行魔法参数
|
|
|
|
|
- **`asm`**:汇编和反汇编,支持 i386/i686/amd64/thumb 等
|
|
|
|
|
- `constants`:对不同架构和操作系统的常量的快速访问
|
|
|
|
|
- `config`:配置文件
|
|
|
|
|
- `context`:设置运行时变量
|
|
|
|
|
- **`dynelf`**:用于远程函数泄露
|
|
|
|
|
- `encoders`:对 shellcode 进行编码
|
|
|
|
|
- **`elf`**:用于操作 ELF 可执行文件和库
|
|
|
|
|
- `flag`:提交 flag 到服务器
|
|
|
|
|
- **`fmtstr`**:格式化字符串利用工具
|
|
|
|
|
- **`gdb`**:与 gdb 配合使用
|
|
|
|
|
- `libcdb`:libc 数据库
|
|
|
|
|
- `log`:日志记录
|
|
|
|
|
- **`memleak`**:用于内存泄露
|
|
|
|
|
- `rop`:ROP 利用模块,包括 rop 和 srop
|
|
|
|
|
- `runner`:运行 shellcode
|
|
|
|
|
- **`shellcraft`**:shellcode 生成器
|
|
|
|
|
- `term`:终端处理
|
|
|
|
|
- `timeout`:超时处理
|
|
|
|
|
- **`tubes`**:能与 sockets, processes, ssh 等进行连接
|
|
|
|
|
- `ui`:与用户交互
|
|
|
|
|
- `useragents`:useragent 字符串数据库
|
|
|
|
|
- **`util`**:一些实用小工具
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 使用 Pwntools
|
|
|
|
|
下面我们对常用模块和函数做详细的介绍。
|
|
|
|
|
|
|
|
|
|
#### tubes
|
|
|
|
|
在一次漏洞利用中,首先当然要与二进制文件或者目标服务器进行交互,这就要用到 tubes 模块。
|
|
|
|
|
|
|
|
|
|
主要函数在 `pwnlib.tubes.tube` 中实现,子模块只实现某管道特殊的地方。四种管道和相对应的子模块如下:
|
|
|
|
|
- `pwnlib.tubes.process`:进程
|
|
|
|
|
- `>>> p = process('/bin/sh')`
|
|
|
|
|
- `pwnlib.tubes.serialtube`:串口
|
|
|
|
|
- `pwnlib.tubes.sock`:套接字
|
|
|
|
|
- `>>> r = remote('127.0.0.1', 1080)`
|
|
|
|
|
- `>>> l = listen(1080)`
|
|
|
|
|
- `pwnlib.tubes.ssh`:SSH
|
|
|
|
|
- `>>> s = ssh(host='example.com`, user='name', password='passwd')`
|
|
|
|
|
|
|
|
|
|
`pwnlib.tubes.tube` 中的主要函数:
|
|
|
|
|
- `interactive()`:可同时读写管道,相当于回到 shell 模式进行交互,在取得 shell 之后调用
|
|
|
|
|
- `recv(numb=1096, timeout=default)`:接收指定字节数的数据
|
|
|
|
|
- `recvall()`:接收数据直到 EOF
|
|
|
|
|
- `recvline(keepends=True)`:接收一行,可选择是否保留行尾的 `\n`
|
|
|
|
|
- `recvrepeat(timeout=default)`:接收数据直到 EOF 或 timeout
|
|
|
|
|
- `recvuntil(delims, timeout=default)`:接收数据直到 delims 出现
|
|
|
|
|
- `send(data)`:发送数据
|
|
|
|
|
- `sendline(data)`:发送一行,默认在行尾加 `\n`
|
|
|
|
|
- `close()`:关闭管道
|
|
|
|
|
|
|
|
|
|
下面是一个例子,先使用 listen 开启一个本地的监听端口,然后使用 remote 开启一个套接字管道与之交互:
|
|
|
|
|
```
|
|
|
|
|
In [1]: from pwn import *
|
|
|
|
|
|
|
|
|
|
In [2]: l = listen()
|
|
|
|
|
[x] Trying to bind to 0.0.0.0 on port 0
|
|
|
|
|
[x] Trying to bind to 0.0.0.0 on port 0: Trying 0.0.0.0
|
|
|
|
|
[+] Trying to bind to 0.0.0.0 on port 0: Done
|
|
|
|
|
[x] Waiting for connections on 0.0.0.0:35117
|
|
|
|
|
|
|
|
|
|
In [3]: r = remote('localhost', l.lport)
|
|
|
|
|
[x] Opening connection to localhost on port 35117
|
|
|
|
|
[x] Opening connection to localhost on port 35117: Trying ::1
|
|
|
|
|
[x] Opening connection to localhost on port 35117: Trying 127.0.0.1
|
|
|
|
|
[+] Opening connection to localhost on port 35117: Done
|
|
|
|
|
|
|
|
|
|
[+] Waiting for connections on 0.0.0.0:35117: Got connection from 127.0.0.1 on port 36966
|
|
|
|
|
In [4]: c = l.wait_for_connection()
|
|
|
|
|
|
|
|
|
|
In [5]: r.send('hello\n')
|
|
|
|
|
|
|
|
|
|
In [6]: c.recv()
|
|
|
|
|
Out[6]: 'hello\n'
|
|
|
|
|
|
|
|
|
|
In [7]: r.send('hello\n')
|
|
|
|
|
|
|
|
|
|
In [8]: c.recvline()
|
|
|
|
|
Out[8]: 'hello\n'
|
|
|
|
|
|
|
|
|
|
In [9]: r.sendline('hello')
|
|
|
|
|
|
|
|
|
|
In [10]: c.recv()
|
|
|
|
|
Out[10]: 'hello\n'
|
|
|
|
|
|
|
|
|
|
In [11]: r.sendline('hello')
|
|
|
|
|
|
|
|
|
|
In [12]: c.recvline()
|
|
|
|
|
Out[12]: 'hello\n'
|
|
|
|
|
|
|
|
|
|
In [13]: r.sendline('hello')
|
|
|
|
|
|
|
|
|
|
In [14]: c.recvline(keepends=False)
|
|
|
|
|
Out[14]: 'hello'
|
|
|
|
|
|
|
|
|
|
In [15]: r.send('hello world')
|
|
|
|
|
|
|
|
|
|
In [16]: c.recvuntil('hello')
|
|
|
|
|
Out[16]: 'hello'
|
|
|
|
|
|
|
|
|
|
In [17]: c.recv()
|
|
|
|
|
Out[17]: ' world'
|
|
|
|
|
|
|
|
|
|
In [18]: c.close()
|
|
|
|
|
[*] Closed connection to 127.0.0.1 port 36966
|
|
|
|
|
|
|
|
|
|
In [19]: r.close()
|
|
|
|
|
[*] Closed connection to localhost port 35117
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
下面是一个与进程交互的例子:
|
|
|
|
|
```
|
|
|
|
|
In [1]: p = process('/bin/sh')
|
|
|
|
|
[x] Starting local process '/bin/sh'
|
|
|
|
|
[+] Starting local process '/bin/sh': pid 32165
|
|
|
|
|
|
|
|
|
|
In [2]: p.sendline('sleep 3; echo hello world;')
|
|
|
|
|
|
|
|
|
|
In [3]: p.recvline(timeout=1)
|
|
|
|
|
Out[3]: 'hello world\n'
|
|
|
|
|
|
|
|
|
|
In [4]: p.sendline('sleep 3; echo hello world;')
|
|
|
|
|
|
|
|
|
|
In [5]: p.recvline(timeout=1)
|
|
|
|
|
Out[5]: ''
|
|
|
|
|
|
|
|
|
|
In [6]: p.recvline(timeout=5)
|
|
|
|
|
Out[6]: 'hello world\n'
|
|
|
|
|
|
|
|
|
|
In [7]: p.interactive()
|
|
|
|
|
[*] Switching to interactive mode
|
|
|
|
|
whoami
|
|
|
|
|
firmy
|
|
|
|
|
^C[*] Interrupted
|
|
|
|
|
|
|
|
|
|
In [8]: p.close()
|
|
|
|
|
[*] Stopped process '/bin/sh' (pid 32165)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### asm
|
|
|
|
|
|
|
|
|
|
#### dynelf
|
|
|
|
|
|
|
|
|
|
#### elf
|
|
|
|
|
|
|
|
|
|
#### fmtstr
|
|
|
|
|
|
|
|
|
|
#### gdb
|
|
|
|
|
|
|
|
|
|
#### memleak
|
|
|
|
|
|
|
|
|
|
#### shellcraft
|
|
|
|
|
|
|
|
|
|
#### util
|
|
|
|
|
|
|
|
|
|
## Pwntools 在 CTF 中的运用
|
|
|
|
|
|
|
|
|
|
## 参考资料
|
|
|
|
|
- [docs.pwntools.com](https://docs.pwntools.com/en/stable/index.html)
|