pwntools
pwntools 是一款專門用於CTF Exploit的python庫,能夠很方便的進行本地與遠程利用的切換,並且里面包含多個模塊,使利用變得簡單。
可以在github上直接搜索pwntools 進行安裝。
基本模塊
asm : 匯編與反匯編,支持x86/x64/arm/mips/powerpc等基本上所有的主流平台
dynelf : 用於遠程符號泄漏,需要提供leak方法
elf : 對elf文件進行操作,可以獲取elf文件中的PLT條目和GOT條目信息
gdb : 配合gdb進行調試,設置斷點之后便能夠在運行過程中直接調用GDB斷下,類似於設置為即使調試JIT
memleak : 用於內存泄漏
shellcraft : shellcode的生成器
asm 匯編模塊
這個模塊提供一些基本的匯編與反匯編操作,一般可以用linux的objdump以及IDA Pro能夠完成基本的需求。
dynelf 模塊
DynELF是leak信息的神器。前提條件是要提供一個輸入地址,輸出此地址最少1byte數的函數。官網給出的說明是:Given a function which can leak data at an arbitrary address, any symbol in any loaded library can be resolved.
# Assume a process or remote connection p = process('./pwnme') # Declare a function that takes a single address, and # leaks at least one byte at that address. def leak(address): data = p.read(address, 4) log.debug("%#x => %s" % (address, (data or '').encode('hex'))) return data # For the sake of this example, let's say that we # have any of these pointers. One is a pointer into # the target binary, the other two are pointers into libc main = 0xfeedf4ce libc = 0xdeadb000 system = 0xdeadbeef # With our leaker, and a pointer into our target binary, # we can resolve the address of anything. # # We do not actually need to have a copy of the target # binary for this to work. d = DynELF(leak, main) assert d.lookup(None, 'libc') == libc assert d.lookup('system', 'libc') == system # However, if we *do* have a copy of the target binary, # we can speed up some of the steps. d = DynELF(leak, main, elf=ELF('./pwnme')) assert d.lookup(None, 'libc') == libc assert d.lookup('system', 'libc') == system # Alternately, we can resolve symbols inside another library, # given a pointer into it. d = DynELF(leak, libc + 0x1234) assert d.lookup('system') == system
elf 模塊
這是一個靜態模塊,即靜態加載ELF文件,然后通過相關接口獲取一些信息,常用接口有:
got 獲取指定函數的GOT條目
plt 獲取指定函數的PLT條目
address 獲取ELF的基址
symbols 獲取函數的實際地址(待確定)
gdb 模塊
該模塊用於調用gdb調試
在python文件中直接設置斷點,當運行到該位置之后就會斷下
import pwnlib from pwn import * p = process('./c') pwnlib.gdb.attach(p)
rop 模塊
用於自動產生ROP鏈 還不支持X64?
elf = ELF('ropasaurusrex') rop = ROP(elf) rop.call('read', (0, elf.bss(0x80))) rop.dump() ## 展示當前的ROP chain ### 搜索指定指令 rop.search(move=0, regs=None, order='size') ''' move(int),棧指針調整的字節數 regs(list),搜索的寄存器list order(str),多個gadgets的排序方式,可選值=['size', 'regs'] ''' rop.r13_r14_r15_rbp == rop.search(regs=['r13','r14','r15','rbp'], order = 'regs')
rop.call, 兩個參數,第一個是需要call的函數或者一個地址,第二個是函數參數,為list,只有一個參數需要在后面加上一個’,’使其變為list
也可以使用ROPgadget進行gadget搜索
shellcraft 模塊
shellcraft模塊是shellcode的模塊,包含一些生成shellcode的函數。
其中的子模塊聲明架構,比如shellcraft.arm 是ARM架構的,shellcraft.amd64是AMD64架構,shellcraft.i386是Intel 80386架構的,以及有一個shellcraft.common是所有架構通用的。
有的時候我們需要在寫exp的時候用到簡單的shellcode,pwntools提供了對簡單的shellcode的支持。
首先,常用的,也是最簡單的shellcode,即調用/bin/sh
可以通過shellcraft得到:
注意,由於各個平台,特別是32位和64位的shellcode不一樣,所以最好先設置context。
print(shellcraft.sh()) # 打印出shellcode
print(asm(shellcraft.sh())) # 打印出匯編后的shellcod
asm可以對匯編代碼進行匯編,不過pwntools目前的asm實現還有一些缺陷,比如不能支持相對跳轉等等,只可以進行簡單的匯編操作。如果需要更復雜一些的匯編功能,可以使用keystone-engine
項目,這里就不再贅述了。
asm也是架構相關,所以一定要先設置context,避免一些意想不到的錯誤。