Defcon 23最新開源工具NetRipper代碼分析與利用
0×01 研究背景
在分析了俄羅斯人被曝光的幾個銀行木馬的源碼後,發現其大多均存在通過劫持瀏覽器數據包來獲取用戶個人信息的模塊,通過截獲瀏覽器內存中加密前或解密後的數據包來得到數據包的明文數據。在Defcon 23被發布的工具NetRipper具備了以上惡意銀行木馬的這一能力,其開源的代碼結構清晰,易於擴展,研究該工具對於研究該類惡意行為很有意義。其github地址在【github】 ,作者還提供了metasploit和powershell版本的利用模塊,本文將分析其不同版本模塊均會用到的c++代碼實現的核心部分。
0×02 NetRipper工具概括
該開源工具實現的功能,主要是通過Hook進程的網絡函數關鍵點(封包加密之前與封包解密之後的網絡函數)來劫持客戶端程序的明文數據。其中包括了諸多主流客戶端,例如:Chrome,Firefox,IE,WinSCP,Putty以及一些代碼庫中提供的網絡封包加解密函數接口,根據函數接口的函數性質來分的話,可以分為“未導出的函數接口”和“導出的函數接口”。其中Chrome,Putty,SecureCrt以及WinSCP中的網絡加解密接口是屬於UnExported,需要通過逆向工程來找到其Signature的位置,然後通過HOOK劫持;例如Mozilla Firefox使用了nss3.dll和nspr4.dll這兩個模塊中的加解密函數,nss3.dll中導出了PR_Read,PR_Write以及PR_GetDescType,後者導出了PR_Send和PR_Recv。其他的例如ncrypt.dll、secur32.dll和ssh2core73u.dll等。
還有對winsock2下的普通網絡傳輸函數進行Hook來直接獲取到一些未加密的信息。
對於未導出函數hook的處理需要先找出hook點,這比hook已知導出函數的過程復雜許多,首先需要通過逆向分析進程的收發包過程來找到關鍵點(加密前與解密後的數據包處理的函數接口)。例如,對於chrome/putty/winscp進程是需要這樣做的,可以通過其開源的代碼作為輔助分析,首先找到其網絡函數的Signature,HOOK之前在進程的內存空間中搜索其所在地址:
伴隨著軟件的升級與安全保護的增強,可能明文層次上的收發包函數會有一些變化,那麽NetRipper代碼就需要修改去適應這些變化,重新調試分析找到對應的Signature,進而重新設置Hook點。
以putty為例來驗證下:
使用CE查找發送函數的標識,位置在0x00408AD7。
IDA中顯示 Sub_408ad7這個函數的原型定義與代碼中聲明是一致的:
至於如何調試找出未導出函數的HOOK點,這方面的內容較多,下一篇文章詳細分析。對於putty和winscp客戶端,因為均已開源,可以參考其開源的代碼;對於chrome,那就需要逆向調試程序來定位HOOK點了。
0×03 Hook的偏移地址計算
E8 XXXXXXXX
其中XXXXXXXX = 目標地址 – 原始地址 – 5
舉個例子,OD加載calc.exe:
指令中的偏移地址:0xFFFF99EB
目標地址:0x6c768
當前指令地址:0x72d78
計算公式:0xFFFFFFFF – ( 0x72d78 + 5 – 0x6c768 ) = 0xFFFF99eb
QA1:為什麽需要使用0xFFFFFFFF減去偏移值呢?
計算補碼
地址為一個DWORD(unsigned long)占4個字節的整型,可以表示的地址範圍是有符號的2倍,可以表示的範圍是0×00000000~0xFFFFFFFF。
QA2:為什麽需要當前指令地址加上5,然後減去目標地址來計算偏移量呢?
這涉及到CALL/JMP指令計算偏移的基礎,首先CALL/JMP(E8或E9)均是占用了5個字節,要跳到目標地址,那麽首先就需要跳過當前指令的長度,然後再跳到目標地址。在上面的例子中也可以看到,通過計算才是正確的結果。
NetRipper實際例子:
NetRipper也處理了在碰到Hot-Patching的情況,其處理的方式與上面的一致,只不過將函數地址加了5個字節,將新的位置作為函數的HOOK點。
NetRipper 對Hook的處理也很有意思:
(1)使用一個結構HookStruct來存儲(或者叫註冊一個函數Hook信息)被HOOK的函數的信息,使用一個vector維護。
(2)回調函數使用內聯匯編編寫,代碼的功能是:當原始函數被調用就執行這一段匯編代碼,然後在匯編代碼中調用Hooker::GetHookStructByOriginalAddress函數,這個函數將原始函數的地址作為參數,在所有已經註冊了HOOK結構的vector<HokStruct>中檢索該函數的HOOK信息,根據函數的地址來確定回調函數。
對於這一段內聯匯編代碼的解釋,在下面會給出分析。
註意:對於Recv這樣的函數來說,只有先調用了原始的函數,才能夠得到recv的信息。這存在一個Hook後回調函數中的處理問題。
0×04 NetRipper 中Hook的處理
0×05 NetRipper中的註入
NetRipper中提供了常規遠程註入和反射註入兩種註入方法,其中反射註入在目前已經非常常見了,除了惡意代碼常常會采用,對於metasploit滲透框架也采用了這種註入方式。關於這種註入方法,資料較多,這裏就不展開了。
0×06代碼框架分析
作者為了使該工具擴展性強,包括核心代碼在內,其他輔助模塊均通過C++類來封裝,具有較低耦合性,易於配置來完成不同的任務。
(1)註入與動態配置
核心模塊在一個DLL中,所以需要註入到目標進程,提供了註入代碼,該註入部分的代碼提供了常規遠程線程註入和反射註入技術兩種選擇,註入器采用命令行形式,可以用於配置要註入的DLL。
(2)插件系統
代碼中使用了作者編寫的一個插件系統,封裝在一個C++類種,以成員函數形式提供了幾個插件函數,也可以根據其代碼方便擴展。
(3)調試日誌
提供了調試信息輸出的功能,作者提供了封裝的這個類,使用者可以通過配置是否使用。
(4)函數流控制
可針對每一個被Hook的線程,保證其Hook操作後處理的時候均只做一種類型的操作,通過一個函數流控制類來控制。例如Hook的回調函數輸出信息到文件,這樣可以控制一個線程中被Hook的函數只輸出到一個log文件中。
0×07 NetRipper的使用
NetRipper主要用於後滲透,目標主機被攻陷後,需要進一步深入橫縱滲透的時候就需要更多的信息,NetRipper通過劫持瀏覽器/客戶端的明文信息來達到這一目的。Net Ripper提供了對瀏覽器以及一些常見的客戶端的劫持實現,通過劫持瀏覽器(IE/Chrome/Firefox)來得到用戶請求的信息;對於WinSCP和putty等客戶端可以直接得到用戶輸入的賬戶等信息,幫助滲透測試人員以及攻擊者從Windows系統過渡到Linux系統,完成攻擊最大化。下面以putty為例測試
(1)將DLL註入至putty進程完成利用
(2)使用putty登陸SSH服務器來驗證
(3)默認在用戶目錄下的temp下生成日誌文件:
(4)putty數據包解密數據
可以看到輸入的用戶名root和密碼qwe以及輸入的命令ifconfig已經被記錄下來了,這是對發包過程的解密操作。
(5)hook send/recv函數獲取的putty加密的數據
*本文作者:任子行,轉載請註明FreeBuf.COM
Defcon 23最新開源工具NetRipper代碼分析與利用