作者:360威脅情報(bào)中心
2017年9月18日,Piriform 官方發(fā)布安全公告,公告稱該公司開發(fā)的 CCleaner version 5.33.6162 和 CCleaner Cloud version 1.07.3191 中的 32 位應(yīng)用程序被植入了惡意代碼。被植入后門代碼的軟件版本被公開下載了一個(gè)月左右,導(dǎo)致百萬級別的用戶受到影響,泄露機(jī)器相關(guān)的敏感信息甚至極少數(shù)被執(zhí)行了更多的惡意代碼。
CCleaner 是獨(dú)立的軟件工作室 Piriform 開發(fā)的系統(tǒng)優(yōu)化和隱私保護(hù)工具,目前已經(jīng)被防病毒廠商 Avast 收購,主要用來清除 Windows 系統(tǒng)不再使用的垃圾文件,以騰出更多硬盤空間,它的另一大功能是清除使用者的上網(wǎng)記錄。自從2004年2月發(fā)布以來,CCleaner 的用戶數(shù)目迅速增長而且很快成為使用量第一的系統(tǒng)垃圾清理及隱私保護(hù)軟件。而正是這樣一款隱私保護(hù)軟件卻被爆出在官方發(fā)布的版本中被植入惡意代碼,且該惡意代碼具備執(zhí)行任意代碼的功能。
這是繼 Xshell 被植入后門代碼事件后,又一起嚴(yán)重的軟件供應(yīng)鏈攻擊活動(dòng)。360威脅情報(bào)中心通過對相關(guān)的技術(shù)細(xì)節(jié)的進(jìn)一步分析,推測這是一個(gè)少見的基于編譯環(huán)境污染的軟件供應(yīng)鏈攻擊,值得分享出來給安全社區(qū)討論。
被植入了惡意代碼的 CCleaner 版本主要具備如下惡意功能:
__scrt_get_dyn_tls_init_callback()
中插入了一個(gè)函數(shù)調(diào)用,并將此函數(shù)調(diào)用指向執(zhí)行另一段惡意代碼。speccy.piriform.com
,并下載執(zhí)行第二階段的惡意代碼。根據(jù)360威脅情報(bào)中心的分析,此次事件極有可能是攻擊者入侵開發(fā)人員機(jī)器后污染開發(fā)環(huán)境中的 CRT 靜態(tài)庫函數(shù)造成的,導(dǎo)致的后果為在該開發(fā)環(huán)境中開發(fā)的程序都有可能被自動(dòng)植入惡意代碼,相應(yīng)的證據(jù)和推論如下:
1、被植入的代碼位于用戶代碼 main 函數(shù)之前
main 函數(shù)之前的綠色代碼塊為編譯器引入的 CRT 代碼,這部分代碼非用戶編寫的代碼。
2、植入的惡意代碼調(diào)用過程
可以看到 CRT 代碼 sub_4010CD
內(nèi)部被插入了一個(gè)惡意 call 調(diào)用。
3、被植入惡意代碼的 CRT 代碼源碼調(diào)用過程
通過分析,我們發(fā)現(xiàn)使用VS2015編譯的Release版本程序的CRT反匯編代碼與本次分析的代碼一致,調(diào)用過程為:
_mainCRTStartup --> __scrt_common_main_seh --> __scrt_get_dyn_tls_dtor_callback --> Malicious call
4、CCleaner中被修改的 __scrt_get_dyn_tls_init_callback()
和源碼對比
基于以上的證據(jù),可以確定的是攻擊者是向 __scrt_get_dyn_tls_init_callback()
中植入惡意源代碼并重新編譯成 OBJ 文件再替換了開發(fā)環(huán)境中的靜態(tài)鏈接庫中對應(yīng)的 OBJ 文件,促使每次編譯 EXE 的過程中,都會(huì)被編譯器通過被污染的惡意的 LIB/OBJ 文件自動(dòng)鏈接進(jìn)惡意代碼,最終感染編譯生成的可執(zhí)行文件。
__scrt_get_dyn_tls_init_callback()
函數(shù)位于源代碼文件dyn_tls_init.c
中。
通過分析發(fā)現(xiàn),如果要向程序CRT代碼中植入惡意代碼,最好的方式就是攻擊編譯過程中引入的CRT靜態(tài)鏈接庫文件,方法有如下三種:
C運(yùn)行時(shí)庫函數(shù)的主要功能為進(jìn)行程序初始化,對全局變量進(jìn)行賦初值,加載用戶程序的入口函數(shù)等。
我們以 VS2008 為例,編寫一個(gè)功能簡單的 main 函數(shù)如下:
#include "stdafx.h"
int main(int argc, _TCHAR* argv[])
{
printf("%d\n", 1);
return 0;
}
在 main 函數(shù)結(jié)尾處設(shè)置斷點(diǎn),使用 /MD 編譯選項(xiàng)編譯調(diào)試運(yùn)行
切換到反匯編代碼并執(zhí)行到 main 函數(shù)返回:
返回后查閱源碼可以看到對應(yīng)的 CRT 源代碼為:crtexe.c
源代碼路徑:
D:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\crtexe.c
參考 MSDN 我們知道,在 VS2008 中,使用 /MD 編譯選項(xiàng)編譯 Release 版本的程序引用的 CRT 靜態(tài)庫為 msvcrt.lib,文件路徑為:
D:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\msvcrt.lib
以 VS2008 中的 msvcrt.lib 為例
這里介紹靜態(tài)庫 LIB 文件,是指編譯器鏈接生成后供第三方程序靜態(tài)鏈接調(diào)用的庫文件,其實(shí)是單個(gè)或多個(gè) OBJ 通過 AR 壓縮打包后的文件,內(nèi)部包含 OBJ 文件以及打包路徑信息,比如 msvcrt.lib
文件解壓后得到的部分OBJ文件路徑如下:
可以看到,msvcrt.lib
解壓后確實(shí)也有 CRT 對應(yīng)的 OBJ 文件:crtexe.obj
等。
源代碼編譯后的 COFF 格式的二進(jìn)制文件,包含匯編代碼信息、符號信息等等,編譯器最終會(huì)將需要使用的 OBJ 鏈接生成 PE 文件,crtexe.obj
文件格式如下:
了解了 CRT 運(yùn)行時(shí)庫的編譯鏈接原理,我們可以知道,使用/MD編譯選項(xiàng)編譯的 main 函數(shù)前的C運(yùn)行時(shí)庫函數(shù)在靜態(tài)鏈接過程中是使用的 msvcrt.ib
中的 crcexe.obj
等進(jìn)行編譯鏈接的,并且源代碼中定義不同的 main 函數(shù)名稱,編譯器會(huì)鏈接 msvcrt.lib
中不同的 OBJ 文件,列舉部分如下表所示:
我們以 VS2008 中編譯 main()
函數(shù)為例,如果修改 msvcrt.lib
中的 crcexe.obj
的二進(jìn)制代碼,比如修改源碼并重編譯crcexe.c
或者直接修改 crcexe.obj
,再將編譯/修改后的 crcexe.obj
替換 msvcrt.lib
中對應(yīng)的 OBJ,最后將VS2008 中的 msvcrt.lib
替換,那么使用/MD編譯選項(xiàng)編譯的所有帶有 main()
函數(shù)的 EXE 程序都會(huì)使用攻擊者的crcexe.obj
編譯鏈接,最終植入任意代碼。
為展示試驗(yàn)效果,我們通過修改 crcexe.obj
中 main 函數(shù)調(diào)用前的兩個(gè)字節(jié)為 0xCC,試驗(yàn)效果將展示編譯的所有 EXE 程序 main 調(diào)用前都會(huì)有兩條 int3 指令:
crcexe.obj
在 msvcrt.lib
中的路徑:
f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\INTEL\dll_obj\crcexe.obj
替換 msvcrt.lib
中的 OBJ 文件需要兩步,這里直接給出方法:
lib /REMOVE: f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\INTEL\dll_obj\crcexe.obj msvcrt.lib
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
重新編譯執(zhí)行我們的測試程序,可以看到在 main 函數(shù)執(zhí)行前的兩條插入的 int3 指令:
2017年9月初360威脅情報(bào)中心發(fā)布了《供應(yīng)鏈來源攻擊分析報(bào)告》,總結(jié)了近幾年來的多起知名的供應(yīng)鏈攻擊案例,發(fā)現(xiàn)大多數(shù)的供應(yīng)鏈攻擊渠道為軟件捆綁。通過污染軟件的編譯環(huán)境的案例不多,最出名的就是2015年影響面巨大的Xcode開發(fā)工具惡意代碼植入事件,從當(dāng)前的分析來看,CCleaner也極有可能是定向性的編譯環(huán)境污染供應(yīng)鏈攻擊。以下是一些相關(guān)的技術(shù)結(jié)論:
由于這類定向的開發(fā)環(huán)境污染攻擊的隱蔽性及影響目標(biāo)的廣泛性,攻擊者有可能影響 CCleaner 以外的其他軟件,我們有可能看到攻擊者造成的其他供應(yīng)鏈污染事件。
https://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.90).aspx