MuddyWater APT 样本分析

简介:

本文分析的样本被认为来自于攻击目标为中东地区的一个APT组织,即MuddyWater。像往常一样,您可以从VirusBay下载该样本,这也是我最喜欢下载新的恶意软件样本的地方,而且下载是免费的。下面我们开始分析:

MD5哈希:6c997726d502a68af2ac2e3563365852

阶段1

已知该恶意软件是以一份Word文档的形式出现的,我们可以清楚地看到,在打开该文件时,最显眼的是其顶部标志显示来自塔吉克斯坦共和国外交部。出人意料的是,需要启用内容(Enable Content)并输入Hash代码来解密该文档。接下来让我们看看点击Enable Content会发生什么。

MuddyWater APT 样本分析

阶段2

打开宏菜单,我们可以看到其有效载荷是经过混淆的。总共有4个恶意的宏,都是混淆过的。幸运的是,对恶意宏的混淆并不难分析,因此我们可以很容易的去除混淆。从我的虚拟机中提取宏到我的Linux机器上的个人文本文件之后,我就可以更容易地分析宏了。在检查Document Open宏时,毫无疑问第一步要先声明多个变量。然后,对变量进行分配,创建一个看起来是Base64编码的字符串。最后,将这些变量添加到最终变量中,表示为“VHMDWPZAEVYFSGYDZHZAXWTGASDREZ”。在这之后还需要进行另一部分操作,但是我首先决定提取存储在变量VHMDWPZAEVYFSGYDZHZAXWTGASDREZ中的字符串。

MuddyWater APT 样本分析

为了提取字符串,我编写了一个简单的python脚本,将“&”替换为“+”,这样python就能够将字符串拼接在一起。我复制了将字符串分配给变量的宏的这部分代码,并将其写入脚本中。下面我将存储了所有变量的部分包含在了主变量中,然后可以输出完整的Base64编码字符串。可以在这里找到完整的脚本(它不复杂,只是将字符串连接在一起)。当字符串是Base64编码时,脚本会解码字符串,并将解码的字符串写在编码字符串下面,所以两种字符串都在文件中。

既然第一部分已经被去混淆了,可以继续分析宏的其他部分,并且我们可以回到Base64解码之后。在变量VHMDWPZAEVYFSGYDZHZAXWTGASDREZ(现在我将调用EncodedPowershellScript)中的字符串被填充之后,它会被传递给另一个宏中的函数,这一操作过程也被混淆了。此处混淆靠XOR和Chr()形成字符串。

在VB脚本中,Chr()允许用户将字符代码解析为他们各自的字符,例如Chr(65)返回“A”。幸运的是,Python还包含Chr()命令,因此我们不需要手动转换代码。在我们能够进行转换代码之前,首先需要通过将两个数字进行异域运算来查找代码:

FLHYHBCQJWZXBUFYAXWVHIBFVJHRJM = FLHYHBCQJWZXBUFYAXWVHIBFVJHRJM & Chr(93 Xor 16)

第一部分解析字符串“MSXML2.DOMDocument” 并将其存储在变量FLHYHBCQJWZXBUFYAXWVHIBFVJHRJM中。然后宏使用CreateObject创建一个对象,并将解析后的字符串作为参数传递。

MuddyWater APT 样本分析

然后,用同样的方法对另一个字符串进行去混淆,这一操作解析为“b64”。创建第二个对象,并且在该对象中创建一个元素,同时将“b64”作为该元素存储在新创建的对象中。

MuddyWater APT 样本分析

最后一个字符串除去混淆后,得到了“bin.base64”,并将其添加在第二个对象中。然后,通过Document_Open宏传递的EncodedPowershellScript也被添加到第二个对象,并且将其从Base64转换为明文。然后函数退出,将明文返回给调用函数。

MuddyWater APT 样本分析

返回到Document_Open宏,我们可以看到4个混淆程度更严重的字符串。但是,最先被除去混淆的三个字符串被添加在一起,形成一个字符串,然后再创建该字符串。当我们将前三个字符串去混淆并将它们放在一起时,它创建了“Scripting.FileSystemObject”这一字符串。然后该字符串作为一个参数传递给CreateObject。该宏中的第四个字符串,在被除去混淆之后,包含该文件路径:“C:\Users\Public\system.ps1”。然后调用CreateTextFile,在公用目录中创建system.ps1文件,其中包含解码的Powershell脚本。

