malware
, 資安
ywc
Draft_PSC_planning_MARCH_quarterly_planning.exe
Draft_PSC_planning_MARCH_quarterly_planning.exe
將其資料區段內容進行 xor 解密,並作為檔案內容寫入 adobe_wf.exe
, libcef.dll
, IntelCPHS.docx
, IntelGFXCoin.docx
檔案中,最後使用 ShellExecuteA API 呼叫 explorer 執行 adobe_wf.exe
程式adobe_wf.exe
程式利用 DLL sideloading 帶起同目錄下惡意的 libcef.dll
,並執行其 cef_api_hash
函式libcef.dll
將 IntelCPHS.docx
和 IntelGFXCoin.docx
內容進行 xor 解密,寫入 WinDbg.exe
和 coreclr.dll
檔案中,並使用 schedule task 排程每兩分鐘嘗試執行 WinDbg.exe
程式WinDbg.exe
程式利用 DLL sideloading 帶起同目錄下惡意的 coreclr.dll
,並執行其 GetCLRRuntimeHost
函式coreclr.dll
檢查並使用 exception handling 機制跳轉到 handler 函式中,將資料區段中的 shellcode 用 xor 解密後放入 VirtualAllocEx 創建的 RWX 空間中,並呼叫執行 shellcodeTONEDROP
+ TONESHELL
varient bDraft_PSC_planning_MARCH_quarterly_planning.exe
: 2020/01/10adobe_wf.exe
(benign): 2021/11/29libcef.dll
: 2023/02/13Windbg.exe
(benign): 2018/10/24coreclr.dll
: 2022/09/21Draft_PSC_planning_MARCH.pdf
Draft_PSC_planning_MARCH_quarterly_planning.exe
212.114.52.210:443
libcef.dll
中,使用 schedule task 設定每兩分鐘嘗試執行一次 Windbg.exe
歐盟
Earth Preta
(MUSTANG PANDA
)coreclr.dll
解密 shellcode 的方式是 xor 加解密的變體,如下所示libcef.dll
, coreclr.dll
部分,部分字串會先進行 xor 加密後,再使用相同的 xor key 進行解密coreclr.dll
部分,使用 exception handling 進行控制流轉移此樣本有兩個檔案,分別是 Draft_PSC_planning_MARCH.pdf
和 Draft_PSC_planning_MARCH_quarterly_planning.exe
,以下會將這兩個檔案和延伸的部分嘗試進行完整的分析
Filetype:
Hash (MD5):6a33fc4b0428b8fd420790a895f2294a
Date Modified:2023/03/07
該檔案是一個 decoy file,檔案內容如下
可以看到這是一個類似內部行事曆的內容,行事曆的月份是 2023 年的 3 月,在行事曆中可以看到與一個叫做 PSC 的組織有關,且內容可以看到有烏俄戰爭、歐盟議會等等
透過基本的搜尋,可以找到一個叫做 Political and Security Committee (PSC) 的歐盟組織,推測為該樣本的攻擊目標
Filetype:
PE 32bit
Hash (MD5):6cc47b9fc19c67b4c61aa2173f4c8b47
Date Modified:2023/03/07
該檔案是一個使用資料夾 icon 的一個 PE 32bit exe 檔案,推測觸發該執行檔的方式為誤導受害者以為它是 decoy file 的附件,雙擊開啟後觸發執行
以下是使用 Detect It Easy (DIE) 工具偵測出的開發工具環境,推測攻擊者使用 Visual Studio 進行惡意程式的開發及編譯
在 PE 的 IMAGE_FILE_HEADER 中可以看到 TimeDateStamp 記載著執行檔的編譯時間為 2020/01/10 19:14:33
以上部分為檔案的基本資訊,接下來會使用 IDA 反編譯工具進行更詳細的分析
在 main 函式中,可看到一開始該程式會嘗試建立 C:\Programdata\LuaJIT
的資料夾,不過後續沒有使用該資料夾,推測是用來偵測是否曾被感染過避免二次感染主機 (類似 mutex 的功能)
而透過搜尋該資料夾名稱,可以找到 Behind the Scenes: Unveiling the Hidden Workings of Earth Preta 這篇報告,提及 TONEDROP family 會使用該名稱資料夾作為是否感染過的判斷,因此可以初步推斷該惡意程式可能是 TONEDROP 類型 (而後續的一些分析可以更加確定這一點)
在建立資料夾的下一步,該惡意程式會做一些 anti-debugging 的行為,首先會檢查 process list 中是否含有一些已知的分析程式如 cheatengine、IDA、x64dbg、procmon 等存在 (sub_401000
,下二圖),假如前項通過後還會使用 FindWindowW API 再檢查是否有一些 debugger 常見的視窗名稱存在 (下一圖),避免分析人員修改分析工具執行檔名稱繞過第一項檢查
下一步,該惡意程式會將 data section 中的四個位置分別做 xor 解密,並將解密的 payload 寫入到 C:\users\public\
資料夾下的各檔案中,解密金鑰為 b7eb9f9e922473a27010e42da25be9d14f9e0df8e9aebddb3f9f50863a249ee47ff0cbf01ca65d9458ac7bd35cb202b3e54b7172cac6c2aa90a9a967cb182fdc
(註: 非 16 進位資料,純文字進行解密),被加密 payload 的位置、大小、寫入檔案資訊整理如下
offset (dynamic VA) | size | filename |
---|---|---|
0x585538 | 0x636D8 | adobe_wf.exe |
0x4D2D38 | 0xB2800 | libcef.dll |
0x454738 | 0x7E600 | IntelCPHS.docx |
0x41A8B0 | 0x39E88 | IntelGFXCoin.docx |
一個簡單的解密腳本如下
在此惡意程式的最後一步,他會呼叫 sub_4011B0
函式,該函式會使用 kernel32 的 LoadLibraryW API 載入 User32 和 Shell32,並使用 Shell32 的 ShellExecuteA API 呼叫 explorer 執行 adobe_wf.exe
程式
Filetype:
PE 32bit
Hash (MD5):c751af3a2b5e5085e0cf4a66a09480d9
此程式是由前項惡意程式解密並寫入檔案系統後,自動帶起的一個程式
以下是使用 DIE 工具偵測出的開發工具環境,可以看到該程式也是由 Visual Studio 所開發,另外也可發現該程式帶有簽章
在 IMAGE_FILE_HEADER 中的 TimeDateStamp 可以看到該執行檔的編譯時間為 2021/11/29 22:04:25
在簽章內容中可看出是由 Adobe Inc.
所簽發,且簽章合法,代表它是一個正常的執行檔
而由於它是一個正常的執行檔,照理說不會有惡意行為,不過由於前項惡意程式在該執行檔的相同目錄中同樣也產生了一個 libcef.dll
檔案,因此可以假定此執行檔執行時有載入 libcef.dll
的行為,但因為 DLL sideloading 的關係載入的不是系統中的 libcef.dll
而是同目錄下的 libcef.dll
,真正的惡意攻擊行為是藏在該 DLL 中
為了驗證前項假設,可以嘗試用 IDA 分析工具嘗試進行分析
首先在執行檔中的 Import Address Table (IAT) 中可看到該程式確實會進行 libcef.dll
的載入
在觸發 libcef.dll
惡意攻擊行為的部分,在 WinMain
函式中會呼叫 sub_405ED0
函式,該函式會再呼叫 libcef.dll
中的 cef_api_hash
函式,執行惡意 DLL 中唯一 export 出來 (扣除 DLLEntryPoint
) 的 cef_api_hash
函式
btw 這個執行檔的 pdb 資訊中可以看出 adobe 內部有使用 jenkins CI/CD 工具 :)
Filetype:
PE 32bit DLL
Hash (MD5):731826d52e6f3527786fe5cff48ef171
首先一樣嘗試使用 DIE 工具分析該 DLL 的開發工具環境,不過沒有發現比較有用的資訊
在 IMAGE_FILE_HEADER 中的 TimeDateStamp 可以看到該 DLL 的編譯時間為 2023/02/13 13:51:25
以上部分為檔案的基本資訊,接下來會使用 IDA 工具進行更詳細的分析
首先是 pdb 的部分如下,基本上看不出什麼有用的資訊,只知道是使用 debug mode 去編譯的
如同 adobe_wf.exe
所述,該 DLL 除了有 DLLEntryPoint
之外,還有 export cef_api_hash
函式做為惡意行為的進入點,因此以下將以 cef_api_hash
作為起始進行分析
在該函式的一開始,除了一些基本的 memset
做資料初始化之外,最主要可以看到有一個 kernel32.dll
的字串的每個 byte 都進行 xor,而後在 79 行時又會對該字串再做一次 xor 運算,不過可以看出他的運算式是 (0x9ef2 + i) (-0x610e + i),而 -0x610e 的二進位補數恰巧是 0x9ef2,因此該運算基本上等同於 xor 0,也就是該字串在運算完後的值就跟原本一樣,這是它的字串混淆方法,而除了 kernel32.dll
字串之外,在其他字串的部分也可以看到類似的混淆方法
忽略掉字串混淆的部分,該函式的第一個行為是使用 kernel32.dll
中的 CreateEventA
創建一個 iygyjtfurt
的 event,不過後續沒有到該 event,推測目的應該與先前分析的Draft_PSC_planning_MARCH_quarterly_planning.exe
的 LuaJIT
資料夾一樣是用來避免重複執行惡意行為
另外在該部分取得 CreateEventA API 的地方使用 sub_10007E50
函式,而追蹤從 sub_10007E50
-> sub_10007F90
-> sub_10007FF0
-> sub_10007FF0
最終可以看到一些字串訊息如 DefWindowProcW1222_test
、Find function HeapAlloc
等
透過搜尋引擎搜索這些字串,可以找到 Tai7sy/vs-obfuscation 和 Sha256: … - LevelBlue - Open Threat Exchange 這兩個連結,前者是一個混淆工具的 GitHub repo,且比對程式碼之後推測此惡意 DLL 有使用該工具進行字串混淆等行為。而在後者的部分,是一個有出現這些字串但是是其他惡意程式的檢測結果,該程式在 VirusTotal 上被偵測為 toneshell family,而這也更進一步支持目前分析樣本是 toneshell 相關 family 的一個判斷依據
在建立 event 的下一步,該惡意 DLL 將 data 區段上的資料做 xor 解密,xor key 是 0x7d,資料位置及解密後的字串整理如下
Address (dynamic VA) | Decrypted String |
---|---|
0x100AD208 | C:\Users\Public\Documents\WinDbg.exe |
0x100AD30C | C:\Users\Public\Documents\coreclr.dll |
0x100AD000 | IntelGFXCoin.docx |
0x100AD104 | IntelCPHS.docx |
可以看到,解密出來的資料似乎是檔案名稱,而可以看到在解密完的 IntelGFXCoin.docx
和 IntelCPHS.docx
字串中還會再透過 command line argument 中取得的當前執行目錄組合這兩個檔案名稱,將它們轉換成絕對路徑
在下個階段,該惡意 DLL 透過 wstrcat
組合一串設定 schedule task 的指令,並在最後使用 CreateProcessW API 做執行
該 schedule task 的完整指令為 schtasks /create /sc minute /mo 2 /tn \"Windowstore\" /tr \"C:\\Users\\Public\\Documents\\WinDbg.exe\" /f
,用途是設定一個叫做 Windowstore
的工作,每兩分鐘會嘗試執行 WinDbg.exe
,而下個階段可以看到該檔案是用於下一階段的惡意行為執行,因此此部分是用於程式常駐使用
另外,在此階段時 schedule task 指令不是一次寫完而要使用字串串接方式進行,推測有部分原因是要規避防毒軟體偵測,不過我認為最大的原因是方便攻擊族群直接抽換關鍵偵測字串如 task name、執行檔名稱等,在針對該惡意行為的偵測規則被生成出來之後可以方便的替換掉,使規則失效
在下個階段,該 DLL 呼叫了 decryptAndCopyfile_100013E0
函式進行解密檔案和複製的行為
在該函式中,第一步會使用 CreateFileW API 以讀取模式開啟檔案
第二步會使用 GetFileSize API 讀取原始檔案的大小,分配適當的空間
第三步會用 ReadFile API 做檔案資料讀取
而第四步會將讀取的資料做 xor 解密,而解密金鑰是由傳入的第三個參數決定是 0x36 或 0x2d,在此例中 IntelGFXCoin_docx
會使用 0x36 而 IntelCPHS_docx
則使用 0x2d
最後一步,創建新的檔案,並將解密後的資料進行寫入
以下是一個簡單的解密腳本
在最後的階段,該 DLL 會先使用 GetCurrentProcess API 取得當前的 process handle,並使用 TerminateProcess 結束程式執行
Filetype:
PE 32bit
Hash (MD5):17e40315660830aa625483bbf608730c
此程式是由前項惡意 DLL 程式解密後,透過 schedule task 帶起的一個程式
以下是使用 DIE 工具偵測出的開發工具環境,可以看到該程式也是由 Visual Studio
所開發,另外與 adobe_wf.exe
相同,可發現該程式帶有簽章
在 IMAGE_FILE_HEADER 中的 TimeDateStamp 可以看到該執行檔的編譯時間為 2018/10/24 10:23:21
在簽章內容中可看出是由 Mircosoft Corporation
所簽發,且簽章合法,代表它是一個正常的執行檔
與 adobe_wf.exe
類似,既然它是一個正常的執行檔就應該不會有惡意行為,而在前面的 DLL 惡意行為中有在該執行檔的同目錄下寫入一個 coreclr.dll
,因此推測應該也是利用 DLL sideloading 技巧載入該 DLL 後才觸發惡意行為,惡意攻擊行為藏在該 DLL 中
為了驗證前項假設,可以嘗試用 IDA 分析工具嘗試進行分析
與 adobe_wf.exe
不同,該執行檔的 IAT 中並沒有看到 coreclr.dll
的載入
不過,從 WinMain
-> sub_406780
-> sub_409510
-> sub_40B690
的 function call chain 中,可以發現在 sub_40B690
中使用了 LoadLibraryW API 進行 coreclr.dll
的載入,並呼叫 GetCLRRuntimeHost
函式
而在 coreclr.dll
的 export table 中確實存在該函式,推測應該是惡意行為的進入點
Filetype:
PE 32bit DLL
Hash (MD5):984b7abf11cf6a13ccd3b99e8f437397
首先一樣嘗試使用 DIE 工具分析該 DLL 的開發工具環境,不過與惡意的 libcef.dll
一樣沒有發現比較有用的資訊
在 IMAGE_FILE_HEADER 中的 TimeDateStamp 可以看到該 DLL 的編譯時間為 2022/09/21 14:21:58
以上部分為檔案的基本資訊,接下來會使用 IDA 工具進行更詳細的分析
如同 Windbg.exe
所推測,該 DLL 的惡意行為進入點為 GetCLRRuntimeHost
,因此以下將以該函式作為起始點進行分析
首先,在 GetCLRRuntimeHost
中,會直接呼叫 sub_10002D00
函式
在 sub_10002D00
中,最一開始會看到有出現類似 libcef.dll
中的字串混淆方式
忽略掉字串混淆的部分,該函式的第一步是使用 CreateEventA API 建立一個名為 ydgffsrbtyt5ster
的 event,推測應該也是用於確保不要重複感染系統
下一步,會先使用 GetModuleFileNameA API 取得當前執行檔的位置,並與一個 xor 解密後的字串做比較,相同的話會進入下方區塊,否則進入上方區塊
xor 解密的金鑰為 0x7e,解密後的字串為 C:\\Users\\Public\\Documents\\WinDbg
,可以看到解密後的字串與 libcef.dll
段落描述的寫檔路徑相同,而一般來說對於惡意程式動態分析而言,通常會將程式置於沙箱中,因此程式路徑會有所改變,可推測此處檢查是為了避免沙盒動態分析
在上一步中,程式分成兩條路線,不過二者都呼叫了 sub_1000B410
只是所帶的參數不同
而在 sub_1000B410
函式中,雖然中間部分看起來很複雜,但是基本上看起來是觸發 exception handling 的部分
而觀察二者帶入的參數,可透過第二個參數推測出正確的 exception handler 位置
在路徑比對不一致的區塊中 (上方區塊),第二個參數帶入 0x10049464
,因此透過下方的 reference 關係得出 handler 位置為 0x10004770
而路徑比對一致的區塊中 (下方區塊),第二個參數帶入 0x100494A4
,因此透過下方的 reference 關係得出 handler 位置為 0x10005470
由於已知程式會進行路徑的檢查並分成兩條路線,因此此處將著重在路徑比對一致的 exception handler 函式分析
在此函式中,首先會先使用 GetCurrentProcess API 取得當前的 process handler,並結合 VirtualAllocEx API 在該 process 中創建一個 0x6000 大小的記憶體空間,權限為可讀、寫和執行
當創建記憶體空間後,會先將 0x1004b000
位置的資料用 0x7e
做 xor 解密,並將解密後的字串作為 xor key 並再與 0x1004B021
位置 0x6000 bytes 大小的資料做 xor 解密,解密後的資料會複製進 VirtualAllocEx API 創建的記憶體空間中,並進行執行
因此,我們可知 0x1004b000
位置的資料是加密後的 xor key,該 xor key 的解密金鑰為 0x7e
,而 0x1004B021
則很可能是加密後的 shellcode
值得一提的是,進行 shellcode 解密的函式並非一般的 xor 解密函式,函式內容如下,在他的循環條件中可看到 v4
變數從一開始 0 ~ str2_len - 1
,之後會先設定成 0 並馬上執行 ++v4
的行為,因此接下來的循環中的 v4
變數會是 1 ~ str2_len - 1
的循環,並非從 0 開始
以下是一個解密並提取 shellcode 的腳本,執行後可提取 shellcode 並進入下一步分析
除了上面的執行流程之外,在此 DLL 中還可以發現一些類似中文姓氏的字串,推測可能為此惡意 DLL 開發者的署名
取得 shellcode 後,以下使用 shcode2exe 工具將 shellcode 先轉換成 exe 的形式,以方便後續分析
在入口點的地方,會直接呼叫 main_401090
函式
在 main_401090
函式的初始化區塊中,可以看到有像是 IP 和 port 列表的資訊,推測應該是存放惡意程式的 C2
該函式的第一步會嘗試使用 get_module_from_peb_401770
函式從 PEB 資訊塊中找出一個特定的 module,帶入資料是一個自定義的 hash,他會將 PEB 中每個 module 的名稱做 hash 之後進行資料比對已找出特定的 module
hash 函式的內容如下
為了找出具體是要使用哪個 module,可以嘗試先取得載入的 module 資訊,並列舉計算 hash 並比對,可以發現他會取得 kernel32.dll
module
當取得 kernel32.dll
後,該函式會再透過列舉導出函式表的方式尋找特定的模組,並且也使用比對 hash 的方式進行查詢,而在此時它會先找出 GetProcAddress 和 LoadLibraryA API 的位置
而在 loadFunctions_401900
函式中,會透過先前找出的 LoadLibraryA 和 GetProcAddress 載入並取得更多 shellcode 所需的 API,他使用類似 function table 的結構進行儲存
當載入完函式後,該 shellcode 會建立並初始化一個自定義的結構,在此簡稱為 commblock,該結構的主要目的是方便管理通訊和訊息資訊
另外值得一提的是,在 createCommblock_4026c0
-> getCryptoContext_402930
函式中會嘗試建立一個 MyKeyContainer
crypto context,以用於後續亂數產生器的使用
在建立完 commblock 後,會進入到主要的 doWork_4031E0
函式
在 doWork_4031E0
函式中,首先他會執行 getComputerRandomNumber_402C10
函式取得一個類似裝置序號的資訊,基本上是拿裝置電腦名稱、使用者名稱、硬碟序號資訊計算而成
在取得裝置序號後,會執行一個 while true 無窮迴圈,而在迴圈中會嘗試遍歷 C2 IP list 和 port list,先將 IP 部分的 hostname 轉換成 IPv4 形式,並將轉換後的 IP 和 port 嘗試建立 socket
在建立 socket 後,會嘗試進行一次 pingpong 通訊以確認受害者與 C2 間網路通訊正常,確認正常後會呼叫 communicate_402B10
函式做後續的溝通行為
pingPong_402DB0
函式的內容如下
從反組譯程式碼中,可以看出相關的封包結構,首先受害者電腦端會送出以下的封包,可以看到傳送了訊息類別 0x2 的資料
而 C2 預期會回傳以下封包,可以看到收到了訊息類別 0x1 的資料
在 communicate_402B10
函式中,首先可以看到 shellcode 會先用 CreateThread 生成一個新的 thread,而後會不斷的嘗試從一個類似 linked list 的 PIPE 結構中取得要傳送的 message,嘗試進行傳送並取得回應
在 sendMsgAndRecv_4035E0
函式中,會呼叫 sendAndRecv_404350
進行資料的接收,並會根據回傳的訊息類別進行 buffer 大小的檢查,當 buffer 大小符合預期,會將訊息塞入另一個接收用的 PIPE
sendAndRecv_404350
函式的內容如下,基本上與 pingpong 的程式碼相似,不過可以看到多了 prepare_sendbuf_404230
和 recv_and_decode_4044E0
函式
在 prepare_sendbuf_404230
和 recv_and_decode_4044E0
函式的程式碼中可以觀察到,在前面 pingpong 時傳送封包中空白的部分是一些隨機產生的資料,主要用途是作為封包資料的 xor key
因此,綜合以上觀察,可以發現一般通訊下伺服器回傳的封包格式如下
而根據相關資料,可以推測該 shellcode 應該是 toneshell varient b 的形式
而回顧 communicate_402B10
函式,他會生成另一個 thread,thread handler 如下所示
可以看到,它會不斷的嘗試從接收的 PIPE 取得訊息,當有訊息時會執行 doCommand_404700
函式
在 doCommand_404700
函式中,可以看到它會根據接收的訊息類別進行相對應的行為,對應的行為可以從其錯誤訊息字串中觀察到
以下是整理出的訊息類別和對應的行為
type | behavior | ret code |
---|---|---|
0x3 | create TOnePipeShell | |
0x9 | cleanup TOnePipeShell | |
0xa | cleanup TOnePipeShell | |
0xb | stop execution | |
0x4 | upload file begin (create file) | 0x6 |
0x5 | upload file write (write file) | 0x7 |
0x6 | upload file end (write and close file) | 0x8 |
0x7 | upload file cancel (delete file) |
此外在 Upload file 相關訊息類別部分,可以觀察到會將執行狀態回傳給 C2 伺服器,正常執行狀態碼資訊列於上表中,如遇到異常狀態,則回應狀態碼 0xa 並將錯誤訊息置於資料欄位中
最後是 create TOnePipeShell 發生錯誤的情況,則會傳輸以下封包內容,資料區段為錯誤訊息部分