構建ROP鏈實現遠端棧溢位
通常情況下棧溢位可能造成的後果有兩種,一類是本地提權另一類則是遠端執行任意命令,通常C/C++並沒有提供智慧化檢查使用者輸入是否合法的功能,同時程式編寫人員在編寫程式碼時也很難始終檢查棧是否會發生溢位,這就給惡意程式碼的溢位提供了的條件,利用溢位,攻擊者可以控制程式的執行流,從而控制程式的執行過程並實施惡意行為,而微軟的DEP保護機制則可使緩衝區溢位失效,不過利用ROP反導技術依然是可被繞過的,接下來將具體分析如何利用ROP技術繞過DEP保護機制。
課件下載地址:https://pan.baidu.com/s/1WwKp2GTVaCEQOLPUM49dUw 提取碼:nk9h
緩衝區溢位的常用攻擊方法是將惡意 shellcode 注入到遠端服務的堆疊中,並利用 jmp esp
FTP Server
該服務執行後會在本機開啟 0.0.0.0:9999
埠,你可以通過nc命令遠端連線到伺服器並可以執行一些命令.
如上圖就是執行後的FTP伺服器,通過nc工具連結服務端的地址nc 192.168.1.8 9999
可以得到一個FTP互動環境,此時可以執行send | hello world
命令,來向伺服器傳送一段字串,同時伺服器會返回給你Data received successfully
這樣的提示資訊,好了我們開始分析程式並挖掘漏洞吧。
模糊測試與分析
要執行模糊測試的第一步就是要確定傳送資料包中包頭的格式,這裡我們可以使用Wireshark工具監控TCP流,將源地址設定為192.168.1.2
,目標地址設定為 192.168.1.8
,監控並從中得到資料傳輸的格式資訊,過濾語句 tcp.stream and ip.src_host==192.168.1.2 and ip.dst_host==192.168.1.8
該語句可以精確的過濾出我們所需要的資料。
上圖中我們可以直觀的看出,資料包的格式僅僅是 send | hello lyshark
並沒有新增任何的特殊符號,更沒有加密傳輸,接下來就是要驗證send函式是否存在緩衝區溢位了,這裡我們需要編寫一個模糊測試指令碼來對目標服務進行測試,指令碼內容如下,Python 指令碼執行後會對目標FTP服務進行發包測試。
# coding:utf-8
import socket,time
def initCount(count,Inc):
buffer = ["A"]
while len(buffer)<=50:
buffer.append("A" * count)
count = count + Inc
return buffer
def Fuzz(addr,port,buffer):
try:
for string in buffer:
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connect = sock.connect((addr,port))
sock.recv(1024)
command = b'send |/.:/' + string.encode()
sock.send(command)
sock.close()
time.sleep(1)
print('Fuzzing Pass with {} bytes'.format(len(string)))
except Exception:
print('\n This buffer cannot exceed the maximum {} bytes'.format(len(string)))
if __name__ == "__main__":
# initCount 10 說明從0開始遞增,每次遞增100
buff = initCount(0,100)
Fuzz("192.168.1.8",9999,buff)
上方的程式碼的構造需要具體分析資料包的形式得到,在漏洞模糊測試中上方程式碼中間部分的互動需要根據不同程式的互動方式進行修改與調整,這裡測試指令碼執行後當緩衝區填充為2200bytes
時程式崩潰了,說明該程式的send函式確實存在緩衝區溢位漏洞,其次該程式緩衝區的大小應在2200位元組以內。
經過模糊測試我們可知該函式確實存在漏洞,為了能讓讀者更加深入的理解緩衝區發生的原因和定位技巧,我將具體分析一下其彙編程式碼的組織形式,這裡為了方便演示我將在攻擊主機進行逆向分析。
首先開啟X64dbg將FTP程式載入並執行,接著我們需要使用Netcat連結本機 nc 192.168.1.2 9999
並進入一個可互動的shell環境中,然後輸入待發送的字串不要回車。
接著我們回到X64DBG按下ctrl + G
在recv函式上下一個斷點,因為程式接收使用者輸入的功能需要使用recv函式的,所以這裡我們直接下斷,然後執行程式,傳送資料後會被斷下,我們直接回到程式領空,會看到以下程式碼片段,這裡我們需要在 0040148D
這個記憶體地址處下一個F2斷點,然後取消系統領空中recv上的斷點。
通過再次傳送send | hello lyshark
程式會被斷下,我們單步向下跟進會發現下面的程式碼片段,這裡正是我們的send
函式所執行的區域,此處我們記下這個記憶體地址 004017D5
然後關閉X64dbg
開啟IDA Pro載入程式並按下G鍵,我們來到剛剛的記憶體地址處,這裡已經給大家分析好了,關鍵的變數是分配了3000
個位元組的緩衝區,直接傳遞給了_Function3
函式。
接著我們繼續跟進這個call _Function3
函式,會發現子過程內部並沒有對接收緩衝區大小進行嚴格的過濾,強制將3000byte
的資料拷貝到2024byte
的緩衝區中,此時緩衝區就會發生溢位,從而導致堆疊失衡,程式崩潰,這和上方的模糊測試指令碼得到的結果是差不多的。
為了能夠更加精確的計算出緩衝區的具體大小,我們還需
控制EIP暫存器
構建漏洞利用程式碼
ROP技術繞過DEP保護
ASLR 如何繞過解析
將指令碼整合到Metasploit
原創作品,轉載請註明出處