MuddyWater APT 样本分析

最后,在该样本分析第2阶段结束之前,剩下的两个宏被执行,这两个宏分别是Form_NewVBS()和Execute_File()。与其命名含义相同,他们分别负责形成一个新的VB脚本,和执行文件。这里VB脚本的形成方式与第一个Powershell脚本的形成方式相同——因此我编写的Python脚本也同样适用于此。然后新形成的VB脚本被写入一个文件,该文件同样存储在C:\Users\Public\ directory,名为system.vbs。Execute_File()宏负责执行system.vbs,继续执行流程,并继续到第三阶段。

阶段3

此样本的第3阶段包含两个文件,分别是提取的.VBS文件和提取的.PS1文件。由于阶段2首先执行.VBS文件,我们就从.VBS文件开始。

打开system.vbs时,我们可以看到一长串数字和看起来像数学符号的东西——可能是用这些计算来创建一个字符串?这串数字和符号都被分配给一个变量,该变量命名为dRnKHWIxVUvMVJuEMmJPZAQQynhwisNKcWN。我们可以看到,一旦该数字字符串被分配给上述变量,它就会被分割并存储在变量lcegmTESJSUSDBdLwgBySRMhvyIciMLERgj中,分割使用的是下面的split命令:

lcegmTESJSUSDBdLwgBySRMhvyIciMLERgj = spLIt(DrNKHwIxvuvMVJueMmJPZAQQyNHWiSnkcwn, cHr(eVAL(6031-5989)))

因此,该命令用值chr(eval(6031-5989))将长字符串分割,在计算时,chr(eval(6031-5989))解析为chr(42),它等于“*”。我们可以使用python将“*”从字符串中分离出来,然后将输出写到一个文件中。现在我们有一长串的数学运算,让我们看看下面的脚本是怎么做的:

MuddyWater APT 样本分析

虽然这看起来很容易混淆,但是一旦将变量的名称更改为更简单的变量名称,就更容易理解了。首先,为列表中的每个数学运算符创建一个For循环。使用chr()计算操作的值,然后转换为字符。然后将其存储在变量nAkbJSmuWefKMmYrXSKmbiWyawkMwOmehqu中。一旦计算了所有操作并将结果转换为一个字符,就会退出For循环并执行另一个Sub Routine(子程序),该程序负责执行For循环中生成的字符串。

我们可以使用Python轻松地形成最后一个字符串:

for item in string_1: 
 string_2 += chr(eval(item))
print string_2

这一操作将把列表中的所有数学操作转换为字符,然后将其输出到终端。你可以在这里找到完整的(简单的)脚本。

现在我们把字符串去除混淆,我们得到的如下所示:

Set objShell = WScript.CreateObject("WScript.Shell")
command = "powershell.exe -WindowStyle hidden -ExecutionPolicy Bypass -nologo -noprofile -file C:\Users\Public\system.ps1"objShell.Run command,0
Set objShell = Nothing

因此,该VBS文件负责执行我们提取的混淆的powershell文件,下面我们分析一下。

在这个文件中,我最先注意到的是二进制字符串的大数组,以及函数“[cOnvERT]::TOInt16”——因此我们现在需要将看起来像二进制的三个字符串数组转换成字符串。为了转换字符串,我们可以使用powershell。但是,由于命令的结果被传输到IEX,并且IEX会执行转换的字符串,我们需要从字符串中将其删除,并将剩下的部分输入Powershell中。由于字符串非常长,我将字符串复制到.PS1文件中,并使用Powershell执行它:

MuddyWater APT 样本分析

当我们对前两个字符串执行这个操作时,我们会收到类似于上面图像中所示的输出。在转换第三个和最后一个字符串时,到目前为止,我们接收到的是实际的、易读的字符串:

MuddyWater APT 样本分析

阶段4

第四阶段由三个部分组成:主后门、附加功能和变量——三者都存储在单独的文件中。因此,我们从保存所有变量的文件开始。

