pwntools使用簡介2


大致框架

官網的一個簡單樣例

from pwn import *
context(arch = 'i386', os = 'linux')

r = remote('exploitme.example.com', 31337)
# EXPLOIT CODE GOES HERE
r.send(asm(shellcraft.sh()))
r.interactive()

基本上仿造這個格式就可以寫exp了。

from pwn import *

用來導入pwntools模塊

context(arch = 'i386', os = 'linux')

設置目標機的信息

r = remote('exploitme.example.com', 31337)

用來建立一個遠程連接,url或者ip作為地址,然后指明端口

這里也可以僅僅使用本地文件,調試時方便:

r = process("./test")

test即為文件名,這使得改變遠程和本地十分方便.

asm(shellcraft.sh())

asm()函數接收一個字符串作為參數,得到匯編碼的機器代碼。

比如

>>> asm('mov eax, 0')
'\xb8\x00\x00\x00\x00'

shellcraft模塊是shellcode的模塊,包含一些生成shellcode的函數。

其中的子模塊聲明架構,比如shellcraft.arm 是ARM架構的,shellcraft.amd64是AMD64架構,shellcraft.i386是Intel 80386架構的,以及有一個shellcraft.common是所有架構通用的。

而這里的shellcraft.sh()則是執行/bin/sh的shellcode了

r.send()將shellcode發送到遠程連接

最后,

r.interactive()

將控制權交給用戶,這樣就可以使用打開的shell了

Context設置

context是pwntools用來設置環境的功能。在很多時候,由於二進制文件的情況不同,我們可能需要進行一些環境設置才能夠正常運行exp,比如有一些需要進行匯編,但是32的匯編和64的匯編不同,如果不設置context會導致一些問題。

一般來說我們設置context只需要簡單的一句話:

context(os='linux', arch='amd64', log_level='debug')

這句話的意思是:

1. os設置系統為linux系統,在完成ctf題目的時候,大多數pwn題目的系統都是linux
2. arch設置架構為amd64,可以簡單的認為設置為64位的模式,對應的32位模式是’i386’
3. log_level設置日志輸出的等級為debug,這句話在調試的時候一般會設置,這樣pwntools會將完整的io過程都打印下來,使得調試更加方便,可以避免在完成CTF題目時出現一些和IO相關的錯誤。

數據打包

數據打包,即將整數值轉換為32位或者64位地址一樣的表示方式,比如0x400010表示為\x10\x00\x40一樣,這使得我們構造payload變得很方便

用法:
* p32/p64: 打包一個整數,分別打包為32或64位
* u32/u64: 解包一個字符串,得到整數

p對應pack,打包,u對應unpack,解包,簡單好記

payload = p32(0xdeadbeef) # pack 32 bits number

 

 

數據輸出

如果需要輸出一些信息,最好使用pwntools自帶的,因為和pwntools本來的格式吻合,看起來也比較舒服,用法:

some_str = "hello, world"
log.info(some_str)

其中的info代表是log等級,也可以使用其他log等級。

Cyclic Pattern

Cyclic pattern是一個很強大的功能,大概意思就是,使用pwntools生成一個pattern,pattern就是指一個字符串,可以通過其中的一部分數據去定位到他在一個字符串中的位置。

在我們完成棧溢出題目的時候,使用pattern可以大大的減少計算溢出點的時間。
用法:

cyclic(0x100) # 生成一個0x100大小的pattern,即一個特殊的字符串
cyclic_find(0x61616161) # 找到該數據在pattern中的位置
cyclic_find('aaaa') # 查找位置也可以使用字符串去定位

比如,我們在棧溢出的時候,首先構造cyclic(0x100),或者更長長度的pattern,進行輸入,輸入后pc的值變味了0x61616161,那么我們通過cyclic_find(0x61616161)就可以得到從哪一個字節開始會控制PC寄存器了,避免了很多沒必要的計算。

匯編與shellcode

有的時候我們需要在寫exp的時候用到簡單的shellcode,pwntools提供了對簡單的shellcode的支持。
首先,常用的,也是最簡單的shellcode,即調用/bin/sh可以通過shellcraft得到:

注意,由於各個平台,特別是32位和64位的shellcode不一樣,所以最好先設置context。

print(shellcraft.sh()) # 打印出shellcode

不過,現在我們看到的shellcode還是匯編代碼,不是能用的機器碼,所以還需要進行一次匯編

print(asm(shellcraft.sh())) # 打印出匯編后的shellcode

asm可以對匯編代碼進行匯編,不過pwntools目前的asm實現還有一些缺陷,比如不能支持相對跳轉等等,只可以進行簡單的匯編操作。如果需要更復雜一些的匯編功能,可以使用keystone-engine項目,這里就不再贅述了。

asm也是架構相關,所以一定要先設置context,避免一些意想不到的錯誤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM