一、概述
BokBot惡意軟件由LUNAR SPIDER惡意組織開發和運營,在2017年首次出現,CrowdStrike的Falcon Overwatch和Falcon Intelligenc團隊對被感染主機進行了分析。最近,由于借助MUMMY SPIDER惡意組織的Emotet惡意軟件進行分發活動,BokBot的感染數量又有所增加。
BokBot惡意軟件具有強大的功能,分為命令和控制、模塊化兩類,具體功能包括:執行進程、注冊表編輯、寫入文件系統、登錄、混淆、防篡改、竊取憑據、攔截代理、通過VNC進行遠程控制。
此外,已經發現BokBot可以從其他惡意軟件中下載并執行二進制代碼,例如Azorult infostealer。
本文將深入探討BokBot主要模塊的技術細節。
二、BokBot容器執行
最初,BokBot被加密包裝。在最終解壓縮BokBot二進制文件并將其注入到svchost.exe之前,加密器經歷了幾個階段。以下是這些不同階段的簡單概述:
· 第一階段(加密器):解碼第二階段的內容并執行。
· 第二階段(加密器):解碼ShellCode并執行。
· 第三階段(ShellCode):對基礎進程映像進行Hollow,解碼核心進程注入PE,使用核心進程注入PE覆蓋基本進程映像。
· 第四階段(進程注入):執行進程注入代碼,啟動svchost.exe子進程,將BokBot作為無頭部的PE映像注入子進程。
我們使用CrowdStrike Falcon平臺,主要可以分析第四階段的過程。因此,本文的重點是BokBot注入子進程的這一過程,惡意軟件作者在這里采用了一種獨特的方法。
2.1 進程注入
為了繞過反病毒檢測,從而可以對進程進行Hollowing,BokBot對幾個Windows API函數進行了掛鉤,并執行掛鉤代碼,然后刪除鉤子。
2.1.1 模擬進程Hollowing過程
為了模擬這一過程,ZwCreateUserProcess例程將被首先掛鉤。BokBot調用ZwProtectVirtualMemory,將例程的權限修改為PAGE_READWRITE。接下來,前五個操作碼(字節)被替換為JMP<掛鉤代碼地址>指令的操作碼。在恢復權限后,調用CreateProcessA。
在調用CreateProcessA后,函數調用鏈將會走到調用ZwCreateUserProcess的地方,隨后調用掛鉤代碼,如上圖所示。
掛鉤代碼將通過從ZwCreateUserprocess例程中刪除掛鉤,來完成子進程的創建,然后調用沒有掛鉤的ZwCreateUserProcess過程。這樣一來,將會創建子進程,但在CreateProcessInternal返回之前不會執行。其余的掛鉤例程將解碼,并將嵌入的BokBot二進制文件注入svchost.exe的子進程。
2.1.2 代碼注入
在注入代碼之前,BokBot PE首先被解壓縮,并被加載到本地進程內存中。加載后,以下Windows過程用于分配和寫入svchost子進程:
ZwAllocateVirtualMemory
ZwWriteVirtualMemory
ZwProtectVirtualMemory
將主BokBot模塊寫入子進程后,將開始執行BokBot代碼。
2.1.3 代碼執行
BokBot采用了一種新穎的技術,來實現代碼在子進程內部的執行。使用與之前相同的API,Dropper將掛鉤子進程中的RtlExitUserProcess。由于svchost.exe是在沒有參數的情況下啟動的,因此會立即終止。當進程嘗試退出時,它將調用掛鉤的RtlExitUserProcess,從而執行BokBot Payload。
在CreateProcessInternalW恢復執行之前,針對掛鉤的例程,還有一個任務要完成。
2.1.4 注入上下文數據結構
將BokBot Payload注入子進程后,要將上下文數據結構寫入子進程。下面的上下文中,包含所需的所有數據,可以確保BokBot的主模塊在執行過程中不出現問題。
1、Windows過程地址:
ntdll.ZwAllocateVirtualMemory
ntdll.ZwWriteVirtualMemory
ntdll.ZwProtectVirtualMemory
ntdll.ZwWaitForSingleObject
ntdll.LdrLoadDll
ntdll.LdrGetProcedureAddress
ntdll.RtlExitUserProcess
ntdll.ZwCreateUserProcess
ntdll.RtlDecompressBuffer
ntdll.ZwFlushInstructionCache
2、加載Payload的地址
3、Dropper二進制文件的路徑
4、C&C URL
5、項目ID
在Dropper進程的整個生命周期中,將會收集上述數據。此外,在下載和執行模塊時,類似的結構將會被寫入到BokBot的子進程。
在注入后,CreatProcessInternalW會恢復,并且Dropper進程將退出。BokBot的主模塊將進入到初始化階段。
三、BokBot初始化
在執行主循環和C&C通信之前,BokBot首先經歷了幾個初始化步驟,為C&C通信做好準備。初始化的具體步驟如下:
1、刪除RtlExitUserProcess的掛鉤
2、創建內存映射文件,以存儲日志記錄數據
3、以登錄用戶身份,執行BokBot(如果當前進程是以System運行)
4、關閉錯誤告警
5、收集系統信息:Windows版本信息、用戶SID、域成員信息
6、生成唯一ID
7、防止多次執行
8、在主機上安裝BokBot
9、將現有下載模塊注入到子進程中
在下面,我們將詳細介紹其中的一些步驟。
3.1 關閉錯誤告警
為了防止出現錯誤提示,從而使受害者得知具體問題,BokBot將進程的錯誤模式設置為0x8007,具體對應如下:
SEM_FAILCRITICALERRORS
SEM_NOALIGNMENTFAULTEXCEPT
SEM_NOGPFAULTERRORBOX
SEM_NOOPENFILEERRORBOX
這樣一來,將會禁用進程崩潰時產生的大多數錯誤通知。
3.2 生成唯一ID
在早期進程執行期間,生成了幾個唯一的ID,BokBot將使用這些ID。這些值將被傳遞給C&C服務器,并會作為RC4加密算法的密鑰,同時也傳遞給子進程。
3.2.1 項目ID
除了將主BokBot模塊注入svchost之外,Dropper還會將一大塊二進制數據注入,為BokBot執行提供上下文,其中也包括項目ID。這些唯一的項目ID值,似乎是用于識別與分發活動對應的感染。項目ID是一個4字節值。
3.2.2 Bot ID
針對受感染主機上每個用戶的特定實例,其Bot ID是唯一的。該值將用作加密密鑰,以及生成BokBot各種唯一值所需的種子。例如,為文件及事件名稱生成的偽隨機字符串,我們將在后續章節中進一步討論。
Bot ID會以下面兩種方式中的一種來生成:
1、帳戶名稱的安全ID(Security ID)
2、文件時間格式的系統時間
由于這兩個值都是64位,所以無論是用哪種方法,該值都會被分為兩個32位塊,并且會被異或。
3.2.3 ID哈希值
除了Bot ID之外,還會生成一個簡單的哈希值,用來驗證Bot ID和項目ID的有效性。該哈希值使用Bot ID和項目ID來生成,具體方法如下:
hash = (( BotID / 0x100001E) & 0xFF) + ((BotID/0x10000) & 0xFF)
hash = (ProjectID[3] + hash[0]) & 0xff
hash = (BotID [0] + hash) & 0xff
hash = (ProjectID[0] + hash[0]) & 0xff
hash = (ProjectID[1] + hash[0]) & 0xff
hash = (ProjectID[2] + hash[0]) & 0xff
該值將與項目ID、Bot ID一起作為C&C URL參數的一部分來傳遞。如果該請求無效,受感染的主機將不會收到來自C&C的任何指令。
四、C&C主機名初始化
Bokbot包含編碼后的C&C主機名列表,這些主機名會作為Dropper注入的上下文數據結構中的一部分。該結構中的C&C列表,也會使用由上下文提供的密鑰進行解碼,然后使用rdtsc指令生成的新密鑰進行重新編碼,最后存儲為指針數組。
五、防止多次執行
使用Bot ID生成唯一的全局命名事件。通過調用GetLastError,繼續成功調用CreateEvent。如果惡意軟件已經在執行,那么最后一個產生的錯誤將會是ERROR_ALREADY_EXISTS,隨后進程將退出。
六、安裝過程
在安裝過程中,將BokBot Dropper二進制文件寫入安裝目錄,并創建計劃任務,以保證其持久性。
安裝目錄將在以下根目錄中創建:C:\ProgramData
安裝目錄的名稱是唯一的,使用Bot ID生成。在創建目錄后,使用Bot ID作為種子對原始的Dropper文件進行重命名,并寫入目錄。由于Bot ID基于系統信息,因此將其用作種子就可以確保惡意軟件始終在特定主機上生成相同的安裝路徑和文件名。
在生成安裝目錄名稱后,BokBot需要為將要寫入該目錄的BokBot二進制文件生成一個文件名。下面的Python代碼重現了BokBot用于生成文件名的算法,以及其他各種字符串。
腳本中的str_id值是一個硬編碼的整數,與Bot ID一起使用,可以生成一致的字符串。例如,使用Bot ID 0x2C6205B3以及str_id 2,總是會生成字符串ayxhmenpqgof,但假如將str_id換為6,生成的字符串就會變為bwjncm。
以下是安裝路徑的示例:
C:\ProgramData\{P6A23L1G-A21G-2389-90A1-95812L5X9AB8}\ruizlfjkex.exe
在這里,將會創建計劃任務,以在Windows登錄時執行。任務名稱的生成方式與安裝目錄相同。
· 任務名稱:{Q6B23L1U-A32L-2389-90A1-95812L5X9AB8}
· 觸發:登錄時
· 動作:啟動一個程序
· 詳細信息:BokBot Dropper路徑
七、C&C通信
BokBot通過HTTPS請求與C&C服務器進行通信,并通過URL參數和POST參數,將各種值傳遞給服務器。除了服務器使用的SSL/TLS之外,URL請求數據沒有進行加密或模糊處理。
下面詳細介紹了所有請求所必須的主要參數、一些其他的可選參數,以及Bot的注冊過程。
7.1 主要C&C請求和響應參數
每個請求或響應都會將這些參數發送到服務器。這些內容將會為C&C提供有關請求/響應類型以及唯一標識受感染計算機的信息:
/in.php?g=2&c=3592L387P92A771N77&p=0&r=102
對于這些參數,更詳細的描述請參見下表:
URL路徑通常會在不同版本之間有所不同。例如,版本100-102使用的是/data100.php,而不是/in.php。
7.2 附加C&C請求和響應參數
在BokBot中,包含一個連續循環的通信線程,該循環直至進程退出,持續從C&C服務器檢索指令。除了上面已經描述的參數之外,請求中還包含一些附加參數。當Bot向C&C服務器返回命令的執行結果時(例如:上傳屏幕截圖時),不會發送這些參數。
下面URL參數中,展示了與C&C初始連接的示例:
/in.php?g=2&c=42454B23
在這個示例中,沒有Web注入,沒有C&C URL,也沒有下載任何模塊,因此其中的一些重要參數值都為0或空。在這里,生成了初始時間戳,版本號為靜態的。
八、初始Bot注冊
注冊請求會與每個發送到C&C的標準C&C URL參數相組合。在初始請求之后,C&C服務器將命令發回受害者主機,并發送信號通知其下載Web注入、更新的C&C主機名、可執行模塊或其他要執行的任務。
初始注冊URL中,包含與系統信息相關的參數。以下字符串是一個示例:
在下表中,描述了注冊URI參數:
下面是注冊請求(紅色)和C&C(藍色)響應的示例,其中包含發送給受感染主機的命令。
8.1 C&C命令
在本節中,將分析C&C發出的命令請求。來自C&C的每個命令,都采用以下格式:
當前版本的BokBot中,提供了以下命令:
需要注意的是,這些命令的ID值可能會在不同版本之間更改。如此列表所示,BokBot為運營商提供了各種與受感染機器進行交互的選項。
8.2 URL下載命令處理程序
其中,許多命令都會觸發命令處理程序函數,該函數需要與C&C URL或服務器請求參數中指定的其他URL進行通信。如果請求指定,那么從目標URL下載的數據就會被寫入到DAT。無論下載的數據是否被寫入到DAT文件,它都將由以下C&C命令之一的回調函數處理:
1、啟動一個新的可執行模塊,重啟當前可執行模塊。
2、更新Web注入(任一命令)
3、更新配置
4、更新BokBot
5、寫入文件
6、下載并執行二進制文件
使用C&C URL主機名的命令,將會發送d URL參數,示例如下:
該值通常設置為0,要下載的文件將由g參數指定。
九、模塊和DAT文件
從C&C接收的所有需要在重新啟動計算機后保留的數據,都會在受感染的計算機上寫入到DAT文件中。這些文件包括:Web注入配置、C&C配置和外部模塊。
使用Bot ID作為密鑰,主模塊和子模塊將根據需要,對每個文件進行加密和解密。每個模塊都有一個唯一的標簽。
9.1 生成唯一標簽
BokBot會為注入的進程、下載的模塊和下載的DAT文件分配唯一的標簽。這些標簽是執行BokBot進程以識別外部進程資源的一種便捷方法。標簽的生成非常簡單:
· 18 – Web注入配置文件,在二進制文件中靜態定義。
· 19 – 報告配置文件,在二進制文件中靜態定義。
· 20 – C&C配置文件,在二進制文件中靜態定義。
· 33-46 – 下載的模塊將注入子進程。需要以增量的方式分配,不一定是對模塊所做的唯一標記。
在對BokBot的分析過程中,這些值將會定期出現,其中也包括生成唯一文件名的值,會在后面詳細描述。
十、下載DAT文件
如前所述,DAT文件是根據C&C發送的命令進行下載。一旦從C&C接收到命令,就會調用特定于此命令的處理程序,來處理該請求。作為響應,受感染的機器將會通知C&C它已經準備好接收RC4加密后的Blob。下圖說明了下載配置文件和模塊的命令的過程。
一個8字節的RC4命令將會被添加到數據緩沖區。在將Blob寫入文件之前,BokBot會對文件進行解密,然后使用基于Bot ID的新RC4密鑰,對其進行重新加密。
10.1 寫入文件
BokBot在C:\ProgramData下創建一個新目錄來存儲DAT文件。使用前面描述的字符串生成算法,生成目錄名稱。使用唯一標記值,生成DAT文件名。該唯一標記值也是通過字符串生成算法(取決于Bot ID)運行,該算法會返回DAT文件的唯一文件名。
上表中引用了我們測試過程中發現的所有DAT文件。在我們的測試環境中,安裝目錄是C:\ProgramData\yyyyyyyyiu\。
10.2 可執行模塊
BokBot有幾個可執行模塊,可以下載并注入svchost.exe子進程。一旦使用RC4解碼相關的DAT文件,就不需要對可執行模塊DAT文件進行額外的解碼或解壓縮??蓤绦心K頭包含識別模塊所需的信息:
文件的其余部分,包含加載和執行模塊所需的數據,包括PE文件的各個部分,以及自定義PE頭。
模塊的注入與執行過程,使用類似于Dropper的技術來注入可執行模塊,并且去掉了ZwCreateUserProcess的掛鉤,并暫停子進程啟動(CREATE_SUSPENDED)。通過添加RtlExitUserProcess掛鉤,它更接近于傳統的進程遷移。
1、PE圖像加載
由于沒有標準的PE頭部,所以DAT文件中必須包含所有相關信息(虛擬大小、重定位等),以便將這個二進制文件正確映射到子進程。該數據是DAT文件標頭的一部分。BokBot在將二進制文件注入子進程之前,現在本地進程內存中構建二進制文件。
2、注入
注入過程,使用與Dropper相同的API,也就是ZwAllocateVirtualMemory、ZwWriteVirtualMemory和ZwProtectVirtualMemory。在注入后,使用ResumeThread恢復進程。
3、執行上下文注入
再一次,在執行之前,先將執行上下文結構寫入子進程。這里包含的一些信息包括:Bot ID、項目ID、C&C主機名、URL路徑格式字符串。
這樣一來,就可以保持父進程與子進程之間的一致性,不需要生成新的唯一標識符,所有加密密鑰都是相同的:相同的主機名,甚至也有相同的URL路徑。父進程和子進程之間的一致性對于使用進程間通信(IPC)在兩者之間發送的消息是非常必要的。
將模塊注入子進程后,解密的DAT文件的前四個字節將添加到一個數組中,BokBot使用該數組來標識當前正在執行的模塊。
10.3 數據文件
其他DAT文件包含與C&C通信或Web注入相關的所必須的數據。從本質上講,這些文件提供了主要BokBot進程和可執行模塊完成其工作所需的任何其他數據。
配置文件包含BokBot主模塊與C&C保持通信所需的所有數據。一旦使用特定于進程的RC4密鑰解密文件,就不再需要額外的解壓縮或者解密過程。
每個配置文件都帶有一個數字簽名塊,用于驗證C&C主機名數據的完整性。根據混淆部分中說明的簽名驗證方法,來對簽名進行驗證。以下是C&C配置的示例,簽名塊為紅色:
其中,有多個Web注入文件。一個包含所有目標URL和主機名數據,另一個包含正則表達式模式以及需要注入的代碼。這些文件都事先經過RC4加密和壓縮。
這些文件并非由主BokBot二進制文件解析,而是由攔截代理模塊對其進行解析。其過程是,驗證Zeus File Magic,分配緩沖區,然后解壓縮文件。
十一、與子進程的通信
BokBot使用內存映射文件和事件,與包含注入模塊的所有子進程進行通信。通過使用CreateEvent、OpenEvent和OpenFileMapping利用命名事件的過程,BokBot主模塊能夠為這些子進程提供附加信息。
11.1 共享模塊日志
這些模塊會寫入到同一個共享內存映射文件中,并使用父進程和子進程之間的共享名稱創建內存映射文件??梢陨纱嗣Q的每個進程,都可以使用它來打開內存映射文件,并將數據寫入共享模塊日志。更多細節我們會在下一節中介紹,所編寫的具體數據會在下面單獨的模塊描述中進行分析。主模塊負責清除日志,并將數據發送到C&C服務器。
11.2 特定模塊的通信
BokBot的主模塊通常需要向包含注入模塊代碼的子進程發出命令。這些命令可以觸發模塊中特定命令的更新,或者指示模塊執行特定功能(例如:從Outlook收集數據)。下圖該輸了這一過程,我們也將在后續章節中進一步說明。
11.2.1 事件名稱生成
為了使BokBot主模塊和子進程、事件之間成功通信,需要生成唯一的名稱,并且必須在所有進程中保持一致。其具體方法如下:
父進程和子進程將使用這些事件來交換數據。
11.2.2 BokBot主模塊
此過程能夠與注入模塊的所有子項進行通信。這些通信都圍繞C&C發出的命令。一旦有需要通知可執行模塊子進程的命令啟動,就會打開一個命名的Q事件,以確保子進程已經準備好接收數據。如果Q事件不存在,那么就表示尚未啟動子進程。BokBot將目標模塊注入紫禁城中,并循環檢查,以查看是否可以打開該事件。
成功打開Q事件后,BokBot將創建一個新的命名R事件,創建一個內存映射文件(名稱為M event),將數據寫入文件,并發出打開Q事件的信號,等待子進程的響應。子進程清除R事件后,內存映射文件將被取消映射,所有句柄都將關閉。
11.2.3 BokBot可執行模塊
初始化之后,子進程將創建一個命名的Q事件,并等待父進程發出信號。在發出信號后,將打開命名的R事件,并處理內存映射文件中的數據。
BokBot的主模塊會將一些上下文信息寫入注入的模塊,并告訴它執行特定的操作。這些操作會根據接收數據的模塊而有所更改。以下命令在模塊之間是一致的,但執行的操作可能會有所不同:
· 0xFF00 – 使用0x1122代碼處理退出
· 0xFF01 – 檢查Web注入或無操作
· 0xFF02 – 更新C&C主機名
除了命令之外,還會基于命令,告知注入模塊要完成的指令,以處理與命令相關聯的相關數據。
在父進程分配的任務完成后,將取消映射內存映射文件,發出R事件信號,并關閉所有其他打開的事件。
十二、混淆與防篡改
BokBot使用幾種方法進行混淆以阻礙分析過程,分別是:字符串混淆、從服務器發出加密的DAT文件、簽名驗證和多態性。
12.1 字符串混淆
為了使分析更加困難,這里使用了移位密鑰算法對重要字符串進行XOR編碼。所有編碼的字符串都具有以下結構:
· 0x0 – DWORD – 初始XOR密鑰
· 0x4 – WORD – 字符串大小
· 0x8 – char[] – 編碼后字符串
解碼字符串的算法如下(Python):
#
# Encoded string structure
#
String_struct = “”
xor_key = string_struct[:4]
string_length = string_struct[4:6]
ciphertext = string_strct[6:]
plaintext = “”
For idx in range(string_length)
xor_key = (((xor_key >> 0x3) | (xor_key << 0x1D)) + idx) & 0xFFFFFFFF
enc_byte = ciphertext[idx]
if (enc_byte ^ (xor_key & 0xFF) != 0:
plaintext += chr(enc_byte & (xor_key & 0xFF))
12.2 簽名驗證
簽名驗證會在以下兩種情況下發生:C&C URL發生更新、BokBot二進制文件發生更新。在這兩種情況下的驗證過程完全一致,驗證函數主要接收兩部分內容:要驗證的128字節簽名,和要驗證的數據。
首先,BokBot創建需要驗證的數據的MD5哈希值。接下來,嵌入在執行二進制文件中的RSA公鑰將通過CryptImportKey導入。生成哈希并導入密鑰后,CryptVerifySignature將用于驗證簽名。這可能是為了防止某些第三方接管,或者以其他方式破壞僵尸網絡。
12.3 多態性
每次安裝BokBot時,在將其寫入安裝目錄之前,都會使用垃圾數據修改二進制文件的.text部分,并更新其虛擬大小。同時,生成新的校驗和(Checksum),并替換當前的校驗和。
十三、總結
BokBot是一款功能強大的銀行木馬,可以為攻擊者提供強大的功能。BokBot最獨特之處之一是它與子模塊通信的方法。我們后續還將對該木馬進行持續分析,并將及時發布最新成果。
十四、BokBot相關哈希值
本文所涉及的全部樣本哈希值如下:
十五、MITRE ATT&CK
1024你懂的国产日韩欧美_亚洲欧美色一区二区三区_久久五月丁香合缴情网_99爱之精品网站
責任編輯:韓希宇
免責聲明:
中國電子銀行網發布的專欄、投稿以及征文相關文章,其文字、圖片、視頻均來源于作者投稿或轉載自相關作品方;如涉及未經許可使用作品的問題,請您優先聯系我們(聯系郵箱:cebnet@cfca.com.cn,電話:400-880-9888),我們會第一時間核實,謝謝配合。