1.背景概述
HW2022期间,各类病毒木马层出不穷,红蓝对抗日益激烈。为提升病毒木马防护能力,蓝队根据往年防守经验研制出了各类木马,尤其是CobaltStrike木马的自动化检测方法,为攻击者的木马投递制造了不小的难度;而攻击者则致力于提升木马的反检测能力,通过选择多种编译语言,变换通信协议,修改原生木马和自写木马等方式,不断尝试绕过各类检测机制,红蓝双方斗得不亦乐乎,着实“战了个痛快”。
HW2022已落下帷幕,微步在线样本分析团队对HW期间出现的各类病毒木马进行了汇总,从逆向分析角度遴选出技术价值更高的样本进行了深入分析,并据此总结了HW2022中木马的变化趋势:
- 编译语言方面,攻击者开始倾向于使用多种语言,可谓“百花齐放”:除了往年已出现过的Go语言样本之外,Rust、Nim等语言的样本也陆续出现。
- 通信协议方面,攻击者为躲避流量检测,可谓“瞒天过海”:木马反连时使用的网络协议渐趋多样化,ICMP隧道和DNS隧道通信样本均有出现。
- 对抗分析技术方面,攻击者采用更丰富的技术手段进行分析对抗,避免在分析环境中运行,可谓“如履薄冰”,判断父进程,判断是否有办公软件和时间检测等方式花样迭出。
- 对于HW中最为经典的CobaltStrike木马,攻击者也做了大量的创新,可谓“移花接木”:通过Hook技术修改反连C2、自定义Base64算法,Shellcode装载IPV4地址等方式令人耳目一新。
- 最后,HW期间出现了部分 “特马”,这些“特马”一般不属于任何已知病毒家族,是资深的攻击者自主设计编写,技术含量很高。我们预计各式各样的“特马”未来也将会不断涌现,可谓“方兴未艾”。
2.分析详情
百花齐放:编译语言的选择(3个案例)
往年的HW,大多病毒木马样本以经典的C/C++语言编译,其他语言较少。而在今年,Go、Rust、Nim等语言编写的木马有逐渐增加的趋势,其中以Go语言样本的增加最为明显,占据了C/C++语言之外的主流。
案例1:Go语言样本
Sha256 | 81f67502d9cf92a9ff03b2f3837ae1cdda7db8e9624ad82106723b520c43fe5a |
SHA1 | cc7af791ac2a977d5d6a4609fc4438085d0becd5 |
MD5 | 63374c5d751d2648c578b46eb6573958 |
文件类型 | EXE |
文件大小 | 24.65MB |
文件名称 | 集团终端自检工具第一版.exe |
功能描述 | Sliver木马 |
技术特点 | 经分析该木马是一个加壳的Sliver。 |
相关样本攻击流程如下图所示,主要使用白加黑技术。
样本执行后,会在%LOCALAPPDATA%目录下名为appli,applic,chrome,firefox,tenc,tence,cent,wec,wech,techa,Nete,Netea,soc,ap,te,tem,tmp,al,ali,ne任意一个文件夹中释放eyunbrowser.exe, libmlt-6.dll,ictl.dt这四个文件。同时为了迷惑用户,弹窗提示缺少程序,无法正常执行。
eyunbrowser.exe为白文件,libmlt-6.dll为黑dll, 负责解密真正的加密载荷文件ictl.dt。释放完成后主程序会调用cmd命令行,将自身的文件删除,并启动eyunbrowser.exe执行。eyunbrowser.exe执行后,会静态加载libmlt-6.dll,执行DllMain入口函数,读取ictl.dt载荷文件,并且libmlt-6.dll所有导出函数均指向ds1导出函数,而ds1导出函数负责执行载荷,因此当白文件eyunbrowser.exe调用libmlt-6.dll任意导出函数都会触发载荷执行。
经分析可判断载荷为Sliver生成的标准shellcode形式的Beacon载荷。
Sliver 是一个开源的跨平台植入型C2框架,使用Go语言编写,由网络安全公司 BishopFox 于 2019 年底首次公开。凭借其开源和易用性的优势,我们预计将来会有越来越多的攻击者使用。当前微步的TDP产品已经支持Sliver家族的检测。
脱壳得到Beacon载荷的本体后,将其拖入ida,我们会发现样本入口点和之前其他Go样本有所不同。Windows平台下常规编译的Go程序,入口点是_rt0_amd64_windows。是单独一条jmp指令。如下图:
而Sliver木马的入口点代码却有明显的差异:
以上图为例,函数sub_401190是以Call为结尾。下图中call sub_461140才是木马真实的入口点。
Sliver编译使用的最低Go版本为Go1.18。对Go语言相关样本分析时,特别依赖于符号。但Go1.18的Pclntab(源代码中src/debug/gosym/pclntab.go定义)的结构有所改变,现阶段只有ida8.0版本才支持解析。
对于Go语言木马样本的分析,我们认为首先需要判断其是什么版本Go编写的:通过ida进行字符串检索,运气好可以找到对应的版本字符串。如果没有相关字符串,就只能通过Pclntab结构来进行判断和符号还原。Pclntab结构的Majic字段如果是0xFFFFFFF0,则可判断是Go1.18及之后的版本。下图是Go源代码中对Majic的定义:
Pclntab结构中的funcnametab记录了程序内各个函数的符号(这些符号原本是程序异常告警时使用的),可以基于此来对各个程序函数的符号进行还原。攻击者也可基于此对函数符号进行各种混淆破坏。
案例2:Rust语言样本
Sha256 | a543cc2a074d9df2d6840e71402b99acd2a5f9cc5d5b0f17c7bc6425157db5a8 |
SHA1 | 9a767aa80e4660852b6355ccf6448e1a48d67928 |
MD5 | 65c9684ac5b54c3d086846ed40d21ed5 |
文件类型 | EXE |
文件大小 | 522.00KB |
文件名称 | 银联快捷支付相关问题 新建DOCX文档.exe |
功能描述 | 后门木马 |
技术特点 | 样本疑似某红队的样本。该样本在今年上半年的一些小HW中就出现过。这款样本最大的特征是使用了https://github.com/GuillaumeGomez/sysinfo项目。该项目是一个Rust项目,主要功能是获取各个系统的信息。基本上支持Windows、Linux、macOS、Android等平台。 |
Rust编写的木马相比Go编写的来说,会更加精简。函数的调用约定也符合Windows下常见的几种调用约定。使用ida打开样本时,可见OEP是标准的C代码入口点– __scrt_common_main_seh。
ida会自动找识别出main函数。但这并不是真实的用户代码,是Rust编译生成的初始化代码。但要注意,ida在解析Rust的代码时,偶尔会出现bug,有部分指令未被识别。如下图,0x48就未被识别成为指令,这里需要人工手动设置一下。
将main函数正确识别后,可在此找到用户代码的入口点。用户代码的入口点在如图所示的地方。
案例3:Nim语言样本
Sha256 | 37b7ec96e0694c5e42c2b206723158102295a05c01b842e818c41078adfd8c9a |
SHA1 | cf4f16a9218320420bbd211fd339beb2d83cf9ac |
MD5 | 6d46b1375228dd879c0438e9e6691b86 |
文件类型 | EXE |
文件大小 | 421.35KB |
文件名称 | 360sdprotect.exe |
功能描述 | 后门木马 |
技术特点 | Nim编译生成的样本 |
这是一个Nim编译的样本。Nim是一种静态的编译语言。虽说是静态型编译语言,但是和Go、Rust相比,编译出的程序甚至更加精简。样本伪装成360安全软件,并且样本有对应的签名(哈希不匹配)。在样本中,我们发现了很多Nim相关字符串:
经分析后,发现世面上见到的大部分Nim样本,都是源于Github上的开源项目https://github.com/aeverj/NimShellCodeLoader。该项目是Nim编写Windows平台shellcode免杀加载器,该工具截图如下。
瞒天过海:通信协议的丰富(2个案例)
今年HW病毒木马在反连C2过程中使用的协议呈现出多样化的趋势,不再局限于经典的TCP、HTTP和HTTPS,少量样本开始使用ICMP隧道和DNS隧道进行通信。
案例4:利用ICMP隧道通信样本
Sha256 | d145e9a2a6e9e904aa2984ae9282d384631f757a978adf24a09dd2600011834a |
SHA1 | 44bacb493e84a14f9f0dc384b0f9648b50dade8e |
MD5 | 70804a1efac34e4f0e24fd0af5286692 |
文件类型 | EXE |
文件大小 | 4.67MB |
文件名称 | 投诉举报证据.dоcxㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ…ㅤㅤㅤㅤㅤㅤ.exe |
功能描述 | 后门木马 |
技术特点 | Go语言加载器,会将后门样本释放本地执行。样本可进行icmp通信。 |
这是一个使用ICMP协议进行通信的样本。样本外层使用Go语言编写的加载器,负责将诱饵Word文档和木马模块释放执行。
之后,木马将在C:\Users\Public目录下释放名为svchost.exe木马并启动执行。
样本利用ICMP协议同C2进行通信,ICMP协议中的data字段可写入任意自定义数据,样本会将上线数据填充1024个字节放在ICMP协议的data字段。并且返回的ICMP数据包的data字段也是固定的1024个字节。C2会对接收的ICMP流量进行判断,如果data数据不符合其格式,将不会发回响应包。在接收到到响应后,样本会基于C2返回的数据执行不同的功能。
案例5:利用DNS隧道通信样本
Sha256 | a108d2144109d920486fdbefa3001ed4f8c51207e43cb2b030e0147476bb3b41 |
SHA1 | 4949952d82daa36a524fdc219b747d5421d16f2b |
MD5 | 67d27a389170fe41e8a840c7bc4f2c00 |
文件类型 | EXE |
文件大小 | 617.00KB |
文件名称 | ConnectTest.exe |
功能描述 | 后门木马 |
技术特点 | CS木马,采用DNS隧道方式通信。 |
这个样本是一个CS木马,采用DNS隧道的方式进行通信。样本会生成一个四级域名,然后进行DNS请求。根据DNS返回的值决定后续的执行流程。像CS、Sliver、Viper等框架,都可进行DNS隧道通信的配置。
受害主机发起DNS请求,比如域名为68fa04f2.ns.360-oss.com。DNS服务器收到此请求首先尝试找到域扩展名“.com”,然后找到“ns.360-oss.com”,但是在其数据库中找不到“68fa04f2.ns.360-oss.com”。然后它将请求转发到ns.360-oss.com(这是黑客搭建的DNS服务器),并询问它是否知道这样的名称,作为回应ns.360-oss.com预计将返回相应的IP;然而,黑客则会在返回数据配置各种C&C指令。
微步云沙箱可以提取CS木马的配置,可以提取出C2地址、Beacon类型、端口等。
如履薄冰:对抗分析技术(3个案例)
如何躲避沙箱的检测和样本分析师的逆向分析是攻击者一直以来十分关注的课题。在今年HW中,各种对抗分析技术五花八门,思路奇特,令人耳目一新。
案例6:多维度进行沙箱对抗
Sha256 | accc714fa5692881619b91cf7f651df127614fa513b56afb660e4018bceacdc7 |
SHA1 | af5b52f567387894590025db0fa80d68e48e2237 |
MD5 | 2c2ff1abbc932fe5d471a1a3379a5041 |
文件类型 | EXE |
文件大小 | 5.46MB |
文件名称 | oleObject1.bin |
功能描述 | 白加黑后门木马 |
技术特点 | 白加黑后门木马,样本使用了一些反沙箱技术。 |
样本是通过WPS漏洞进行执行,执行一个自解压程序,将需要的组件释放到本地。
该组样本是通关白加黑执行。其中QQProject.exe是唯一一个白文件,该程序是VMP壳保护,并且有完整的合法签名。QQProject.exe执行后会加载UnityPlayer.dll。UnityPlayer.dll会读取QQProject.ini和QQProject.dat,将它们俩进行解密。
其中QQProject.dat解密后是一段Shellcode,QQProject.ini解密后是一段密钥。QQProject.dat通过QQProject.ini的密钥来解密QQProject.hlp。QQProject.hlp解密后同样是一段Shellcode。最终会在内存中释放一个后门木马来执行。
(1)判断父进程是否是rundll32
案例6中的UnityPlayer.dll,它会进行很多环境检测,防止运行在虚拟机等环境中。由于UnityPlayer.dll是一个dll文件,为了防止分析,它会判断父进程是否是rundll32。如果是rundll32就会退出,不是就会继续执行。
目前流行的沙箱,dll类样本一般都是通过rundll32来执行的。因此判断父进程是否为rundll32.exe是一种很具有针对性的反沙箱方法。
(2)判断是否有办公软件
UnityPlayer.dll会检擦注册表,从注册表中查找是否有钉钉、企业微信等办公软件,以检测是否是常用的主机,则不是虚拟的分析环境。如果没检测到这类办公软件,样本就会退出。
(3)时间检测
UnityPlayer.dll内会记录一个时间范围,如:2022-08-01到2022-08-10。样本在运行时会查看当前时间。如果当前时间在记录的时间范围内,就会执行,否则就会退出。
案例7:特殊Sleep反沙箱
Sha256 | 1bd79c88d48c0721935589d5f8414a777cfe58353a0cc9f614e30a348b6e253f |
SHA1 | c35f8294584ecb893dda12111aebe7d952cb2ce9 |
MD5 | 3835268b68e07c16073bbe4b29c00ba8 |
文件类型 | EXE |
文件大小 | 2.12MB |
文件名称 | 迅雷卸载程序.exe |
功能描述 | CS木马 |
技术特点 | 新建Sleep线程,通过WaitForSingleObject对Sleep线程进行等待。记录其等待时间,判断是否符号预期值。 |
样本创建一个Sleep线程,线程Sleep时间为183201毫秒。
随后样本会对Sleep线程进行等待。等待的时间是180201毫秒。两个时间会相差3000毫秒。
当WaitForSingleObject超时时,Sleep线程还有3000毫秒结束。就利用这3000毫秒的时间差,样本会循环使用WaitForSingleObject来等待Sleep线程,其dwMilliseconds设置为0,不进行等待。
样本在循环中会计算数值,如果该值大于默认设置的值,就会进行之后的联网操作。否则样本就会退出。沙箱常规操作会把样本Sleep的时间设置为0或较短的时间,这就导致最终计算的值会小于样本默认的值,样本关键代码就不会执行。
移花接木:CS木马的新手法(4个案例)
CS木马可算是HW时期的老演员了。微步云沙箱在今年HW前夕上线了CS木马专项检测功能,显著提升了CS木马检测的能力,不仅可以发现那些在内存中执行的CS木马,还可以对其进行配置提取。而在今年大量被微步云沙箱检测为CS木马的样本中我们发现了很多新奇的隐藏手法。
案例8:通过Hook隐藏真实C2
Sha256 | 25d95723686d8663814123085f68293ded4aefc6eb09188b137a20bebc240a3d |
SHA1 | ef962ecf3b8b97a91c2e1d274b9eca07daf28745 |
MD5 | 7086318a21b79946ad323976ccdd0c0c |
文件类型 | EXE |
文件大小 | 1.36MB |
文件名称 | 022Q3待发债券清单.xlsx.exe |
功能描述 | CS木马 |
技术特点 | 通过Hook达到隐藏C2的目的。 |
在对该样本进行自动化配置解析时,我们发现得到的C2地址竟然是111.111.111.111——一个常用的DNS服务器地址,显然不属于攻击者。这个奇怪的现象引起了样本分析师的警觉。
将内部的载荷单独执行,发现样本确实会与111.111.111.111通信,但原始文件执行时却会连接到一个完全不同的IP地址。经过一番排查后发现,加载器通过导入表hook在不改变原始载荷的情况下改变了C2地址。首先加载器加载内层载荷时,会将GetProcAddress函数hook为GetProcAddress_hook_func。
同样在hook的代码中对InternetConnectA函数进行过滤, 当内层的Beacon进行反射注入时,会调用GetProcAddress_hook_func动态获取InternetConnectA函数,这时hook代码将其定位到自己实现的InternetConnectA_hook_func函数上。
因此在加载完成后的Beacon中,InternetConnectA_hook_func取代了原有InternetConnectA函数,从而可以忽略由配置解析得到的原始IP地址,连接到指定的地址上。
因此无需重新生成内部的CS Beacon载荷, 只需要将存储在加载器.data节中的地址数据改为其他的IP或者域名即可更换木马的C2。
由于本篇报告内容较长(一共15个木马分析案例),限于篇幅,在此只展示一部分,想了解更多内容可以在公众号“微步在线研究响应中心”回复“2022”获取完整版报告(PDF)。希望这份报告可以帮大家在2023年的攻防演练发挥出更佳的水平!
发表评论
您还未登录,请先登录。
登录