FBI針對Tor網絡的惡意代碼分析
英文原文:Analysis of the FBI Tor Malware
一、背景
Tor(The Oninon Router)提供一個匿名交流網絡平臺,它使得用戶在瀏覽網頁或訪問其它網絡服務時不會被跟蹤。作為該網絡的一部分即所謂的“暗網” (darknet),是指只能通過 Tor 網絡訪問的服務器群組,這些服務器提供包括社區論壇、電子郵件等多種服務。雖然提供這些服務都是無惡意的,初衷是用來關注侵犯人權問題,但是由于匿名的原 因吸引了很多有犯罪意圖的人,比如傳播兒童色情。事后執法部門也不能追蹤到犯罪者的源 IP 地址。
2013 年,在“暗網”服務器上發現了一款惡意軟件,它利用特定 Web 瀏覽器上的安全漏洞在用戶電腦上執行一段代碼。該代碼收集一些用戶信息,發往弗吉尼亞州的服務器,之后自毀。就惡意軟件的特征來講,它沒有明顯的惡意意 圖。初步推斷是 FBI 植入,他們在弗吉尼亞州有辦事處,曾經也派專人開發過惡意程序,可能是他們創建了它—現在看來是真的。
二、對 Shellcode 的逆向分析
1、漏洞利用
漏洞利用代碼用 javascript 編寫,利用一個出名的 firefox 瀏覽器的特定版本(Tor 網絡預裝的 firefox)的漏洞。該漏洞利用代碼經過了模糊處理,但通過快速掃描可以看到一長串十六進制字符,這些字符是 shellcode 的前幾個標志性字節,即 call 操作碼(shellcode 經常以一個 jump 或 call 開始,因此知道了這些操作碼使得識別 shellcode 變得容易起來)。
我不會在這里分析這個漏洞,但是要看一下這個 shellcode。
首先,讓我們用一些基本的 shellcode 原則設定一個場景。
2、位置無關代碼
Shellcode 的成功執行經過了獨一無二的挑戰,因為它是直接注入到一個進程而不是由 Windows 加載器加載。因此,我們不知道 shellcode 位于內存中的什么地方,更關鍵的是,不知道標準的 windowsAPI 函數位于什么地方(而通常情況下,Windows 加載器會告訴一個程序這些信息)。
因此,我們必須使用一系列技巧去獲得這個信息。FBI 惡意程序用了一個常用的技巧去找出它的內存地址:
call start
start:
pop ebp
call 函數將執行程序移動到 start 標簽處,同時將程序當前執行的位置壓入堆棧中(這樣我們稍后可以從 call 函數返回)。
在此,我們將要用這個值,從棧里竊取位置,堆棧彈出的值保存到 ebp 寄存器。我們現在知道了下一條指令的地址,那么就可以用它來訪問跟我們的 shellcode 相關的數據。
三、定位 Windows API
因為正常情況下 Windows 加載器會加載 Windows API 的位置到我們的程序,所以我們不奢望運行一個 shellcode 時能夠知道程序的位置信息。找出 API 函數慣用的方法是查看 FS 段寄存器所指的線程信息塊(thread information block)。我們能夠通過這個結構體去定位被我們 shellcode 宿主程序加載的 DLLs,然后利用這些 DLL 的輸出直到找到目標函數為止。當然這個過程是很乏味的,所以,FBI 這個 shellcode 使用了一個庫,包含在 MetasploitFramwork 內,這是由 Stephen Fewer 寫的一個函數解析器。它的工作原理如下:
push arguments
. . .
push FUNCTIONHASH
call<Stephen’sResolver>
這個函數的哈希值是由一個簡單的 hash 算法生成,以我們調用函數的名稱命名。這樣做的目的不是為了混淆代碼(盡管它達到這個目的),但只允許我們用一個 32 位的 DWORD 來調用此函數,而不是一個長型字符串(shellcode 空間往往是有限的)。
值得慶幸的是,我們自己可以計算出 hash 值,或者用別人生成的查找表。
四、開始
如果我們對 shellcode 的開始進行反匯編,如下圖:
我們一旦計算出指向 API 解析器的 ebp 寄存器值,我們就可以在 windows 的 API 進行哈希調用前獲取其十六進制數。如此,如果在查找表里查找到那個值,在那個值附近查找調用的函數,并且添加一些注釋,如下圖:
這段代碼執行完整性檢查,通過用 GET 開始的 HTTP 請求頭部信息以確保 shellcode 安全運行。然后調用 Windows API 函數 LoadLibrary()載入兩個動態鏈接庫:ws2_32.dll(用于互聯網通信的 Windows 套接字庫)和 iphlpapi.dll(WindowsIP 輔助庫)。
五、連接到 HTTP 服務器
在必要的庫文件都加載完之后,shellcode 將執行下圖中的操作:
再一次,用相同的步驟,用哈希值查找一個 Windows API 函數:connect ()函數。我們可以看見,在[ebp +0x2e1]位置的數據作為一個參數傳遞給 connect ()函數—從手冊我們知道,那個參數是一個 sockaddr 結構體(sockaddr structure)。我們知道 ebp 寄存器指向我們在內存中的地址,使用那個地址,再加上偏移量,我們就能定位出那些數據在內存 0x2E8 處(ebp=0×7)。
因此,我們在分析 sockaddr 之前,先給這些代碼添加一些注釋,命名一些內存偏移地址,如下圖:
這個 eax 寄存器保存著調用 connect ()函數的返回值,如果這個值為0(來自微軟用戶手冊)表示 connect ()調用成功。但是我們成功連接到哪兒?如果我們現在添加一些注釋到我們之前的反匯編文件,基于我們在微軟用戶手冊中能查到的關于 sockaddr 結構體的信息,我們可以這樣添加注釋,如下圖:
通過對 IP 地址進行 whois 快速查詢,只得到很少信息。如下圖:
六、收集用戶信息
接下來,這個惡意軟件嘗試獲得 windows 主機名—通常情況下這是 windows 機器的名字。這可能有助于確認嫌疑犯和確認他們沒有逮捕錯人。
其次,它枚舉了活躍主機的 hostname 和 IP 地址。
使用 SendARP ()函數來發現網絡中所有電腦的 MAC 地址。有一些“恰當”的方式做到這樣,但是 shellocode 只能獲得有限的空間去完成這些事。MAC 地址將用戶與一張特定的網卡綁定,于是可以通過這些網卡的供應鏈來追蹤用戶。
最后,它要構建 HTTP 頭部信息,將 MAC 地址放進 Cookie 字段,用戶的主機名放進 Host 字段,并且要以 GET 請求方式發送到 http://65.222.202.54/05cea4de-951d-4037-bf8f-f69055b279bb。這些十六進制數字的意義不清 楚,它們可能是任意選擇或鏈接一個用戶到特定的接入服務器。
七、最后階段
這個 shellcode 最后階段的唯一目的就是在該 shellcode 結束時運行更多的 shell 代碼—它這樣做的方式稍微有點迂回,我也不知道為什么這樣,也許是一次粗略的嘗試。
那么,最后一歩要怎么做。首先,它利用一些字符串長度操作找出一些被嵌入在其他所有數據區的代碼。那些代碼計算出我們的 HTTP 請求字符串結束的位置,跳過在 shellcode 結尾處的所有的無效的空操作指令,然后跳到那里。那里是哪里?誰知道!我被告知有更多的 shellcode(這不重要),但是我已經沒有時間來調試這個漏洞并獲得它。
構建頭部,然后跳轉到頭部結尾處。
查找 http 頭部結尾處的無效指令并且跳過它們。
八、運行代碼
到目前為止,我以完全靜態的方式分析了這些代碼—主要是為了完整性。通過運行這些代碼能夠更快速的分析它們,同時可以驗證我們的分析是否正確。 既然這段惡意代碼沒有任何破壞系統的行為,因此我們可以安全的在真機上運行它。于是運行它并觀察它發送給 FBI 的確切數據。因為 shellcode 不是一個 exe 可執行文件,我需要一個 shellcode 加載器去運行它—-它們快速的分配需要的內存,加載 shellcode 并跳轉到該處。這是加載 shellcode 需要做的—-在調用真正的 shellcode 之前會自動斷開。
然后我們啟動調試器跨步執行到調用 cnnect()函數。我們不得不把這個 shellcode 的目標指向另一臺我們自己的機器,便于觀察運行結果。因此,我將讓他指向 ip 地址為 192.168.0.254 的 77 端口,然后在這個機器上運行 netcat 程序抓取數據。在下圖代碼暫停的箭頭所指處,就是早期通過 patch 方式來修改 sockaddr 結構體。
然后我們繼續跨步執行到調用 send()函數,執行它,之后我們能看見在 netcat 終端的輸出,它將輸出它收到的所有數據—顯示的那些數據原本是發給 FBI。你可以看到,cookie 里面的 ID 包含了我的 MAC 地址,Host 頭部包含了我的 desktop 名。
最后,我們跨步執行到最后階段—最后的空操作可能是用來注入更多的已經提取的 shellcode。在那個十六進制查看器窗口可以看見,我們構造的那個 HTTP 請求已經發出。
九、結論
這個惡意軟件從用戶瀏覽器發送確認信息給攻擊機,然后使用戶 firefox 瀏覽器崩潰。就復雜性而言,它沒有很明顯的特別之處,也沒有使用一些大家不知道的新技術。
如果這個惡意軟件作者是 FBI,那么他們需要去回答一些很嚴肅的問題。這些惡意程序被植入到非美國的服務器上,并攻擊利用全球用戶的瀏覽器(他們當中很多人是無辜的)他們這樣做 甚至可能會得到法律授權?我不這么認為。當有人告發時 FBI 是否需要出示他們曾經得到過法律授權的證據?未必。我希望他們會依據用戶的電腦內發現的證據和在收到起訴時取得的證據—-盡管最初的搜索授權可能很不靠 譜。不管怎么說,我畢竟不是一個律師。