安全路透社
当前位置:安全路透社 > 网络转载 > 正文

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

综述

2017年9月18日,Piriform 官方发布安全公告,公告称该公司开发的CCleaner version 5.33.6162和CCleaner Cloudversion 1.07.3191中的32位应用程序被植入了恶意代码。被植入后门代码的软件版本被公开下载了一个月左右,导致百万级别的用户受到影响,泄露机器相关的敏感信息甚至极少数被执行了更多的恶意代码。

CCleaner是独立的软件工作室Piriform开发的系统优化和隐私保护工具,目前已经被防病毒厂商Avast收购,主要用来清除Windows系统不再使用的垃圾文件,以腾出更多硬盘空间,它的另一大功能是清除使用者的上网记录。自从2004年2月发布以来,CCleaner的用户数目迅速增长而且很快成为使用量第一的系统垃圾清理及隐私保护软件。而正是这样一款隐私保护软件却被爆出在官方发布的版本中被植入恶意代码,且该恶意代码具备执行任意代码的功能。

这是继Xshell被植入后门代码事件后,又一起严重的软件供应链攻击活动。360威胁情报中心通过对相关的技术细节的进一步分析,推测这是一个少见的基于编译环境污染的软件供应链攻击,值得分享出来给安全社区讨论。

后门技术细节分析

恶意代码功能

被植入了恶意代码的CCleaner版本主要具备如下恶意功能:

1、攻击者在CRT初始化函数 __scrt_get_dyn_tls_init_callback()中插入了一个函数调用,并将此函数调用指向执行另一段恶意代码。

2、收集主机信息(主机名、已安装软件列表、进程列表和网卡信息等)加密编码后通过HTTPS协议的POST请求尝试发送到远程IP:216.126.225.148:443,且伪造HTTP头的HOST字段为:speccy.piriform.com,并下载执行第二阶段的恶意代码。

3、若IP失效,则根据月份生成DGA域名,并再次尝试发送同样的信息,如果成功则下载执行第二阶段的恶意代码。

植入方式推测

根据360威胁情报中心的分析,此次事件极有可能是攻击者入侵开发人员机器后污染开发环境中的CRT静态库函数造成的,导致的后果为在该开发环境中开发的程序都有可能被自动植入恶意代码,相应的证据和推论如下:

1、 被植入的代码位于用户代码main函数之前

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

main函数之前的绿色代码块为编译器引入的CRT代码,这部分代码非用户编写的代码。

2、  植入的恶意代码调用过程

image.png

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

可以看到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() 和源码对比

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

基于以上的证据,可以确定的是攻击者是向 __scrt_get_dyn_tls_init_callback() 中植入恶意源代码并重新编译成OBJ文件再替换了开发环境中的静态链接库中对应的OBJ文件,促使每次编译EXE的过程中,都会被编译器通过被污染的恶意的LIB/OBJ文件自动链接进恶意代码,最终感染编译生成的可执行文件。

__scrt_get_dyn_tls_init_callback() 函数位于源代码文件dyn_tls_init.c中。

攻击技术重现验证

编译环境的攻击面

通过分析发现,如果要向程序CRT代码中植入恶意代码,最好的方式就是攻击编译过程中引入的CRT静态链接库文件,方法有如下三种:

1、 修改CRT库文件源码,重新编译并替换编译环境中的CRT静态库文件(LIB)

2、 修改CRT库文件中某个OBJ文件对应的C源码,重新编译并替换LIB中对应的OBJ文件。

3、 修改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编译选项编译调试运行

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

切换到反汇编代码并执行到main函数返回:

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

返回后查阅源码可以看到对应的CRT源代码为:crtexe.c

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

源代码路径:

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文件路径如下:

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

可以看到,msvcrt.lib解压后确实也有CRT对应的OBJ文件:crtexe.obj等

OBJ

源代码编译后的COFF格式的二进制文件,包含汇编代码信息、符号信息等等,编译器最终会将需要使用的OBJ链接生成PE文件,crtexe.obj文件格式如下:

深入分析CCleaner后门代码:编译环境污染类的供应链攻击案例

攻击CRT运行时库

了解了CRT运行时库的编译链接原理,我们可以知道,使用/MD编译选项编译的main函数前的C运行时库函数在静态链接过程中是使用的msvcrt.ib中的crcexe.obj等进行编译链接的,并且源代码中定义不同的main函数名称,编译器会链接msvcrt.lib中不同的OBJ文件,列举部分如下表所示:

main函数名称 对应的OBJ文件 说明
main() crcexe.obj thestartup routine for console apps
main() wcrcexe.obj thestartup routine for console apps with wide chars
WinMain crcexew.obj thestartup routine for Windows apps
wWinMain() wcrcexe.obj thestartup routine for Windows apps with wide chars
赞 (0)
分享到:更多 ()

评论 0

评论前必须登录!

登陆 注册