FortiGuard实验室最近发现了一封假装来自匈牙利政府的电子邮件。它通知用户,他们的政府门户的新凭证已经附加。然而,附件是一个压缩的可执行文件,在执行时,它将把Warzone RAT提取到内存中并运行它。在我们最初发现的几天后,匈牙利国家网络安全中心也发布了关于这次攻击的警告。
受影响的平台:Microsoft Windows;
受影响方:Microsoft Windows用户;
影响:为攻击者提供远程访问;
严重级别:高;
感染载体
最初的感染是通过模仿匈牙利政府门户网站的仿冒电子邮件(图1)发生的。该门户用于在线开展公务,如提交文件、订购ID等。
含有Warzone RAT恶意软件附件的恶意邮件
电子邮件告诉受害者,他们的凭据已更改,并附上了新的凭据。完整的翻译是:
从语言上看,这封邮件是由母语为英语的人写的,然而这封邮件并没有使用官方通信应有的语法。
附件是一个zip文件,其中包含一个伪装为PDF的可执行文件。如上图所示,该文件包含一个模仿Adobe PDF Reader图标的图。文件名以pdf结尾,但扩展名为.exe。然而,在默认的Windows安装中,文件扩展名是隐藏的,它看起来像一个实际的PDF文件。用户唯一的警告是文件资源管理器将文件类型显示为“应用程序”,这意味着它是可执行文件而不是文档。但这对普通用户来说可能并不明显。
伪装成PDF的可执行文件
俄罗斯套娃式的混淆
当我们开始分析“Uj bejelentkezEsi adatai·pdf.exe”时,我们很快意识到它就像一个俄罗斯套娃混淆,但不是每次打开一个娃娃都会得到一个更小的娃娃,而是得到越来越多的混淆的.NET二进制文件,这就是我们将在本节中看到的。
“Uj bejelentkezEsi adatai·pdf.exe”是一个32位的.NET可执行文件。一旦在dnspy(一个著名的.NET反编译程序)中进行了反编译,我们就会发现源代码很简单,同时也很容易混淆。代码的一般结构如下图所示。原始二进制文件可能在重命名为“Uj bejelentkezEsi adatai·pdf.exe”之前被称为iANO。
“Uj bejelentkezEsi adatai·pdf.exe”的程序结构
代码显示了BattleShipLiteLibrary和一个计算器的混合体,这看起来像是桌面游戏Battleship的实现。下图显示了实现计算器的实际代码。
计算器的实现
有时它看起来像一个计算器,行为也像一个计算器,但它仍然不是一个真正计算器。在本例中,为计算器设置用户界面的InitializeComponent()函数也会在最后调用PerformLayout()函数。然后该函数继续调用ResourceTemplateDefine()函数。
从资源加载代码
ResourceTemplateDefine()函数加载名为“Web”的资源。起初,它似乎将其解释为位图,但最后,它将其转换为程序集。如果我们在十六进制编辑器中查看这个资源,我们会看到它有一个位图标头。但是当我们进一步观察时,它还包括MZ字符,这是可移植可执行文件(PE)的神奇值。在底部,我们甚至可以看到臭名昭著的“此程序不能在DOS模式下运行”字符串,这是PE文件的另一个标志。
检查“Web”资源发现它隐藏了一个PE文件
该PE文件从资源中加载。下图显示了使用GetMethod()加载它的方法,并调用其中一个方法。另一个图显示了在调试器中调用的方法是' sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY() '。
从PE文件加载并调用特定的方法
显示被调用方法名称的调试器
KeyNormalize.dll
“Web”资源中的PE文件的原始名称是KeyNormalize.dll。从被调用函数的名称中,我们已经可以预期它是混淆的。由于它是另一个.NET可执行文件,我们可以在dnspy中打开它并轻松检测,并使用SmartAssembly确认它已被混淆。
使用SmartAssembly混淆器
De4Dot是一个去混淆器工具,在消除二进制文件的混淆方面很有效率。但是,它不能解析混淆的字符串。为此,我们编写了一个可以解析字符串的定制程序。
在静态分析KeyNormalize.dll之后,我们看到它从资源加载另一个二进制文件并执行函数调用,如前面所示。
从资源加载程序集并调用它的一个函数
我们可以恢复二进制文件,并再次使用调试器调用哪个函数。下图显示了变量'text6 '中的base64编码数据,在解码之后,我们看到它是另一个PE文件。这个PE文件也是一个.NET可执行文件,最初称为Metall.dll。
变量' text6 '中的Base64编码数据
' text6 '中的数据是另一个PE文件
在调试器中,我们还可以看到在这个新恢复的PE文件中调用了' OwbdG5aNVQQYu6X20i.o9pVsMvoTr75y5TrkE.V4j9c6YCwC() '函数。
Metall.dll
在开始分析这个二进制文件之后,我的第一反应如下图所示。
metal .dll为游戏添加了另一层混淆
不用说,metal .dll通过向二进制文件添加控制流扁平化等特性,增加了混淆的程度。当我们谈到混淆器时,我们说他们的目标是减缓逆向进程。这在某种程度上是有效的。然而,在本例中,我们可以简单地采取一个快捷方式,让二进制文件运行并将其最终有效载荷加载到内存中。这样,我们可以将其转储到一个文件中,以便进一步分析。
Warzone RAT
最终由metal .dll加载到内存中的有效负载是Warzone远程访问木马(RAT)的一个版本。这是一个众所周知的恶意软件操作作为恶意软件服务(MaaS)。它在互联网上是公开的,任何人都可以通过订阅模式访问它。当前的定价如下图所示。
Warzone RAT的当前定价
它为其订户提供以下功能:
Native, independent stubCookies RecoveryRemote DesktopHidden Remote Desktop - HRDPPrivilege Escalation - UAC BypassRemote WebCamPassword RecoveryFile ManagerDownload & ExecuteLive KeyloggerOffline KeyloggerRemote ShellProcess ManagerReverse ProxyAutomatic TasksMass ExecuteSmart UpdaterHRDP WAN Direct ConnectionPersistenceWindows Defender Bypass
WarzoneRAT通常也被称为“Ave_Maria Stealer”,因为下图所示的字符串出现在二进制文件中。
Ave_Maria Stealer名称来自于二进制文件中的这个误导性字符串
嵌入到GitHub的链接没有提供任何有用的东西,这可能只是误导逆向的另一种方式。
Warzone根据Windows版本提供多种升级权限的方法。其中一个是在同一个二进制文件中实现的,另一个作为WM_DSP资源添加到二进制文件中。如果需要,这将在运行时加载并执行。
可以在资源中找到一个特权升级漏洞
为了躲避防病毒软件,Warzone试图将自己添加到Windows Defender的排除列表中,如下图所示。
Warzone将自己添加到防病毒排除列表中
为了建立持久性,它还将自身复制到以下路径:
C:\Users\Admin\Documents\ Adobe5151.exe
Warzone还使用与其指挥控制服务器的加密通信。过去,加密的密码/密钥是字符串' warzone160\x00 '。在此示例中,它已更改为字符串“nevergonnagiveyouup”。所以,受害者在不知不觉的情况下被人用人力推倒。
使用新密码进行加密
通过动态分析,C2服务器的地址为171.22.30.72:5151。在我们的内部系统中查找这个IP和端口号,如下图所示。从这张图中我们可以看到,这场特别的攻击活动早在2022年6月20日就开始了。
访问地址171.22.30.72:5151
可以看出,攻击者用一封写得很好的虚假政府邮件作为诱饵,执行所附的恶意软件。这种诱惑是经过深思熟虑的,因为它与匈牙利所有使用在线管理门户的人都相关。
嵌入式.NET二进制文件的russian yoshka doll具有越来越复杂的混淆功能,支持攻击者越来越依赖现代混淆技术的趋势。这将导致逆向工程师不得不投入更多的时间来清除和分析恶意软件。使用Warzone RAT作为最终有效载荷也支持了攻击者对MaaS服务日益增长的依赖。我们在勒索软件样本中看到了类似的趋势,勒索软件即服务提供商越来越受欢迎。
如上所述,该活动的最后一个有效载荷Warzone RAT是通过一系列混淆的.NET二进制文件部署的。每个阶段都从二进制文件中的某个位置加载下一个阶段,对其进行解码,将其加载到内存中,并调用一个函数将控制流传递给下一个阶段。这样的多阶段加载程序可能会使动态分析变得困难,因为每次重新启动恶意软件样本时,在不同的阶段进行导航都会很困难。为了避免这个问题,我们从各个阶段创建了独立的可执行文件,以实现更高效的调试。这就是我们将在下面讨论的。
下图显示了Warzone RAT在这一特定攻击中的部署链。钓鱼电子邮件包含一个zip文件。该zip文件包含下图所示的二进制文件。
拆封过程
一旦上一步被执行,它就加载下一步,KeysNormalize.dll一个解压缩到内存中的.NET动态链接库(DLL)。它通过调用它的一个函数(sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY())来运行。这篇文章讨论了如何使用调试恢复。一种方法是使用dnspy作为调试器从内存中转储KeysNormalize.dll。它被一种叫做SmartAssembly的混淆工具混淆了。
要了解第三阶段是什么(Metal.dll)并将其转储到文件中,我们需要能够调试KeysNormalize.dll。但在此之前,我们还面临以下挑战:
我们如何独立于最初解包并在内存中运行它的可执行文件运行KeysNormalize.dll ?
我们如何为KeysNormalize.dll创建一个环境,让它可以释放下一个阶段,就像在原始恶意软件中那样?
方案1:独立运行KeysNormalize.dll
因为这不是一个.exe文件,我们不能直接双击它来运行。此外,原始的.exe文件调用来自KeysNormalize.dll的特定函数,因此我们还必须确保在运行该DLL时调用相同的函数。
有多种方法可以做到这一点。在这种情况下,对我有用的是用c#创建一个包装器程序,我在其中导入keysnormize . DLL作为一个正常的DLL,并简单地调用sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY()函数。如果你是一个.NET/C#开发人员,这是非常容易的,而我不是,但如果你不经常这样做,这可能会很有挑战性。
设置Visual Studio
首先,让我们启动Visual Studio并创建一个新的C#控制台应用程序(.NET Framework)项目,然后选择.NET 4.7.2版本。我们可以调用这个项目dll_wrapper。默认情况下,它加载一个空类。但我们可以将其更改为下图所示的代码。
等待击键的基本程序
此代码将无限期等待按键,然后不执行任何操作。将此添加到代码中的原因是我们无法在调试器中提前添加断点。这样,我们可以在程序等待按键时中断执行,然后在需要时添加断点。
导入KeysNormalize.dll
下一步是在项目中包含KeysNormalize.dll。首先,我们将DLL复制到项目文件夹中。
将KeysNormalize.dll复制到项目文件夹中
我们还需要添加对KeysNormalize.dll的引用,这可以在Project->Add Project Reference->Browse->Choose the KeysNormalize.dll下完成。KeysNormalize现在应该出现在SolutionExplorer的References下,如下图所示。
将对DLL的引用添加到项目中
现在我们应该可以开始在项目中使用KeysNormalize.dll了。我们需要调用以下函数(我们从对原始二进制文件的分析中了解到这一点,这里不讨论):
sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY("4F515364", "746771", "BattleshipLiteLibrary");
为此,我们首先需要导入sk41Ua2AFu5PANMKit,这是Program.cs中KeysNormalize中的命名空间。接下来,我们将上面的函数调用添加到按键循环之后的代码中,如下图所示。
导入库并调用目标函数
如果运行此程序,则表示正在执行恶意负载,因此只能在隔离的安全系统上运行。
我们现在可以构建一个x86版本的二进制文件。如果我们运行该程序,无论是在Visual Studio中还是单独运行,它都会崩溃并抛出异常,如下图所示。
未找到资源,导致异常
从错误消息中,我们看到没有找到BattleshipLiteLibrary.Properties.Resources.resources。该资源存在于第一阶段二进制文件“Uj bejelentkezEsi adatai·pdf.exe”或“iANO”中。
iANO二进制文件中的资源
这很有趣,因为这意味着尽管KeysNormalize是一个独立的DLL,但它不能单独工作。
方案2:创建BattleshipLiteLibrary.Properties.Resources.resources
为了克服资源问题,我们需要满足KeysNormalize.dll的需求,并创建一个名为BattleshipLiteLibrary.Properties.Resources.resources的资源。这并不像看上去那么简单。资源名的构建方式如下:
我们需要创建一个名为BattleshipLiteLibrary.Property.Resources.Resources的资源。因此名称空间必须是BattleshipLiteLibrary。它还需要位于Properties文件夹中,并且必须名为Resources.Resources。
要获取资源内容,我们转到dnspy,右键点击资源,然后选择Raw Save battleshiplitelibrary .Properties. Resources.resources。我们需要将其保存在dll_wrapper的Properties文件夹下的Resources.Resources。
从dnspy保存资源
要将此文件添加到项目中,请右键点击SolutionExplorer中的Properties,然后选择 Add/Existing Item 。选择Resources.resources 文件然后点击“确定”。
向项目添加资源文件
最后一步是将项目的名称空间更改为BattleshipLiteLibrary,以便在KeysNormalize查找资源名称时资源名称是正确的。这可以分两步完成:
1. 双击解决方案资源管理器中的属性,并将默认名称空间更改为BattleshipLiteLibrary,如下图所示。
更改默认命名空间
2. 右键单击Program.cs中的名称空间,选择Rename,并将其更改为BattleshipLiteLibrary,如下图所示。
更改命名空间
这两个步骤应该会更改项目中的所有名称空间。有了这个资源,我们可以构建一个新的x86发行版二进制文件。
转储下一阶段
使KeysNormalize.dll运行的原因是为了有效地调试它并转储下一阶段。
这可以在dnspy中完成。因此,让我们在dnspy中加载dll_wrapper.exe,并在对abiJPmfBfTL6iLfmaW.Y5tFvU8EY()函数的调用中放置一个断点,如下图所示。
向KeysNormalize调用中添加断点
在启动调试器并按下请求时的一个键之后,我们碰到了断点。这样,我们可以点击“Step into”,这也将使dnspy反编译KeysNormalize.dll,允许我们调试二进制文件。
KeysNormalize从资源加载数据、转换数据并调用函数
查看下图的代码后,我们可以看到以下内容:
第76行调用以位图形式加载资源的函数;
该位图被加载到数组中,并执行一些转换;
第83行调用将array作为Assembly对象加载的函数,这意味着数组可能包含下一个阶段;
第84行调用将调用加载的Assembly对象中的一个函数的函数,并通过该函数将执行传递到第93行中的下一个阶段;
现在我们知道可以在第83行转储数组,并找出在第93行调用了哪个函数。
下图显示了内存中的数组变量。它包含一个PE文件。这将是Metal.dll,这是攻击的下一个阶段。
array包含一个PE文件
下图显示了包含在加载的Assembly对象中调用的函数名称的ethodInfo变量。函数名为“OwbdG5aNVQQYu6X20i.o9pVsMvoTr75y5TrkE.V4j9c6YCwC()”
MethodInfo包含被调用函数的名称
现在,为了继续分析,我们需要查看转储的Metal.dll中的这个函数,但这不在本文讨论的范围。
总结
本文介绍了如何创建自定义.NET程序来帮助调试直接在内存中加载和调用的DLL。我们还研究了如何向程序中添加资源以满足调试二进制文件的要求。最后,我们调试了目标DLL以转储下一阶段的二进制文件,并找出哪个函数是它的攻击开始处。
参考及来源:https://www.fortinet.com/blog/threat-research/fake-hungarian-government-email-drops-warzone-rat
https://www.fortinet.com/blog/threat-research/debugging-net-malware-in-a-multi-stage-malware-deployment