一、背景
近期发现一枚样本,传播载体为批处理文件(cl.bat),经过分析发现其通过net use命令将某Cloudflare Tunnel内网穿透服务挂载为网络驱动器后,下载并运行其中的恶意Python脚本(yea.py)。该py脚本为典型的ShellCode加载器,通过donut生成的ShellCode二进制经过base64编码+RC4加密两层处理之后在脚本中反序列化加载(调用Windows API VirtualProtect修改内存属性为可读可执行,将解密后的二进制数据强制转换为函数指针,并直接调用函数指针执行内存中的ShellCode),将其ShellCode提取并分析后发现其基于开源项目laZzzy修改,会拉起notepad进行APC早鸟注入,连接C2(95[.]217[.]129[.]88[:]5921)接收指令。该黑客警惕性高,样本传播12小时后迅速关停了当前使用的Cloudflare Tunnel内网穿透服务和C2。由于分析时C2已离线,通过对威胁情报进行研判发现:(1)威胁情报信息显示,在连接该C2的样本中发现了另一个Donut ShellCode,对该新发现的ShellCode进行研判后发现其为直接连接该C2的XWorm木马 (C2: 95[.]217[.]129[.]88[:]5921; Version: XWorm V5.6)。(2)威胁情报信息显示,该C2曾下发通过PowerShell下载其他载荷的指令,对此载荷做进一步分析和威胁情报研判后发现该载荷是连接另一个C2的XWorm木马 (C2: ftpproxy672-44246[.]portmap[.]io[:]44246)。
二、样本分析
第一节:
[原始样本分析]
原始传播样本cl.bat (0d1323d50ff0496c7ee687d65050b02de85e80b81938d7e1df204ed7320ef7c2)代码如下图所示:
可见网络驱动器挂载地址: \digital-childrens-junior-cure[.]trycloudflare[.]com@SSLDavWWWRoot (使用Cloudflare Tunnel内网穿透服务)代码说明如下图所示:其下载jaka.zip (96f96b24b16109fb93d65b68c983bb2fa69f07232212437c53d6bb32642f93c3)并解压出yea.py (f27344ae5b14d85975391f8fec471ee806e85568c6d87ac835693b47a7bacfad),使用jaka.zip内携带的Python环境启动,执行其中的代码。
jaka结构如下图所示:
yea.py代码如下图所示:
在yea.py代码中可以看到:(1) 该脚本先对字符串中的数据进行base64解码,赋值给变量GWFiawqTIgMLwbSqDwRGMzYOKXbSpnYm.(2) 将ASCII编码的xWp0LaAO字符串和base64解码后的数据作为参数传入函数IxcXpWUvfBDATqvXtEqdwbKpAovJwfdU,将函数返回结果赋值给变量FiCSYrhwEzAKhYhvZqAiVpGrlYwsnuOS.现在分析函数IxcXpWUvfBDATqvXtEqdwbKpAovJwfdU,其内部有一个变量IluiDvLCpTJsFOJzDLmyyyqiaMhVyKFm初始化了为一个长度为256的列表,值从0到255,用于定义一个S盒,初始化S盒等状态向量,为后续执行RC4的KSA(密钥调度算法)步骤做准备,然后将变量RuEZdSDXxJAkVRPopNlDpUedgxdYQnZp初始化为0.代码中有两个循环。第一个for循环遍历0到255,通过密钥对状态向量进行置换,对S盒进行打乱。至此,符合RC4的KSA(密钥调度算法)。在第二个循环中,变量aAKfNgohZOMShFLCIxwMcIHnbLjFjhZx和RuEZdSDXxJAkVRPopNlDpUedgxdYQnZp重新初始化为0。然后,对于数据中的每个字节,进行索引的更新、交换状态向量,并生成一个密钥流字节UVNOGXlIDSmoOkzXydluvTrriPJYzdEm。最后,将输入的数据字节与该密钥流字节进行异或操作,将结果添加到结果字节数组中,得到解密后的数据,最后返回解密后的字节。至此,符合RC4的PRGA(伪随机生成算法)。而xWp0LaAO字符串密文的则是解密密钥。因此,黑客使用RC4加密算法(密钥: xWp0LaAO)对恶意二进制数据进行了加密,再将密文进行了base64编码,然后存储至该Python脚本中,实现了序列化存储。
解密步骤:法一:先将base64数据解码,再进行RC4解密(密钥: xWp0LaAO)。解密后可得到一个通过开源项目Donut生成的ShellCode二进制法二:由于最终解密后的数据赋值给了变量FiCSYrhwEzAKhYhvZqAiVpGrlYwsnuOS,直接修改其源代码保存解密后的数据
继续向下看,可以看到: 脚本执行了ctypes.create_string_buffer(FiCSYrhwEzAKhYhvZqAiVpGrlYwsnuOS)将解密后的数据写入到内存缓冲区,然后执行ctypes.windll.kernel32.VirtualProtect调用Windows API VirtualProtect修改内存属性为可读可执行,其中0x40是内存保护标志,表示允许读写和执行。然后继续执行: 复制代码 隐藏代码pEoiTsJphfEBjJLbNFXEMvdPdvfdmibC = ctypes.cast(IvBappaUBLSolqUdSbrJfGzprBgfHtdr, ctypes.CFUNCTYPE(ctypes.c_void_p))# 将缓冲区转换为函数指针pEoiTsJphfEBjJLbNFXEMvdPdvfdmibC()# 执行内存中的代码
将解密后的二进制数据强制转换为函数指针,直接调用函数指针执行内存中的ShellCode.
我们提取并保存解密后的数据,发现其为Donut生成的ShellCode (7f48d92abd37c4c2d1ced2a850de9ff6a9b8f31113e1853a26c0d7968ae14573),如下图所示:
我们使用开源项目将该Donut ShellCode加载的内容解密,得到可供分析的可执行文件 (11a2ac0a4953482356f338ae02e110e13b6eb9b8dad1b6a1152fba7bd1d306f9) [1],如下图所示:
静态分析后发现,样本的输出信息毫不遮掩,向我们呈现出许多输出内容和字符串,显示其具备ShellCode加载、Payload解密和注入器等功能且具有多种注入方式,如下图所示:
以上信息展示出样本是一个成熟的ShellCode加载器和注入器,样本我们比对了样本中出现的字符串、输出信息和函数功能,确认该样本基于开源项目laZzzy修改。开源项目laZzzy支持的ShellCode执行技术包括但不限于: 复制代码 隐藏代码1. Early-bird APC Queue (requires sacrificial process)// 早鸟APC队列注入2. Thread Hijacking (requires sacrificial process)// 线程劫持3. KernelCallbackTable (requires sacrificial process that has a GUI)4. Section View Mapping5. Thread Suspension// 线程挂起6. LineDDA Callback7. EnumSystemGeoID Callback8. Fiber Local Storage (FLS) Callback9. SetTimer10. Clipboard
如下图所示:
可以看到,该开源项目所具有的功能和支持的注入方式与上述的样本静态分析结果完全一致。
同时,样本命中了社区Yara规则HKTL_LaZzy_Loader_Nov22_1,进一步佐证了其基于开源项目laZzzy修改,如下图所示:
动态分析后发现,样本运行后会拉起notepad进行APC早鸟注入。其将目标进程内存属性由可读可写(Read-Write)修改为可读可执行(Read-Execute),修改目标进程的APC队列,将恶意代码注入其中,远程注入notepad进程,如下图所示(图左为基于ETW-TI的行为监控工具,右图为执行样本以及样本的返回和输出,二者相吻合,结论相一致):
notepad进程被注入后会不断尝试与远程地址95[.]217[.]129[.]88[:]5921建立TCP连接,如下图所示:
[关联样本研判1]
由于C2已经离线,我们在VirusTotal平台上通过IP 95[.]217[.]129[.]88的威胁情报发现了与之相关联的另一个Donut ShellCode (2ad007f1bb1668e52e096d1bde95e57f1a2a2cfdd42fe37411963e131adf2fd0),解密后关联到样本8d937db7e89980ba45a77f3f0a09cc7898c01c1991f85dd052d93783aad88bd9. 从当时的动态运行结果可以证实其为XWorm木马,且版本为XWorm V5.6,样本配置为: 复制代码 隐藏代码{'XWorm': {'Sleep': [3], 'Hosts': ['95.217.129.88'], 'Port': ['5921'], 'KEY': [''], 'SPL': [''], 'Groub': ['XWorm V5.6'], 'USBNM': ['USB