概述
海莲花(OceanLotus)是一个据称东南亚背景的APT组织。该组织最早于2015年5月被天眼实验室(现红雨滴团队)披露并命名,其攻击活动最早可追溯到2012 年4月,攻击目标包括人权代表、异见人士、媒体、银行、海事机构、海域建设部门、科研院所和航运企业,后扩展到几乎所有重要的组织机构,受害区域涉及东亚、东南亚、欧洲等地区,持续活跃至今。
从2020年中开始海莲花组织逐渐放弃了基于鱼叉邮件的投递方式,开始通过渗透的手段对高价值目标进行攻击活动,这意味着出现在大众视野范围内的海莲花将会大幅度减少。但历史告诉我们,看不见的敌人才是最危险的,那些尚未被发现的APT攻击,才应该是我们研究的重点。
本文将对部分出现在VirusTotal上的海莲花后渗透阶段释放cs远控的各类白加黑组件进行分析和总结。
样本分析
从shellcode的存放位置来讲,可以大体将海莲花白加黑组件分为shellcode在资源和shellcode硬编码在数据段。而从shellcode的加载方式来讲,可以将其分为:不依赖外部文件直接自解密、获取当前主机信息作为密钥解密shellcode、读取外部文件解密shellcode、进程注入加载shellcode等几类。下文将分别对这几类样本进行分析。
shellcode硬编码
获取主机信息解密类
此类样本入口点代码如下,关键函数在DllMain末尾的函数中
该函数内部会执行一个call调用,push 0 之后直接调用ExitProcess结束进程
被调用的这个函数将会先创建一个互斥体进行多开检测,互斥体的命名格式为,该互斥体名通常由上一段shellcode获取计算机用户名并转换生成:
Local{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
互斥体创建完成之后,程序将会VirtualAlloc分配一段内存空间并在将一段硬编码在程序中的数据拷贝过来,最终通过call esi的方式跳转到新开辟的内存空间中执行。
shellcode如下,这类样本的shellcode仅需动态获取API地址即可,不用再自解密自身。
大多数情况下,这段shellcode也是一个加载器,它会尝试获取当前主机的一些信息以解密后续的payload,这取决于上一阶段的样本向C2发送了哪种类型的信息hash值以生成加密的数据。常见的信息类型为计算机名、用户名、ip地址等。
程序以相同的逻辑获取当前主机的信息,计算hash并尝试用该hash进行解密,这是一种较为有效的反分析手法,可以确保程序不会在非预期的环境下运行。
待解密的数据也以硬编码的形式存储在原始文件的data段中
若程序解密成功,则创建线程执行解密之后的shellcode
自解密类
在另外一种情况下,攻击者可能会在加载硬编码的shellcode之前获取当前dll的调用进程名并与预定义的进程名做比较来实现简单的环境检测
而这个版本硬编码的shellcode将会动态解密自身
循环自解密之后,程序动态获取API地址,然后通过VirtualAlloc分配新的内存空间之后填充另外一段shellcode加载执行。
加载的代码为CobaltStrike的payload
释放白加黑组件类
而在某些情况下,硬编码的shellcode可能是如下形式:
此类样本主要是起到一个文件拷贝功能,程序会将当前目录下一组白加黑的样本拷贝到%temp%目录下并启动白exe以加载恶意dll。
拷贝利用的黑dll
设置计划任务用于启动%temp%目录下的wps.exe
设置的计划任务如下
shellcode在资源
获取主机信息解密类
此类样本和上述样本在解密方式上保持一致,均为获取受害者主机上的基本信息生成key进行解密。但不同的是此类样本的shellcode并没有硬编码到数据段,而是藏在了资源中。样本在dllMain进来依旧是先创建一个海莲花风格的互斥体,然后在执行一段无实际意义的代码之后读取资源并创建线程执行资源的shellcode。
此类样本读取资源之后将会直接加载,在shellcode中动态解密自身。
资源shellcode会通过多个循环动态解密自身
解密完成之后通常会出现如下格式的代码,一般情况下,call执行的代码主要是用于动态获取API地址,jmp跳转过去的代码才是真实的功能代码
和类别一的解密逻辑相同,此类样本最终通过获取的信息生成key然后尝试用该key进行解密,若解密成功创建线程执行解密后的shellcode
读取文件解密类
除了获取上一阶段的主机信息以解密shellcode,海莲花有时候还会通过读取特定的外部文件进行解密。
原始样本为dll,依旧是白利用的方式加载名为InitLPUHelper的导出函数
在ExitProcess之前的函数调用,会读取当前的资源文件并将其拷贝到VirtualAlloc分配的新内存空间中,通过call edi的方式加载shellcode。
shellcode入口点是熟悉的自解密代码,代码会动态循环解密自身,解密之后的代码如下:
加载链接库和获取API地址
尝试打开%Temp% 路径下的vpKQod.tmp文件
若文件打开失败,程序则判定当前的环境不符合预期,从而退出运行。
进程注入类
此类样本主要通过进程注入实现shellcode的加载, 外层的loader大同小异,只是少数样本会将关键call藏到某个导出函数中而不再是dllMain
该段shellcode执行之后会动态获取一些API的地址并调用
创建一个svchost.exe进程用于注入
最终,程序尝试在刚才启动的进程中进行注入
分配的空间为0x90000
将shellcode写入到svchost的内存中
写入的代码为海莲花的常用自解密shellcode
总结
最开始,海莲花艺高超的社工技巧出现在我们的视野中,那时候对海莲花TTP的构建中其中一条便是:擅长使用鱼叉攻击和水坑攻击。但通过近两年的表现来看,攻击者的战术也在不断更新。他们已经逐渐舍弃了钓鱼攻击的手法,而是将更多的精力放在了供应链和渗透上,让受害者更加防不胜防,难以排查。作为安全人员,我们不可能专情的只盯着一个APT组织,但是作为APT组织,他们可以非常「纯粹」和「专一」的盯着一个目标。本文简单分析了海莲花组织在渗透中所使用的白加黑组件的各类加载方式,但这只是我们视野范围内的冰山一角,在看不到的地方,还有更多未知的威胁等着我们去发现。