pwntools
pwntools是一个ctf框架和漏洞利用开发库,用python开发,旨在让使用者简单快速的编写exploit。
python2安装方法: sudo pip install pwntools
python3安装方法: sudo pip3 install pwntools
IO模块
下面给出了PwnTools中的主要IO函数。1
2
3
4
5
6
7
8
9
10
11send(data) : 发送数据
sendline(data) : 发送一行数据,相当于在末尾加\n
recv(numb=4096, timeout=default) : 给出接收字节数,timeout指定超时
recvuntil(delims, drop=False) : 接收到delims的pattern
(以下可以看作until的特例)
recvline(keepends=True) : 接收到\n,keepends指定保留\n
recvall() : 接收到EOF
recvrepeat(timeout=default) : 接收到EOF或timeout
interactive() : 与shell交互
ELF模块
ELF模块用于获取ELF文件的信息,首先使用ELF()获取这个文件的句柄,然后使用这个句柄调用函数,和IO模块很相似。
下面演示了:获取基地址、获取函数地址(基于符号)、获取函数got地址、获取函数plt地址1
2
3
4
5
6
7
8
9>>> e = ELF('/bin/cat')
>>> print hex(e.address) # 文件装载的基地址
0x400000
>>> print hex(e.symbols['write']) # 函数地址
0x401680
>>> print hex(e.got['write']) # GOT表的地址
0x60b070
>>> print hex(e.plt['write']) # PLT的地址
0x401680
数据处理
主要是对整数进行打包,就是转换成二进制的形式,比如转换成地址。p32、p64是打包,u32、u64是解包。
数据打包,即将整数值转换为32位或者64位地址一样的表示方式,比如0x400010表示为\x10\x00\x40一样,这使得我们构造payload变得很方便
用法:
- p32/p64: 打包一个整数,分别打包为32或64位
- u32/u64: 解包一个字符串,得到整数
大致框架
官网的一个简单样例
1 | from pwn import * |
Context设置
context是pwntools用来设置环境的功能。在很多时候,由于二进制文件的情况不同,我们可能需要进行一些环境设置才能够正常运行exp,比如有一些需要进行汇编,但是32的汇编和64的汇编不同,如果不设置context会导致一些问题。
一般来说我们设置context只需要简单的一句话:
context(os=’linux’, arch=’amd64’, log_level=’debug’)
这句话的意思是:
- os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux
- arch设置架构为amd64,可以简单的认为设置为64位的模式,对应的32位模式是’i386’
- log_level设置日志输出的等级为debug,这句话在调试的时候一般会设置,这样pwntools会将完整的io过程都打印下来,使得调试更加方便,可以避免在完成CTF题目时出现一些和IO相关的错误。
汇编与shellcode
有的时候我们需要在写exp的时候用到简单的shellcode,pwntools提供了对简单的shellcode的支持。
首先,常用的,也是最简单的shellcode,即调用/bin/sh可以通过shellcraft得到:
注意,由于各个平台,特别是32位和64位的shellcode不一样,所以最好先设置context。1
print(shellcraft.sh()) # 打印出shellcode
不过,现在我们看到的shellcode还是汇编代码,不是能用的机器码,所以还需要进行一次汇编1
print(asm(shellcraft.sh())) # 打印出汇编后的shellcode
asm可以对汇编代码进行汇编,不过pwntools目前的asm实现还有一些缺陷,比如不能支持相对跳转等等,只可以进行简单的汇编操作。如果需要更复杂一些的汇编功能,可以使用keystone-engine项目,这里就不再赘述了。
asm也是架构相关,所以一定要先设置context,避免一些意想不到的错误。