pwn从入门到放弃第四章——pwntools的基本使用教程

pwntools是除了ida和gdb以外最常用的工具,python的语法并不难,大概只要懂一些c和c++的编程,转换到python的编程非常简单

这里随便给一个教程,你也可以找其他自己觉得好的教程学一下

python教程

基本学一下循环,函数之类的就可以直接写python了

这里还要说一下,pwntools只能安装在python2下面,所以语法什么的都是python2的,但是如果学过python3的也很容易转换过来

这里写给一下我pwntools脚本的模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *

debug=1
if debug:
p=process('')
#p=process('',env={'LD_PRELOAD':'./libc.so'})
context.log_level='debug'
gdb.attach(p)
else:
p=remote('')

def ru(x):
return p.recvuntil(x)

def se(x):
p.send(x)

p.interactive()

这里介绍一下pwntools比较有用的函数

我们可以打开terminal,输入python,进入python的交互命令行,然后再输入

1
from pwn import *

p32 p64

就是将一个数字转换为字符,例如

1
p32(0xdeadbeef)

就会转换为

1
'\xef\xbe\xad\xde'

这里顺序反了是因为linux编译的程序是小端序的

u32 u64

就是将字符转换为数字,例如

1
u32('\x12\x34\x56\x78')

结果

这里可能要解释下,\x78是一个字符,代表的是16进制78的ascii字符

1
2
0x78=120='x'
0x56=86='V'

cyclic

这个是一个在栈溢出或者各种需要找偏移的时候比较有用的函数

1
cyclic(40)

这是生成40个字节长的字符串,这个字符串是按照一定规律来生成的

假如说我想找aaaj这个字符串的偏移,我们可以用

1
cyclic_find('aaaj')

接下来解释下我模板中定义的ru和se函数

1
2
3
4
5
def ru(x):
return p.recvuntil(x)

def se(x):
p.send(x)

这里的p是由

1
2
3
p=process('')

p=remote('')

赋值的,process是指运行本地的程序,remote是指连接远程的服务器
这里给下process和remote的例子

1
2
p=process('./babystack')
p=remote('123.123.123.123',8888)

回到函数,p.recvuntil,这个很明显就是接收字符串直到接收到x

这里给个运用的例子

1
ru('Hello World')

这里就是说明接收字符串,直到接收到Hello World

而p.send就是发送字符串

1
se('Hi!')

这里就是发送 Hi! 给程序或者远程服务器

其实pwntools还有另外一个函数

1
p.sendline('xxxx')

这里就是发送 ‘xxxx\n’ 给程序或者服务器

接下来解释下模板中的gdb.attach

1
gdb.attach(p)

这个是用于本地程序调试的,gdb可以附加到一个正在运行的程序上面,进行调试

gdb attach一般会停在read的syscall那里,等待输入,因为gdb attach是附加到正在运行的程序上面,而p=process之后,程序停在了等待输入那里,所以gdb附加上去之后就停在read 的syscall那里

之后的各种操作就和gdb使用教程教的一样