CTF-All-In-One/doc/2.7_pwntools.md
2017-10-11 18:22:24 +08:00

6.0 KiB
Raw Blame History

2.7 Pwntools

Pwntools 是一个 CTF 框架和漏洞利用开发库,用 Python 开发,由 rapid 设计,旨在让使用者简单快速的编写 exp 脚本。包含了本地执行、远程连接读写、shellcode 生成、ROP 链的构建、ELF 解析、符号泄露众多强大功能。

安装

  1. 安装binutils
    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
    git clone https://github.com/aquynh/capstone
    cd capstone
    make
    sudo make install
    
  3. 安装pwntools:
    sudo apt-get install libssl-dev
    sudo pip install pwntools
    

如果你在使用 Arch Linux则可以通过 AUR 直接安装,这个包目前是由我维护的,如果有什么问题,欢迎与我交流:

$ yaourt -S python2-pwntools

或者

$ yaourt -S python2-pwntools-git

测试安装是否成功:

>>> import pwn  
>>> pwn.asm("xor eax,eax")
'1\xc0'

模块简介

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 配合使用
  • libcdblibc 数据库
  • log:日志记录
  • memleak:用于内存泄露
  • ropROP 利用模块,包括 rop 和 srop
  • runner:运行 shellcode
  • shellcraftshellcode 生成器
  • term:终端处理
  • timeout:超时处理
  • tubes:能与 sockets, processes, ssh 等进行连接
  • ui:与用户交互
  • useragentsuseragent 字符串数据库
  • 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.sshSSH
    • >>> 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 中的运用

参考资料