作者:360威脅情報中心
一、綜述
2017年9月18日,Piriform 官方發布安全公告,公告稱該公司開發的 CCleaner version 5.33.6162 和 CCleaner Cloud version 1.07.3191 中的 32 位應用程序被植入了惡意代碼。被植入后門代碼的軟件版本被公開下載了一個月左右,導致百萬級別的用戶受到影響,泄露機器相關的敏感信息甚至極少數被執行了更多的惡意代碼。
CCleaner 是獨立的軟件工作室 Piriform 開發的系統優化和隱私保護工具,目前已經被防病毒廠商 Avast 收購,主要用來清除 Windows 系統不再使用的垃圾文件,以騰出更多硬盤空間,它的另一大功能是清除使用者的上網記錄。自從2004年2月發布以來,CCleaner 的用戶數目迅速增長而且很快成為使用量第一的系統垃圾清理及隱私保護軟件。而正是這樣一款隱私保護軟件卻被爆出在官方發布的版本中被植入惡意代碼,且該惡意代碼具備執行任意代碼的功能。
這是繼 Xshell 被植入后門代碼事件后,又一起嚴重的軟件供應鏈攻擊活動。360威脅情報中心通過對相關的技術細節的進一步分析,推測這是一個少見的基于編譯環境污染的軟件供應鏈攻擊,值得分享出來給安全社區討論。
二、后門技術細節分析
惡意代碼功能
被植入了惡意代碼的 CCleaner 版本主要具備如下惡意功能:
- 攻擊者在CRT初始化函數
__scrt_get_dyn_tls_init_callback()中插入了一個函數調用,并將此函數調用指向執行另一段惡意代碼。 - 收集主機信息(主機名、已安裝軟件列表、進程列表和網卡信息等)加密編碼后通過HTTPS協議的POST請求嘗試發送到遠程IP:216.126.225.148:443,且偽造HTTP頭的HOST字段為:
speccy.piriform.com,并下載執行第二階段的惡意代碼。 - 若IP失效,則根據月份生成DGA域名,并再次嘗試發送同樣的信息,如果成功則下載執行第二階段的惡意代碼。
植入方式推測
根據360威脅情報中心的分析,此次事件極有可能是攻擊者入侵開發人員機器后污染開發環境中的 CRT 靜態庫函數造成的,導致的后果為在該開發環境中開發的程序都有可能被自動植入惡意代碼,相應的證據和推論如下:
1、被植入的代碼位于用戶代碼 main 函數之前

main 函數之前的綠色代碼塊為編譯器引入的 CRT 代碼,這部分代碼非用戶編寫的代碼。
2、植入的惡意代碼調用過程

可以看到 CRT 代碼 sub_4010CD 內部被插入了一個惡意 call 調用。
3、被植入惡意代碼的 CRT 代碼源碼調用過程
通過分析,我們發現使用VS2015編譯的Release版本程序的CRT反匯編代碼與本次分析的代碼一致,調用過程為:
_mainCRTStartup --> __scrt_common_main_seh --> __scrt_get_dyn_tls_dtor_callback --> Malicious call
4、CCleaner中被修改的 __scrt_get_dyn_tls_init_callback() 和源碼對比

基于以上的證據,可以確定的是攻擊者是向 __scrt_get_dyn_tls_init_callback() 中植入惡意源代碼并重新編譯成 OBJ 文件再替換了開發環境中的靜態鏈接庫中對應的 OBJ 文件,促使每次編譯 EXE 的過程中,都會被編譯器通過被污染的惡意的 LIB/OBJ 文件自動鏈接進惡意代碼,最終感染編譯生成的可執行文件。
__scrt_get_dyn_tls_init_callback() 函數位于源代碼文件dyn_tls_init.c中。
三、攻擊技術重現驗證
編譯環境的攻擊面
通過分析發現,如果要向程序CRT代碼中植入惡意代碼,最好的方式就是攻擊編譯過程中引入的CRT靜態鏈接庫文件,方法有如下三種:
- 修改 CRT 庫文件源碼,重新編譯并替換編譯環境中的 CRT 靜態庫文件(LIB)
- 修改 CRT 庫文件中某個 OBJ 文件對應的C源碼,重新編譯并替換 LIB 中對應的 OBJ 文件。
- 修改 CRT 庫文件中某個 OBJ 文件的二進制代碼,并替換 LIB 中對應的 OBJ 文件。
CRT運行時庫
C運行時庫函數的主要功能為進行程序初始化,對全局變量進行賦初值,加載用戶程序的入口函數等。
定位CRT源代碼
我們以 VS2008 為例,編寫一個功能簡單的 main 函數如下:
#include "stdafx.h"
int main(int argc, _TCHAR* argv[])
{
printf("%d\n", 1);
return 0;
}
在 main 函數結尾處設置斷點,使用 /MD 編譯選項編譯調試運行

切換到反匯編代碼并執行到 main 函數返回:

返回后查閱源碼可以看到對應的 CRT 源代碼為:crtexe.c

