导语:PlugX吸引人的地方 PlugX恶意软件可以算是攻击界的老前辈了,自2012年被曝光以来,它就以各种形式被黑客利用,截至目前它还一直活跃在攻击的最前沿。关于其长盛不衰的攻击功能,已经有很多个机构对其进行了研究,比如: 1.由Circl机构发
PlugX吸引人的地方
PlugX恶意软件可以算是攻击界的老前辈了,自2012年被曝光以来,它就以各种形式被黑客利用,截至目前它还一直活跃在攻击的最前沿。关于其长盛不衰的攻击功能,已经有很多个机构对其进行了研究,比如:
1.由Circl机构发布的“TR-12-用于针对性攻击的PlugX恶意软件变体的分析”;
2.由JPCert机构发布的“分析最近的PlugX变体- P2P PlugX”;
3.由Airbus机构发布的“PlugX一些未覆盖点”;
4.由Sophos机构发布的“下一代的PlugX”。
鉴于对其的大量研究,PlugX已经被各个安全厂商重点关注,还为此进行了专门的检测。尽管如此,它仍然是今天许多攻击者的首选工具,这意味着如果攻击者要成功使用PlugX,就要对它进行不断地升级和创新,才能成功感染目标。
PlugX丰富的攻击手段
这也是PlugX恶意软件家族一直吸引我持续关注的地方,所以在本文中我会挑选它的一个变种进行分析。再加上偶然间我发现了Fabien Perigaud的相关研究,并从中了解到了一个老版PlugX构建器。顺着这个思路,我搭建了一个PlugX变种的实验环境,并对PlugX攻击活动进行了深入分析。
在分析中,我发现了该样本使用了许多有趣的技术,比如安装过程以及C2通信。
PlugX通常也被称为是KORPLUG,SOGU,DestroyRAT,目前已被不同的织用于有针对性的攻击,并且是一个模块化的后门程序,它被设计为依靠执行签名和合法的可执行文件来加载恶意代码。通常,PlugX有三个主要组件,一个DLL,一个加密的二进制文件和一个合法且经过签名的可执行文件,用于使用称为DLL搜索顺序劫持的技术加载恶意软件。我先简要介绍一下这个构建器。
我所得到的Builder样本为英文版本(MD5: 6aad032a084de893b0e8184c17f0376a),代码日期为2013年8月份,其中包含了功能丰富的模块化指令以及控制接口,可支持的恶意操作如下:
1.构建有效载荷,对攻击活动进行设置,并对受感染主机的攻击方式与控制服务器之间的通信进行定义;
2.代理连接并构建构建C2通信模块;
3.定义持久性攻击机制及其属性;
4.对要使用有效载荷注入的进程进行设置;
5.定义C2通信回调的时间表;
6.启用键盘记录和屏幕截图功能;
7. 管理所有的受感染系统。
针对每一台被感染的系统,攻击者可以利用多种方式来与系统进行交互并实现远程控制,其中涉及到下列功能模块:
1.磁盘模块允许攻击者编写、读取、上传、下载和执行文件;
2.网络浏览器模块允许攻击者浏览网络连接并通过SMB连接到另一个系统;
3.进程模块用于枚举,终止并列出每个进程加载的模块;
4.服务模块允许攻击者列举,启动,停止和更改攻击属性;
5.注册表模块允许攻击者浏览注册表并创建,删除或修改密钥;
6.Netstat模块允许攻击者枚举TCP和UDP网络连接以及相关的进程;
7.截图模块允许攻击者执行屏幕截图;
8.控制插件允许攻击者以类似VNC的方式查看或远程控制受感染的系统;
9.Shell模块允许攻击者在受感染的系统上获得命令行shell;
10.PortMap模块允许运营商建立端口转发规则;
11.SQL模块允许攻击者连接到SQL服务器并执行SQL语句;
12. 选项模块,允许攻击者关闭、重启、锁定或注销受感染设备;
13.键盘记录模块会捕获每个进程的按键记录,包括窗口标题。
构建用于测试PlugX的实验环境并分析它所使用的攻击技术
下图显示了Plug-X的C2接口:
因此,我就可以使用构建器功能来定义不同的C2命令、控制密码、IP地址、安装属性、注入代码,回调计划等。然后,构建我的有效载荷。由于本文我选的这个版本的构建器(LZ 2013-8-18)所生成的PlugX代码是一种自提取的RAR文档。根据Fabien Perigaud的文章描述,它在运行自提取RAR文档之后将会选择性地在目录中存放这三份文件,被作者称为PlugX三位一体有效载荷。在我的测试环境下,目录为“%AUTO%/RasTls”,文件分别为:一个来自卡巴斯基反病毒解决方案的已签名合法可执行程序,文件名为“avp.exe”(MD5:e26d04cecd6c7c71cfbb3f335875bc31),其功能是实现DLL搜索顺序劫持。当“avp.exe”运行时将会加载第二个文件-“ushata.dll”(MD5:728fe666b673c781f5a018490a7a412a),这是PlugX构建器制作的一个DLL,而这个文件将会加载第三个文件“ushata.DLL.818”(MD5 :21078990300b4cdb6149dbd95dff146f),该文件包含了经过混淆处理和封装的Shellcode。
那么,让我来看看执行自解压存档时会发生什么。这三个文件被提取到一个临时目录,并执行“avp.exe”。执行“avp.exe”时,由于使用Kernel32.LoadLibrary API的DLL搜索顺序劫持,将从运行目录加载“ushata.dll”。
然后执行“ushata.dll”DLL入口点, DLL入口点的代码负责验证系统日期是否等于或高于20130808。如果是,它将会把恶意内容注入到内存中调用“ushata.DLL.818”,并使用Kernel32.VirtualProtect API来修改内存地址分段权限(RWX),其中“ushata.DLL.818”文件中包含了经过混淆处理的Shellcode,下图就是部分Shellcode:
shellcode使用的是自定义算法来解包,这个shellcode包含了位置代码,下图显示了解包后的shellcode。
shellcode首先通过访问包含指向进程环境块(PEB)结构的指针的线程信息块(TIB)来查找kernel32.dll地址,下图显示了shellcode的一个片段,它包含用于查找Kernel32.dll的代码的不同序列的汇编指令。
然后它会读取kernel32.dll输出表,通过将它们与堆叠字符串进行比较来找到所需的Windows API。然后,shellcode利用ntdll.dll.RtlDecompressBuffer API,使用LZNT1算法将DLL(偏移0x784)MD5 333e2767c8e575fbbb1c47147b9f9643解压缩到内存中。 DLL包含用“XV”值替换的 PE header。恢复 PE header签名可以让我恢复恶意DLL。
接下来,载荷将开始执行不同的运行来实现持久性攻击。在Windows 7及更高版本中,PlugX会创建一个文件夹 “%ProgramData%\RasTl”,其中“RasTl”与构建器中定义的安装设置相匹配。然后,使用SetFileAttributesW API将文件夹属性更改为 “SYSTEM|HIDDEN” 。接下来,将其三个组件复制到文件夹中,并使用 “SYSTEM|HIDDEN” 属性设置所有文件。
有效载荷还会使用SetFileTime API从ntdll.dll获取创建的目录和文件的时间戳。
然后创建服务“RasTl”,其中ImagePath指向“%ProgramData%\RasTl\avp.exe”。
如果恶意软件无法启动刚刚安装的服务,则会将其删除,然后通过RegSetValueExW API将注册表 “HKLMSOFTWAREClassesSOFTWAREMicrosoftWindowsCurrentVersionRunRasTls” 的值修改为“C:ProgramDataRasTlsavp.exe” ,在注册表中实现持久性感染机制。
如果构建器选项启用了键盘记录功能,则可能会创建一个随机名称的文件,例如存储按键信息的“%ProgramData%RasTlrjowfhxnzmdknsixtx”。如果有效载荷是使用屏幕截图功能构建的,则可以创建文件夹“%ProgramData%RasTl RasTlScreen”,以<datetime> .jpg格式存储JPG图像,这些格式是以构建过程中指定的。有效载荷也可以创建文件“%ProgramData%DEBUG.LOG”,这其中包含有关其执行过程的调试信息(有趣的是,在执行恶意活动期间,恶意软件会使用OutputDebugString API输出有关正在发生的调试消息)。
PlugX的恶意运行过程
恶意代码通过启动一个“svchost.exe”的新实例来完成它的任务,然后使用 process hollowing技术将恶意代码注入到svchost.exe进程地址空间中。下图显示了进程挖空技术的第一步,其中载荷创建了一个处于SUSPENDED状态的新“svchost.exe”实例。
Process Hollowing是现代恶意软件常用的一种进程创建技术。一般来说,使用Process Hollowing技术所创建出来的进程在使用任务管理器之类的工具进行查看时,它们看起来是正常的,但是这种进程中包含的所码实际上就是恶意代码。
这种技术可以对运行中的进程进行动态修改,并且整个过程既不用挂起进程,也不需要调用额外的Windows API,即无需调用WriteProcessMemory, QueueUserApc, CreateRemoteThread和SetThreadContext。
然后使用WriteProcessMemory API来注入恶意载荷:
现在主进程仍然处于挂起状态,但是之后它会调用SetThreadContext API来改变其状态SetThreadContext API会指向新图像库(image base )的入口点。然后调用ResumeThread API并开始执行恶意代码。如果需要,恶意软件还可以绕过用户帐户控制(UAC)。从这一刻起,控制权被传递给“svchost.exe”,Plug-X就可以开始执行它的操作。由于此时我是幕后操控者,所以我知道在构建过程中所定义的设置。但是,我想了解我如何提取配置设置。在“ Black Hat 2014”期间,Takahiro Haruyama 和 Hiroshi Suzuki 发表了题为“解惑PlugX”的演讲,作者详细分析了各种PlugX样本、演变。其中Takahiro为不同类型的PlugX样本发布了一组PlugX解析器,即Type I,Type II和Type III。我在构建实验环境时,使用的是PlugX II型,顺着这个思路,要转储配置,我需要使用Immunity Debugger并使用Python API。我需要将“plugx_dumper.py”文件放入Immunity Debugger安装路径下的“PyCommands”文件夹中。然后将调试器连接到受感染的进程,例如“svchost.exe”,然后运行插件。该插件将转储配置设置,并将提取解压缩的DLL。
可以看到,这个解析器能够找到注入的shellcode,通过解码配置信息之后,我们能够导出攻击者所注入的DLL文件,而其中则包含了恶意软件的核心功能代码。
接着让我么看看网络流量数据,正如我在PlugX控制器中所观察到的那样,恶意软件可以配置为使用多种网络协议与控制器通信。在我的测试环境中,我将其配置为在端口80上使用HTTP进行通信。网络通信包含一个16字节的标头,后跟一个有效载荷。标头使用自定义例程进行编码,有效载荷使用LZNT1进行编码和压缩。综合分析,我是从控制器启动了一个Shell提示符,输入命令“ipconfig”并观察到网络流量数据的。同时,我将调试器附加到“svchost.exe”并设置断点,先在Ws2_32.dll!WSASend和Ws2_32.dll!WSARecv上捕获数据包,又在ntdll.dll!RtlCompressBuffer和ntdll.dll!RtlDecompressBuffer上查看压缩前后的数据。通过在自定义编码例程之前和之后查看数据,可以发现很多变化。下图就是自定义编码例程的反汇编列表:
所以,从调试器的角度来看,只要设置了正确的断点,我就可以开始观察正在发生的事情。下图的左侧显示了编码和压缩之前的数据包。它包含一个16字节的头文件,其中刚开始的4个字节是自定义编码例程的关键字。接下来的4个字节是包含正在使用的命令或插件的标志,然后接下来的4个字节是大小。在头文件之后,包含的载荷是ipconfig.exe命令的输出。而下图的右侧则是编码和压缩后的数据包,它包含由编码和压缩的有效载荷进行编码的16字节头文件。
然后,恶意软件使用WSASend API发送流量。
捕捉流量,我就可以观察到相同的数据。
在控制器端,当数据包到达时,头文件将被解码,然后载荷将被解码和解压缩。最后,输出显示给攻击者。
现在开始说说我是如何处理C2流量的?对于这些流量,我可以捕获并解码它们。 Kyle Creyts创造了一个支持PCAP的PlugX解码器。该解码器可以支持PlugX Type I的解密。但Fabien Perigaud逆向了Type II算法并在python中实现了它。如果我将Kyle的想法与Takahiro Haruyama和Fabien Perigaud的想法结合起来,我可以创建一个PCAP解析器来解析PlugX Type II和Type III。下面我会针对1个数据包进行具体的讲解,我会向捕获流量,然后使用一个小型的python脚本来解密数据包。由于它不依赖Windows,所以使用herrcore的LZNT1 就可以实现,该实现基于ChopShop协议分析和解码器框架。
总结
我在本文先用了PlugX控制器构建了一个测试环境,然后查看了恶意软件的安装及调试过程,进而查找和解释了DLL搜索顺序劫持,PlugX的攻击和感染机制、经过混淆处理的Shellcode、持久化攻击机制以及它所使用的process hollowing技术。在这些分析的基础上,我又使用了一个随时可用的解析器,通过从内存中转储它的配置,简单分析PlugX与C2通信的方式,并创建了一个脚本来解码流量。
通过这一系列全面地分析,在一个受控制和隔离的实验环境中,我可以进一步模拟不同的攻击工具和技术,并观察攻击者如何进行攻击。这样我就可以学习,按照自己的方式练习,并在幕后进行观察,以更好地理解攻击方法并找到对应之策。