CCleanerGhost软件供应链安全事件
0x00 前言
2017年可以算是软件供应链攻击高发的一年,上个“XshellGhost”案例的发生时间是2017年七月份,随后2个月在2017年九月份又爆出了另外一起在国外影响深远的类似事件“CClenerGhost”。该事件也是一起针对IT基础设施平台(软件)的经典供应链攻击案例,攻击者利用植入其中的后门代码作跳板来实施渗透到其他大型IT公司的目标,其攻击水平和渗透能力也是比较突出,甚至在某些方面可能与“XshellGhost”案例存在一定的关联性和相似性。
0x01 事件背景
本次事件的重要时间节点如下所示。
详细的时间节点如下:
2017年3月11日,攻击者通过TeamViewer访问了CCleaner开发人员的工作站;
2017年3月12日,攻击者横向移动到第二台机器并投放旧版第二阶段后门;
2017年3月14日,攻击者在第一台机器也投放了旧版第二阶段后门;
2017年4月12日,攻击者在Piriform网络中的4台机器和1台构建服务器投放了定制版本的ShadowPad后门;
2017年4月至7月,攻击者安装键盘记录监控并准备CCleaner后门版本;
2017年7月04日,攻击者创建第一阶段后门CnC通信时使用的自签名证书;
2017年7月18日,Avast收购了CCleaner的制造商Piriform;
2017年8月02日,CCleaner后门版本第一次被构建;
2017年8月11日,CCleaner Cloud后门版本被构建;
2017年8月14日,Piriform旗下另一款产品Defraggler的后门版本被构建;
2017年8月15日,CCleaner后门版本分发给数百万用户;
2017年9月11日,Morphisec公司通过客户分享的日志调查CCleaner遭拦截事件;
2017年9月12日,Avast收到Morphisec公司的安全通知报告;
2017年9月13日,Cisco公司的防护系统拦截了CCleaner程序;
2017年9月14日,Avast收到Cisco公司的安全通知报告;
2017年9月15日,Avast与FBI执法部门合作关闭CnC服务器;同时Cisco公司抢注了相关DGA域名;
2017年9月18日,Piriform官方发布安全公告,称旗下的产品CCleaner(5.33.6162)和CCleaner Cloud(1.07.3191)被篡改植入恶意代码;
2017年9月19日,卡巴斯基研究员发推特指出CCleaner后门与APT组织Axiom的关联;
2017年9月20日,Cisco公司发布报告披露关于CCleaner后门的CnC服务器上相关文件的分析;
2018年4月18日,Avast研究员在RSA大会分享的CCleaner后门案例披露了2例ShadowPad后门。
0x02 植入位置
CCleaner安装后有32位版本和64位版本,其中仅32位版本的“CCleaner.exe”被植入了后门。
“CCleaner.exe”植入是通过污染VS2015的CRT静态库“msvcrt.lib”中的“dyn_tls_init.obj”目标文件,在函数“scrt_get_dyn_tls_init_callback”中插入一个恶意函数调用“malicious_40102C”。下图中左边是“CCleaner.exe”被污染的代码位置,右图是“msvcrt.lib”静态库中“exe_winmain.obj”的代码,二者代码相一致,其调用的“scrt_get_dyn_tls_init_callback”函数则位于另一个“dyn_tls_init.obj”中,也就是该目标文件的“__scrt_get_dyn_tls_init_callback”函数代码被恶意修改。
函数“scrt_get_dyn_tls_init_callback”的实现源码可以在VS的安装目录下“/VC/crt/src/dyn_tls_init.c”中找到,它的调用过程为:“_WinMainCRTStartup” => “scrt_common_main_seh ” => “__scrt_get_dyn_tls_init_callback” => “WinMain”,即在主函数之前运行。
在相应的位置上插入恶意代码并编译成obj目标文件后可以使用“LIB.exe”工具的“REMOVE”参数先移除静态库中指定obj,然后再使用该工具重新插入,最后将植入后门的静态库lib文件进行替换来污染构建服务器的开发环境。
另外一款产品“Defraggler.exe”及同项目中“DefragglerShell.dll”等模块均在同一个结构位置植入了相同的恶意函数,这也侧面佐证了污染的方式是替换CRT静态库。植入过程则是通过污染VS2010的CRT静态库“libcmt.lib”中的“onexit.obj”目标文件,在函数“__onexitinit”返回之前插入一个恶意函数调用“malicious_58C50A”。
函数“onexitinit”的实现源码可以在VS的安装目录下“/VC/crt/src/onexit.c”中找到,它的调用过程为:“tmainCRTStartup” => “cinit” => “initterm_e” => “__onexitinit” => “wWinMain”,也是在主函数之前运行。
0x03 样本分析
CCleaner和Defraggler被植入的恶意函数完全一致,故本节仅以“CCleaner.exe”为例进行分析。
(一)、第一阶段后门
恶意函数的主要功能是解密执行shellcode,全局变量“shellcode_encode_82E0A8”是一段大小为0x2978*4字节的加密代码,解密后被拷贝到从可执行堆分配的内存运行,执行完毕后还进行了擦除清理。
解密函数如下所示,使用初始种子数“0x2547383”与“0x47A6547”的循环累积数简单异或加密数据进行解密。
解密后的shellcode(PIC位置无关代码)实质上是一个PELoader加载器,其功能就是内存加载本阶段的后门模块“CCBkdr.dll”(思科报告命名)。
“CCBkdr.dll”实际上是一个被擦除了PE头部数据的dll模块,但是此定制的加载器可以读取其导入表进行API准备工作。
加载完成后调用其入口点,可以看到创建了一个工作线程来负责执行后门代码。
后门代码首先通过设置发送icmp数据包的超时为601秒来实现延时10分钟运行,这可能是为了逃避自动化分析系统的安全检测。接着判断当前时间和用户权限是否满足执行条件后开始收集当前计算机的系统信息如安装ID、系统版本/位数、主机名、DNS域名称、网卡信息、安装软件列表和进程列表,加密编码后就准备进行上线通信。
通信的C2地址为硬编码的一个IP地址“216.126.225.148”,如果连接失败则使用DGA生成每月更换的动态C2域名,解析其返回的DNS记录进一步生成通信的IP地址进行连接。若成功连接并接收到数据则解密后运行其中的shellcode(第二阶段后门代码),随后设置一个7天的潜伏时间。
DGA生成算法是基于当前时间的月份和年份作随机数种子,生成2个每月固定的随机数值然后以“ab%x%x.com”进行格式化。
随后获取此DGA域名的DNS记录,从h_addr_list地址表中取出2个数值合成一个IP地址作为备用C2地址。
通信过程就是使用http(s)协议连接C2 IP地址的443端口,并伪造协议头的主机名为Piriform企业的域名“speccy.piriform.com”,然后以POST方式发送上线数据包。
发送的上线数据包类似如下格式,此数据经过一种自定义的base64算法编码而成,C2服务器接收后若通过筛选则将返回下一阶段后门代码。
(二)、第二阶段后门
本阶段后门的样本来自思科安全团队公布的报告,该报告表示在调查过程中获得了第一阶段后门C2服务器(“216.126.225.148”)上的存档,基于这份存档上的数据格式和配置与第一阶段活动比较吻合,所以认为这份存档可能具备真实性。
该存档上筛选目标用户后通过一段“peloader_x86”代码和“GeeSetup_x86.dll”组合加密后下发第二阶段后门,服务器上相关的x64版本代码未使用。
“peloader_x86”是一段PE程序加载器的shellcode代码,用于实现内存加载尾部的PE程序“GeeSetup_x86.dll”。
“GeeSetup_x86.dll”是本阶段后门的安装器,首先判断系统版本用于针对性的选择持久化驻留的方式。在Win7或Win10系统中,会释放文件名为“TSMSISrv.dll”的文件到系统目录,并通过配置和启动“SessionEnV”服务(远程桌面服务)的方式来运行。而在WinXp系统则改换文件名投放到系统目录下的“spoolprtprocsx64localspl.dll”路径,配置和启动的服务则换成“Spooler”(打印机服务)。
释放的文件根据系统位数分x86和x64版本,2种版本功能相同。如下是x64版本,该文件的版本信息伪装成赛门铁克的终端组件“EFACli64.dll”(x86版本则伪装成Corel公司的产品组件“VirtCDRDrv.dll”),并且文件的时间属性也被设置成与系统“msvcrt.dll”运行库一致来进一步伪装自身。
通过这种方式来实现后门模块的驻留,该模块会在每次系统启动时自动被相应的服务加载,比如“TSMSISrv.dll”将被负责远程桌面服务的进程“svchost.exe”加载运行。
另外,在“GeeSetup_x86.dll”安装期间,会将本阶段的核心模块加密存储到注册表“SOFTWAREMicrosoftWindows NTCurrentVersionWbemPerf”,其中“001”项表示代码模块的长度,“002”项为加密的代码模块,“003”项为解密key的长度,“004”项则是解密key。
驻留系统服务的dll模块即负责加载运行注册表中的核心模块,并且加载过程的代码也特地在伪装的程序模块中做隐蔽处理。以x64版本的“EFACli64.dll”为例,加载代码的shellcode函数地址在dll入口点的“_security_init_cookie”函数进行设置,随后调用偏移量为“13CC0”的函数指针来运行。
此段shellcode代码的代码负责加载另外一小段专门加载注册表中核心模块的“load_shellcode”。
“load_shellcode”读取注册表“SOFTWAREMicrosoftWindows NTCurrentVersionWbemPerf”的数据并通过解密key简单异或解密核心模块的开头代码,之后还通过一小段ROP链去执行解密后的开头代码。
核心模块的代码由一个定制的PE加载器代码和一个擦除了PE头部数据的dll模块(类似第一阶段后门)共同构成,这里简单介绍x86版本dll模块的功能,该模块的主要功能就是下载执行第三阶段后门。首先随机从3个内置的加密地址选择一个以获取下一步骤IP地址,其中前2个URL类型的地址访问后根据其返回内容计算出IP地址,最后1个域名地址“get.adoble.net”(仿adobe公司)则通过解析其DNS记录计算出IP地址(类似第一阶段后门的方式)。
前2个URL中第二个wordpress博客地址目前已无法找到有效的控制数据,但是第一个github的地址还能看到疑似有效的控制数据。如下是通过搜索用户名为“joinlur”来获取其个人备注信息中的“ptoken”字段,该字段是一个十六进制数据,将其与“0x31415926”进行异或运算后即下一步骤IP地址(0x5A093B0D即“13.59.9.90”,目前无法确认此IP的真实性)。
获取到IP地址后主要分2种路径来获取第三阶段后门。一种是首次上线时连接“TCP://IP:443”,然后搜集用户信息发送到服务器后接收加密PE程序即第三阶段后门,解密后进行内存加载。
另外一种方式则是先连接“UDP://IP:53”发送查询“ds.download.windowsupdate.com”的DNS请求,然后解析返回数据获得第三阶段后门的下载IP地址,最后再通过http(s)协议下载解密运行。
(三)、第三阶段后门
根据avast研究员在RSA2018大会上分享的PPT可知,本阶段后门并没有拿到实际传播的样本,可能因为经过第一阶段的信息筛选后下发第二阶段后门的用户数量较少(已知只发现40台机器)。之所以认为第三阶段后门是“ShadowPad”后门则是因为在被攻击的Piriform网络中找到了第一阶段后门和第二阶段后门的旧版本,根据旧版本第二阶段后门下载的第三阶段payload判断是“ShadowPad”后门(实际也没有百分百确认直接的下载关系,仅通过已掌握的线索推测可能性比较大)。如下是avast官方提供的TeamViewer日志,记录了旧版第二阶段后门的安装运行过程。
在Piriform网络中发现的第三阶段后门据说是以.net运行库的文件存放在“%ProgramFiles%Common FilesMicrosoft.NETFrameworkv2.0.50727\mscoree.dll”(构建时间为“2017-04-04 23:55:48”),功能框架大致如下,与XShellGhost的最终后门相类似的插件模式(PlugX/ShadowPad后门),并且其中使用的DGA域名生成算法也类似。
对此ShadowPad后门存放在文件系统上的加密键盘记录日志进行解密(密钥是硬盘驱动器的卷ID)后,avast研究员发现了攻击者对CCleaner开发环境的监控信息。
这里由于avast官方没有公布此阶段样本的哈希值信息,无法进一步获取样本分析,关于该后门的技术分析至此先告一段落。
0x04 溯源分析
第一阶段后门生成的DGA域名(从2017年2月到12月)如下,思科报告中提到分析时DGA域尚未注册,可能因为是备用的地址所以还没启用,于是思科团队就抢注了相关域名来防范恶意使用(所谓的“sinkhole”处理)。
根据思科某产品的监测,DGA域名的DNS请求从8月份开始逐渐活跃,这个和CCleaner后门版本的发布时间相吻合。
最关键的攻击方资产还是内置在CCleaner后门中的控制服务器IP地址(“216.126.225.148”),第二阶段后门即来源于该服务器上的文件存档。该服务器以典型的“PHP+MySQL”架构提供web接口用于收发数据,在被执法部门关闭时保存有4天的数据(大概80多万条数据记录)。另外一个关联的服务器IP“216.126.225.163”(关联方式未知)猜测可能是用于数据备份。
比较有意思的是在控制服务器上发现了一张攻击者关注的目标域名列表,通过这张表筛选出处于下列域网络的目标用户进一步渗透(下发第二阶段后门)。这个信息表明,攻击者不仅是关注特定目标的APT组织,并且关注的目标都是闻名世界的技术公司如思科、索尼、三星、英特尔、微软和vmware等。
当然针对搜集上来的受害用户数据,也可以在随时筛选其他行业的目标进行渗透,如下是思科在报告中展示的2个可能的维度(银行和政府)。
另外在服务器上的初始化脚本“init.php”中配置了时区为“PRC”,思科报告提到这个信息不足以用于归因,因为没有其他明确的证据无法分辨是粗心留下的痕迹还是故意的栽赃甩锅。
稍微比较靠谱的归因是由卡巴斯基实验室研究员首次在推特上公布的关于代码重叠的发现,因此认为CCleaner后门与APT组织“Axiom”可能相关联。
重叠的代码主要是第一阶段后门在最后通信过程中使用的自定义base64编码算法,如下左边代码是CCleaner后门的加密算法,右边代码是APT17(Axiom)相关后门的加密算法,2者确实完全一致。不过这个也不能作为归因的直接证据,因为APT攻击中可能会出现通过使用其他攻击组织的工具来伪装自身身份的情况。
再看下第二阶段后门的相关C2资产,由于时间过去比较久,这些地址基本都已过期失效,所以只能从以前的资料中简单整理。这里主要参考如下PPT页,可以看出第二阶段对应的IP地址都被打码了,其中域名“get.adoble.net”对应2个IP地址,通过计算后得到与URL云控返回数据一致的IP地址“216.126.xxx.xxx”,由前2位可推测该IP可能与第一阶段后门C2地址同网段。
不过,avast研究员虽然有心不打算公开第二阶段的控制IP地址,但是通过他在PPT里贴出的当时github和wordpress的2个URL中的控制数据(“ptoken=44d7cc80947b27fe9c0cbc3cf97c48d1&”和“ptoken=82a078a0947b27fe15a35f6014a948c5&”),参照第二阶段后门分析的解密算法可以还原出2个URL对应的控制IP均是“216.126.58.165”。
由此也可判断上文关于当前github上的控制数据得到的IP地址“13.59.9.90”可能的确不是真实的控制IP,因为从以下信息也能看出当前这个“joinlur”账户的创建时间是2017年9月20日,这个时间点已经是公开披露此事件的2天后,所以推测该数据也可能是第三方介入的测试数据。
0x05 总结
“CClenerGhost”事件本质上是攻击者入侵知名公司Piriform的工作网络后污染其开发编译环境中的静态库来植入后门,然后利用该产品“CCleaner”的大量分发进行传播渗透到目标用户机器中,最终通过在云端的信息筛选进一步实施定向攻击。这个案例由于影响面较广且涉及的目标企业比较庞大,并且因为事件发生在安全公司avast刚收购完Piriform公司不久,所以披露出来的调查信息相对比较全面,非常值得深入研究。最后呼应一下上篇总结提到的“所有的单位或个人都可能成为被渗透和攻击的对象”,这里借卡巴斯基某篇文章的一句话来印证:“就算你不是APT攻击者关注的目标, 也仍然有可能成为恶意软件传递链中的受害者。”所以,别让自己成为供应链攻击中的薄弱环节。
0x06 参考链接
1、MORPHISEC DISCOVERS CCLEANER BACKDOOR SAVING MILLIONS OF AVAST USERS,https://blog.morphisec.com/morphisec-discovers-ccleaner-backdoor
2、Update to the CCleaner 5.33.6162 Security Incident,https://blog.avast.com/update-to-the-ccleaner-5.33.6162-security-incident
3、CCleanup: A Vast Number of Machines at Risk,https://blog.talosintelligence.com/2017/09/avast-distributes-malware.html
4、CCleaner Attack Timeline—Here's How Hackers Infected 2.3 Million PCs,https://thehackernews.com/2018/04/ccleaner-malware-attack.html
5、Recent findings from CCleaner APT investigation reveal that attackers entered the Piriform network via TeamViewer,https://blog.avast.com/update-ccleaner-attackers-entered-via-teamviewer
6、Progress on CCleaner Investigation,https://blog.avast.com/progress-on-ccleaner-investigation
7、New investigations into the CCleaner incident point to a possible third stage that had keylogger capacities,https://blog.avast.com/new-investigations-in-ccleaner-incident-point-to-a-possible-third-stage-that-had-keylogger-capacities
8、CCleaner Malware Infects Big Tech Companies With Second Backdoor,https://thehackernews.com/2017/09/ccleaner-malware-hacking.html#search
9、CCleaner Command and Control Causes Concern,https://blog.talosintelligence.com/2017/09/ccleaner-c2-concern.html
10、CCleaner APT Attack: A Technical Look Inside,https://published-prd.lanyonevents.com/published/rsaus18/sessionsFiles/8739/HTA-T10_CCleaner%20APT%20Attack-A%20Technical%20Look%20Inside.pdf
11、对CCleaner的C2服务器的技术分析,https://www.anquanke.com/post/id/86908
12、分析供应链攻击中的C/C++运行时库代码篡改技术,https://www.anquanke.com/post/id/177106
13、“夭折”的供应链攻击 - Defraggler被植入后门代码分析,https://www.anquanke.com/post/id/87332
14、别成为供应链攻击中的薄弱环节,https://www.kaspersky.com.cn/blog/ccleaner-supply-chain/9471/
15、CCleaner后门分析,https://v2.s.tencent.com/research/report/275.html
16、供应链幽灵再现:CCleaner软件攻击分析报告,https://www.anquanke.com/post/id/86882
17、深入分析CCleaner后门代码-编译环境污染供应链攻击案例,https://www.anquanke.com/post/id/86923
18、CCleaner恶意代码分析预警,https://www.anquanke.com/post/id/86872
19、供应链攻击:CCleaner 5.33官方下载被植入恶意代码,https://v2.s.tencent.com/research/report/275.html
目前没有反馈
表单载入中...