源代碼路徑:
D:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\crtexe.c
定位 CRT 靜態鏈接庫
參考 MSDN 我們知道,在 VS2008 中,使用 /MD 編譯選項編譯 Release 版本的程序引用的 CRT 靜態庫為 msvcrt.lib,文件路徑為:
D:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\msvcrt.lib
四、LIB/OBJ文件介紹
以 VS2008 中的 msvcrt.lib 為例
LIB
這里介紹靜態庫 LIB 文件,是指編譯器鏈接生成后供第三方程序靜態鏈接調用的庫文件,其實是單個或多個 OBJ 通過 AR 壓縮打包后的文件,內部包含 OBJ 文件以及打包路徑信息,比如 msvcrt.lib 文件解壓后得到的部分OBJ文件路徑如下:

可以看到,msvcrt.lib 解壓后確實也有 CRT 對應的 OBJ 文件:crtexe.obj等。
OBJ
源代碼編譯后的 COFF 格式的二進制文件,包含匯編代碼信息、符號信息等等,編譯器最終會將需要使用的 OBJ 鏈接生成 PE 文件,crtexe.obj 文件格式如下:

五、攻擊CRT運行時庫
了解了 CRT 運行時庫的編譯鏈接原理,我們可以知道,使用/MD編譯選項編譯的 main 函數前的C運行時庫函數在靜態鏈接過程中是使用的 msvcrt.ib 中的 crcexe.obj 等進行編譯鏈接的,并且源代碼中定義不同的 main 函數名稱,編譯器會鏈接 msvcrt.lib 中不同的 OBJ 文件,列舉部分如下表所示:

修改crcexe.obj
我們以 VS2008 中編譯 main() 函數為例,如果修改 msvcrt.lib 中的 crcexe.obj 的二進制代碼,比如修改源碼并重編譯crcexe.c 或者直接修改 crcexe.obj,再將編譯/修改后的 crcexe.obj 替換 msvcrt.lib 中對應的 OBJ,最后將VS2008 中的 msvcrt.lib 替換,那么使用/MD編譯選項編譯的所有帶有 main() 函數的 EXE 程序都會使用攻擊者的crcexe.obj 編譯鏈接,最終植入任意代碼。
為展示試驗效果,我們通過修改 crcexe.obj 中 main 函數調用前的兩個字節為 0xCC,試驗效果將展示編譯的所有 EXE 程序 main 調用前都會有兩條 int3 指令:

crcexe.obj 在 msvcrt.lib 中的路徑:
f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\INTEL\dll_obj\crcexe.obj
替換 msvcrt.lib 中的 crcexe.obj
替換 msvcrt.lib 中的 OBJ 文件需要兩步,這里直接給出方法:
-
移除 msvcrt.lib 中的 OBJ 文件,使用VS自帶的LIB.EXE移除crcexe.obj:
lib /REMOVE: f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\INTEL\dll_obj\crcexe.obj msvcrt.lib -
向msvcrt.lib中插入修改后的crcexe.obj文件,使用VS自帶的LIB.EXE插入污染后的crcexe.obj:
lib msvcrt.lib f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\INTEL\dll_obj\crcexe.obj
編譯過程自動植入惡意代碼
將替換了 crcexe.obj 的 msvcrt.lib 覆蓋 VS 編譯器中的 msvcrt.lib:
D:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\msvcrt.lib
重新編譯執行我們的測試程序,可以看到在 main 函數執行前的兩條插入的 int3 指令:

六、結論與思考
2017年9月初360威脅情報中心發布了《供應鏈來源攻擊分析報告》,總結了近幾年來的多起知名的供應鏈攻擊案例,發現大多數的供應鏈攻擊渠道為軟件捆綁。通過污染軟件的編譯環境的案例不多,最出名的就是2015年影響面巨大的Xcode開發工具惡意代碼植入事件,從當前的分析來看,CCleaner也極有可能是定向性的編譯環境污染供應鏈攻擊。以下是一些相關的技術結論:
- 針對 LIB 文件攻擊方式可以通過重編譯源碼或者修改 OBJ 二進制代碼這兩種方式實現。
- 修改 OBJ 二進制代碼實現對LIB文件的代碼注入不同于修改源碼,此方法理論上可用于注入任何靜態鏈接庫 LIB。
- 只需按照 OBJ 文件格式規范即可注入任意代碼(shellcode),比如在 OBJ 中新增/擴大節,填充 shellcode 并跳轉執行。
- 此攻擊方法可以在用戶代碼執行前(CRT)、執行中(調用庫函數)、甚至執行結束后執行植入的惡意代碼,并且由于惡意代碼并不存在于編寫的源代碼中,所以很難被開發人員發現。
- 攻擊者完全可以植入某個深層次調用的開發環境下的靜態庫文件,以達到感染大部分開發程序并持久化隱藏的目的。
- 使用源代碼安全審查的方式無法發現這類攻擊
由于這類定向的開發環境污染攻擊的隱蔽性及影響目標的廣泛性,攻擊者有可能影響 CCleaner 以外的其他軟件,我們有可能看到攻擊者造成的其他供應鏈污染事件。
七、參考鏈接
https://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.90).aspx
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/404/
暫無評論