pwntools的使用
November 16, 2018 PWN 访问: 30 次
pwntools
- pwntools是一个二进制利用框架。官方文档提供了详细的api规范。然而目前并没有一个很好的新手教程。因此我用了我过去的几篇writeup。由于本文只是用来介绍pwntools使用方法,我不会过于详细的讲解各种二进制漏洞攻击技术。
使用方法
引入pwntools模块
from pwn import *
连接到我们指定的地址及端口,然后该函数会返回remote对象。
remote("一个域名或者ip地址", 端口)
remote对象主要用来进行对远程主机的输入输出,它有如下几个方法:
- send(payload)发送payload
- sendline(payload)发送payload,并进行换行(末尾\n)
- sendafter(some_string, payload)接收到 some_string 后,发送你的 payload
- recvn(N) 接受 N(数字) 字符;
- recvline() 接收一行输出;
- recvlines(N)接收 N(数字) 行输出;
- recvuntil(some_string)接收到 some_string 为止。
- recvuntil(some_string,drop=True)接受到some_string为止前面的字符串
- r.interactive() 获取到shell,进行交互
p32()、u32()
- p**()可以让我们转换整数到小端序格式,p32转换4字节,p64和p16 则分别转换 8 bit 和 2 bit 数字
- u**()可以将字符串转化为数字
debug调试输出
- context.log_level="debug"脚本在执行时就会输出debug的信息,你可以通过观察这些信息查找哪步出错了
在pwntools写脚本的时候与GDB交互
- pwnlib.gdb.attach(p)在发送payload前加入这条语句,同时加上pause() 时脚本暂停
然后就会弹出来一个开启着gdb的终端,你先在gdb中设置好断点
然后再运行脚本的那个终端按一下回车继续运行脚本,程序就会运行到断点,你就可以查看相应的寄存器,或者是栈的信息
ELF():用来操作elf的工具
- 既可以操作ELF可执行文件,
e = ELF("./pwn") #用来加载一个文件
e.plt["funcname"] # 找出funcname在plt段中的地址
e.got["funcname"] # 找出funcname在got段中的地址
e.symbols["funcname"] #找出funcname在.text段中中的地址
e.search("/bin/sh").next() #找出“/bin/sh”在文件中的位置
e.bss() #返回该文件中bss段的首地址
- 可以用来操作libc.so文件
libc = ELF("libc.so.6")
libc.address = function_real_addr - function_got #libc.address赋值过之后再用libc.symbols查找函数时,地址是自动计算好的
DynELF
- 通过信息泄露 获得远程函数地址
def leak(address):
#函数体
d = DynELF(leak, main) # 创建一个没有程序的DynELF对象
d = DynELF(leak, main, elf=ELF('./pwnme')) # 创建一个有程序的DynELF对象
d.lookup('system', 'libc') # 显示system在内存中的地址
汇编与反汇编
- asm('mov eax, 0')
- disasm('\xb8\x0b\x00\x00\x00')
生成shellcode
context.arch = 'amd64'
shellcode = asm(shellcraft.amd64.sh())
一些小工具
#base64加密解密
b64e("test")
b64d('dGVzdA==')
#字符串与ASCII码的转换
enhex("test")
unhex("74657374")
#随机生成n个字符的字符串
randoms(n)
2019-9-14 总结
pwnlib.args
:用于接收命令行传进的参数
#coding:utf-8
from pwn import *
print args
print "远程端口 : "+ args['IP']
print "远程地址 : "+ args['PORT']
out:
一筐萝卜➜ test python study.py IP=127.0.0.1 PORT=12345
defaultdict(<type 'str'>, {'PLT_DEBUG': '', 'PORT': '12345', 'IP': '127.0.0.1'})
远程端口 : 127.0.0.1
远程地址 : 12345
一筐萝卜➜ test
在python中直接运行字节码
#coding:utf-8
from pwn import *
binsh_code = asm(shellcraft.i386.sh())
filename = make_elf(binsh_code,extract=False)
p = process(filename)
p.sendline("ls")
print "-"*40
print p.recvline()
print "-"*40
out:
一筐萝卜➜ test python study.py
[+] Starting local process '/tmp/pwn-asm-L1xcN5/step3-elf': pid 16587
----------------------------------------
easy_heap exp.py study.py test.py
----------------------------------------
[*] Stopped process '/tmp/pwn-asm-L1xcN5/step3-elf' (pid 16587)
一筐萝卜➜ test
pwn.context
:设置运行时的变量
使用context.binary自动设置所有适当的值
from pwn import *
context.binary='./pwn_file'
context.update
:改写变量
context.update(os='linux',arch='amd64')