用Python寫Exploit
測試軟件漏洞時,個人比較鐘愛用python來完成exploit,簡單,快速。也見過不少用perl來寫的,我不喜歡。隨便記錄一些常用的方法。
python中有個概念叫模塊,模塊中包含了定義的函數,方便重用。使用模塊的語句如下:
import 模塊名
struct模塊有個很方便的函數,pack,格式如下:
struct.pack(format,參數)
將參數內容轉換成format中指定的格式。寫shellcode時,需要將覆蓋地址倒序(little-endian)排列,為了方便,咱們可以使用這個函數。咱們要用到的指定格式是"<L”,以無符號長整型的little-endian格式。
0x7ffa4512是通殺windows 2000/xp/2003的jmp esp地址,以它為例:
import struct
struct.pack('<L',0x7ffa4512)
溢出測試時,常常需要生成一長串字符串去填充緩沖區,用循環的話比較麻煩。python中直接可以用乘號來操作字符串:
shellcode = '\x90' * 1000
執行后,shellcode的值為1000個\x90。
同時也可以用加號來操作字符串,連接兩個字符串的例子如下:
import struct
buffer = 'A' * 100
jmpesp = struct('<L', 0x7ffa4512) #將0x7ffa4512轉化為\x12\x45\xfa\x7f的格式
buffer += jmpesp
在python中“+=”與C語言中的“+=”用法一樣,buffer += jmpesp等同于buffer = buffer + jmpesp,當然也可以用后者來表示。
ord函數可用于將指定字符轉換成ASCIIi碼,函數聲明如下:
ord(字符)
例:
>>>print ord('A')
65
注意ord函數只接受字符,不能接受字符串。
對讀取文件時發生溢出的程序來說,需要生成一個帶有測試代碼的文件。python提供了方便的文件操作函數。
filename = 'test' #定義一個變量,賦值為將要打開的文件名
payload = 'A' * 5000 #生成五千個A
f = open(filename,'w') #以寫模式打開文件
f.write(payload) #將五千個A寫入到該文件內
f.close #關閉
執行以上代碼后,會在當前目錄下生成一個內容為5000個A的、文件名為test的文件。
有時需要對網絡程序進行安全性測試,python也提供了socket編程。需要使用socket模板。
import socket
shellcode = 'A' * 1000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #創建一個socket對象
s.connect(("127.0.0.1", 200)) #連接到127.0.0.1,端口指定為200
s.send(shellcode) #發送數據(一千個A)
該例子可以用在FTP Server之類的網絡程序進行測試。