MuddyWater APT 样本分析

在这个文件中没有任何可读的东西——除了最后一个字符串:

.REpLACE(([ChAR]103+[ChAR]56+[ChAR]88),[STRIng][ChAR]39).REpLACE(([ChAR]89+[ChAR]108+[ChAR]48),[STRIng][ChAR]124).REpLACE(([ChAR]70+[ChAR]85+[ChAR]97),[STRIng][ChAR]36).REpLACE(([ChAR]102+[ChAR]115+[ChAR]66),[STRIng][ChAR]34) | . ( $env:PUbLic[13]+$ENv:pUbLIC[5]+'X')

这意味着文件自身进行了去除混淆,然后使用IEX执行该文件,因此,如果我们删除IEX最后面的 ($env:PUbLic[13]+$ env:PUbLic[5]+ ' X '),那么按道理它应该输出去除了混淆的文件。在这方面MuddyWater实现了总共4层混淆,所以当该文件被混淆了,其输出的是混淆程度更严重的文本。幸运的是,使用的混淆方法相同,因此我们可以使用相同的方法来对文件进行去除混淆。进行了四层去除混淆之后,剩下的如下:

MuddyWater APT 样本分析

因此,结果仍然还是有一定程度的混淆,简单地将这个脚本复制并粘贴到Powershell IDE中,我们可以提取出来下面这些值:

MuddyWater APT 样本分析

现在我们已经提取了C2服务器使用的IP地址,并找到了该恶意软件使用的代理站点。在撰写本文时,该代理站点已经被清除了所有恶意软件,所以为了公司的利益,我决定不将这些恶意软件公布。其C2 IP也出现故障,所以我不能对其进行检查。

不管怎样,现在我们对该文件有了一定的应对打算,我们开始对下一个文件进行分析。

MuddyWater APT 样本分析

同样的,该文件也是高度混淆的,但是它遵循变量文件使用的相同的去除混淆线路。删除对IEX的所有调用,并使用Powershell运行,我们得到一个包含多个函数的输出。清除剩余的混淆后,功能如下:RegRead、RegWrite、 RegWriteCurrentUserProxy、 RegWriteLocalMachineProxy、Encode 和Decode。

MuddyWater APT 样本分析

最后的文件-后门。

MuddyWater APT 样本分析

我们不对每个单独的文件的功能进行解释,只讨论后门的功能,及执行程序。在后门执行时,它使用了“IsDebugEnv”函数,该函数包括检查运行进程是否匹配硬编码字符串的列表,如“ollydbg”。如果有任何匹配,后门关闭计算机,防止进一步分析。如果后门没有找到任何匹配,它返回并试图通过在名称“Windows Optimizations”下写入“HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Run”和“HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Run”,获得持久性。这与公共目录中的Visual Basic脚本有关。系统任务也会使用schtasks进行调度,这也与Visual Basic脚本相关联。后门还使用attrib命令来更改system.vbs和system.ps1文件的属性,以隐藏它的用户。最后,该样本修改Excel和Word注册表键,允许附件和其他恶意文件在不警告用户的情况下运行。

在恶意软件嵌入系统后,它会休眠一个小时——这可能是另一种反分析方法。一旦时间到了,恶意软件就会试图使用密钥“BitDefender”,写入HKLM/Software/。即使该注册表写入成功了,它仍然会与密钥“BitDefender”,一起写入HKCU/Software/。这看起来不像一个持久性方法,而是一种检查恶意软件是否已经安装的方法。

一旦其改变了注册表,就会执行“getKey”函数,该函数创建了一个看起来是唯一的ID,由系统操作系统、用户名、版本等组成,与如下所示类似:

a=r&b=REVERSING~~RE~~64-bit|6.1.7601|Microsoft Windows 7 Ultimate |C:\Windows~~LAN_IP~~WORKGROUP

这是通过“register”函数生成的。一旦生成了密钥,就使用Base64进行编码。如果我们用编码函数对上面显示的唯一ID进行编码,我们得到如下:

|T1y)*I9UkVWRV)TSU5Hfn5SRX5[NjQt|*l0f(|uMS43NjA$fE1p|3)vc29*dCBXaW5k@3dzI(cgVW$0aW1hdGUgfEM6XFdp@*Rvd3N[fk$BTl9)UH5[V09
SS0dST1VQ

然后将其发送到C2服务器,无论响应是什么,它都保存在一个变量中。getKey函数在while循环中运行,因此如果该恶意文件无法访问C2服务器,它将休眠120秒,然后重试。当密钥成功生成后,接收命令的循环就开始运行。这一过程包括首先检查使用IsDebugEnv的调试程序,然后调用getCommand,在这里分析的样本将到达C2服务器并解码该命令。然后执行该命令,并且使用sendResult将结果发送回来,sendResult会在发送之前对结果进行编码。在执行命令并返回结果后,程序休眠300秒,然后跳到循环的开始。

该恶意软件样本能够通过HTTP发送和接收命令、读取并写入注册表、编码和解码字符串、收集系统信息,并允许攻击者远程访问以执行本地命令。它也可以作为一个下载器,或者仅仅是一个更复杂的恶意软件的stager。

IOC:

C2:

hxxp://104.237.233.39:8081

文本文档:

6c997726d502a68af2ac2e3563365852

阶段1的宏:

c2d06b61d63c2a3093747e7bb4982e50

3ef79f2cb378c12bc49a2d489629db40

cdc9b9ee8193cfb4209e43caebbdb330

fcd72d7c8b73ca54c24909e3d200b9d8

VBS文件:

5fa0eb28851fd4885cf194825a75fd0d

PS1文件:

70fc08a450a3503d34545e6a87d64dc0

变量:

344e196be72d24cb7d43c4f3af81fa5a

额外的函数:

9d2245bbafee132f0b8b27f555e9e030

主要后门:

102b79929e8dfae8d5e6611e75867606


原文发布时间为:2018-06-8

本文来自云栖社区合作伙伴“嘶吼网”,了解相关信息可以关注“嘶吼网”。

相关文章
|
1天前
|
vr&ar
R语言时间序列TAR阈值自回归模型(下)
R语言时间序列TAR阈值自回归模型(下)
|
1天前
|
前端开发
数据分享|R语言零膨胀泊松回归ZERO-INFLATED POISSON(ZIP)模型分析露营钓鱼数据实例估计IRR和OR
数据分享|R语言零膨胀泊松回归ZERO-INFLATED POISSON(ZIP)模型分析露营钓鱼数据实例估计IRR和OR
27 4
|
8天前
|
安全 vr&ar
R语言时间序列TAR阈值模型分析
R语言时间序列TAR阈值模型分析
|
8天前
|
vr&ar
时间序列TAR阈值自回归模型
时间序列TAR阈值自回归模型
13 0
|
6天前
|
机器学习/深度学习 数据可视化 算法
Python支持向量回归SVR拟合、预测回归数据和可视化准确性检查实例
Python支持向量回归SVR拟合、预测回归数据和可视化准确性检查实例
|
7天前
|
数据可视化 Python
R语言GARCH建模常用软件包比较、拟合标准普尔SP 500指数波动率时间序列和预测可视化
R语言GARCH建模常用软件包比较、拟合标准普尔SP 500指数波动率时间序列和预测可视化
25 9
|
7天前
|
数据挖掘
R语言预测期货波动率的实现:ARCH与HAR-RV与GARCH,ARFIMA模型比较
R语言预测期货波动率的实现:ARCH与HAR-RV与GARCH,ARFIMA模型比较
24 0
R语言预测期货波动率的实现:ARCH与HAR-RV与GARCH,ARFIMA模型比较
|
7天前
|
数据挖掘
R语言预测波动率的实现:ARCH模型与HAR
R语言预测波动率的实现:ARCH模型与HAR
13 0
|
7天前
|
数据挖掘
R语言预测波动率的实现:ARCH模型与HAR-RV模型
R语言预测波动率的实现:ARCH模型与HAR-RV模型
12 1
|
7天前
|
机器学习/深度学习 算法 数据可视化
python用支持向量机回归(SVR)模型分析用电量预测电力消费
python用支持向量机回归(SVR)模型分析用电量预测电力消费
27 7

热门文章

最新文章