1. 逆向工程简介
逆向工程 (RE) 是将某物分解以了解其功能的过程。在网络安全中,逆向工程用于分析应用程序(二进制文件)的运行方式。这可用于确定应用程序是否是恶意的或是否存在任何安全漏洞。
例如,网络安全分析师对攻击者分发的恶意应用程序进行逆向工程,以了解是否有任何可归因的指标将二进制文件与攻击者联系起来,以及任何可能的防御恶意二进制文件的方法。一个著名的例子是2017 年 5 月的WannaCry勒索软件。安全研究员Marcus Hutchins对勒索软件应用程序进行了逆向工程,并发现了应用程序中的一项特定功能,如果特定域已注册并可用,恶意软件就不会运行。
随后,Marcus 注册了这个域名,阻止了全球性的 WannaCry 攻击。这只是逆向工程在网络安全防御中运用的众多著名案例之一。
2. 二进制文件
在计算领域,二进制文件是从源代码编译而来的文件。例如,在计算机上启动可执行文件时,会运行二进制文件。在某个时间点,此应用程序可能是用 C# 等编程语言编写的。然后对其进行编译,编译器将代码转换为机器指令。
二进制文件具有特定的结构,具体取决于它们设计用于运行的操作系统。例如,Windows 二进制文件遵循可移植可执行 (PE) 结构,而在Linux上,二进制文件遵循可执行和可链接格式 (ELF)。这就是为什么您无法在 MacOS 上运行.exe文件的原因。话虽如此,所有二进制文件至少包含:
代码部分:此部分包含CPU将执行的指令
数据部分:此部分包含变量、资源(图像、其他数据)等信息
导入/导出表:这些表引用二进制文件使用(导入)或导出的其他库。二进制文件通常依赖库来执行功能。例如,与 Windows API交互以操作文件
今天的任务中的二进制文件遵循PE结构。整个任务将解释此结构。
3. 反汇编与反编译
对二进制文件进行逆向工程时,您将使用两种主要技术。本任务部分将向您介绍反汇编和反编译,解释它们的主要区别及其优缺点。
反汇编二进制文件会显示二进制文件将执行的低级机器指令(您可能将其称为汇编)。由于输出是翻译后的机器指令,因此您可以详细了解二进制文件在哪个阶段将如何与系统交互。IDA、Ghidra和 GDB 等工具可以做到这一点。
然而,反编译会将二进制文件转换为高级代码,例如 C++、C# 等,使其更易于阅读。但是,这种转换通常会丢失变量名称等信息。如果您想从高层次了解应用程序的流程,这种对二进制文件进行逆向工程的方法非常有用。
在某些特定情况下,您会选择一种方法而不是另一种方法。例如,反编译有时是基于您使用的工具的"最佳猜测",并不提供实际的完整源代码。
4. 多阶段二进制
网络安全的最新趋势是,攻击者越来越多地在攻击活动中使用所谓的"多阶段二进制文件"------尤其是恶意软件。这些攻击涉及使用负责不同操作的多个二进制文件,而不是一个执行整个攻击的二进制文件。通常,涉及多个二进制文件的攻击将如下所示:
第 1 阶段 - Dropper:此二进制文件通常是一个轻量级的基本二进制文件,负责枚举操作系统以查看有效负载是否有效等操作。一旦验证了某些条件,二进制文件就会从攻击者的基础设施下载第二个更恶意的二进制文件。
第 2 阶段 - 有效载荷:此二进制文件是攻击的"核心"。例如,在发生勒索软件时,此有效载荷将加密并泄露数据。
经验丰富的攻击者可能会进一步将攻击链(例如横向移动)的行为拆分为其他二进制文件。使用多个阶段有助于逃避检测并使分析过程更加困难。
例如,与执行恶意操作(例如加密)的完整二进制文件相比,较小的、更"无害"的初始二进制文件更有可能逃避电子邮件过滤检测。此外,将这些功能拆分为多个阶段可让攻击者获得更大的控制权(即,仅在满足时间等条件后下载特定阶段)。
下图显示了涉及多个阶段二进制文件的攻击可能是什么样子。
5. 使用 .NET
对于今天的任务,您将使用反编译器 ILSpy 对两个 .NET 二进制文件进行逆向工程。您可以按照下面的演练,使用名为的示例应用程序进行逆向工程demo.exe。然后,您将在本任务结束时自行逆向应用程序。
在分析目标之前,我们需要学习并找到一种方法来识别原始二进制文件、修改它或将其用作证据。此外,对我们正在处理的文件有一个大致的了解也是一种很好的做法,这样我们就可以选择所需的适当工具。
让我们首先通过右键单击名为demo 的文件并单击来导航到机器桌面上demoProperties文件夹中的文件位置。
我们可以观察到该文件的扩展名是.exe,表明它是一个 Windows 可执行文件。
由于它是一个 Windows 文件,我们将使用PEStudio,这是一款旨在调查潜在恶意文件并从中提取信息而无需执行的软件。这将帮助我们专注于调查的静态分析方面。 让我们从任务栏打开 PEstudio,然后单击 文件>打开demo.exe并选择位于的文件,C:\Users\Administrator\Desktop\demo\demo.exe如下所示。
如下所示,PEStudio 将显示有关该文件的信息,因此让我们开始列举我们可以从中获得的一些最重要的方面。使用左侧面板,我们可以浏览不同的部分,这些部分将共享有关该文件的不同类型信息。在打开文件时显示的常规信息输出中,我们可以看到SHA-256形式的文件哈希值、体系结构类型(在本例中为x64)、文件类型以及用于编译可执行文件的语言的签名(在本例中为使用 C# 语言的. NET 框架) 。
让我们关注一些我们可以获得的关键数据。首先,如果我们想要识别文件并提供其被更改的证据,我们需要记下文件的 SHA-256 哈希值(如上所述),以及 PE 文件上每个部分的哈希值。PE 代表可移植可执行文件,它是 Windows 可执行文件的排列格式;您可以在此处了解更多信息。
这些部分代表了 PE 格式的 Windows 可执行文件的不同内容的内存空间。我们可以计算这些部分的哈希值,以便正确识别可执行文件。这次我们将重点关注两个哈希值:一个来自.text部分,它是包含可执行代码的文件部分;此部分通常标记为已读和可执行,因此在复制文件时不应对其进行任何更改。我们可以在下面的屏幕截图中看到它们:
我们可以使用另一个重要部分来获取有关二进制文件的信息,即"指标"部分。此部分告诉我们有关二进制文件的潜在指标,例如 URL 或其他可疑属性。
上面的截图显示了文件中的几个字符串,如文件名、URL 和函数名。根据文件的执行流程,这可能非常重要。此外,寻找 IP 地址、URL 和加密钱包等人工信息可以"快速"收集一些识别情报。我们将在下一节中了解这一点。
现在我们已经掌握了有关正在调查的文件的信息,让我们尝试了解可执行文件正在做什么。我们需要了解它的流程。如果我们尝试通过打开文件来读取它,我们将无法做到这一点,因为它是二进制格式。在上一节中,我们了解到该文件是使用.NET该语言使用的框架编译的;我们可以使用ILSpyC#等反编译工具将二进制代码反编译为 C# 。
此工具将反编译代码,为我们提供可读信息,我们可以使用这些信息来确定执行流程。让我们首先从任务栏打开 ILSpy,然后单击File > Open,然后导航到C:\Users\Administrator\Desktop\demo 并选择文件demo.exe。该工具ILSpy可能需要长达 30 秒才能显示在屏幕上。
从上面我们可以看出,左侧面板包含框架使用的库,而实际的反编译代码位于文件名为demo的部分。我们点击它展开,看看它包含什么。
如上图所示,ILSpy 可以提供很多信息,例如元数据和引用。但是,实际显示的内容显示在括号符号 {} 上,在本例中,在 下DemoBinary > Program > Main,这实际上是可执行文件的 Main 函数。现在我们可以访问二进制文件上运行的代码,让我们对其进行分析。
private static void Main(string[] args)
{
Console.WriteLine("Hello THM DEMO Binary");
Thread.Sleep(5000);
string address = "http://10.10.10.10/img/tryhackme_connect.png";
string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "thm-demo.png");
using (WebClient webClient = new WebClient())
{
try
{
Console.WriteLine("Downloading file...");
webClient.DownloadFile(address, text);
Console.WriteLine("File downloaded to: " + text);
Process.Start(new ProcessStartInfo(text)
{
UseShellExecute = true
});
Console.WriteLine("Image opened successfully.");
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
}
Console.WriteLine("Bye Bye leaving Demo Binary");
Thread.Sleep(5000);
}
上面的代码显示了 main 函数及其代码。我们可以观察到,它首先使用Console.Writeline 方法将消息"Hello THM DEMO Binary"打印到屏幕上。
Console.WriteLine("Hello THM DEMO Binary");
然后它使用Sleep方法等待 5 秒。
Thread.Sleep(5000);
然后,它将一个值分配给两个字符串变量: address 和 text ,第一个变量是访问 PNG 文件的 URL ,第二个变量是用户桌面上名为thm-demo.png 的文件名。
string address = "http://10.10.10.10/img/tryhackme_connect.png";
string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "thm-demo.png");
然后,它将尝试连接到地址变量上的 URL,并使用WebClient 类将内容保存到桌面上的文件中,然后它将使用Process 类 和Start 方法执行分配给文本变量的下载文件路径,如下所示。
using (WebClient webClient = new WebClient())
{
try
{
Console.WriteLine("Downloading file...");
webClient.DownloadFile(address, text);
Console.WriteLine("File downloaded to: " + text);
Process.Start(new ProcessStartInfo(text)
{
UseShellExecute = true
});
Console.WriteLine("Image opened successfully.");
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
}
最后,它再次向控制台打印消息" Bye Bye,离开THM DEMO Binary ",并使用Sleep方法等待 5 秒钟后再关闭。
Console.WriteLine("By bye leaving THM Demo Binary");
Thread.Sleep(5000);
太棒了!我们现在明白二进制文件在做什么了。它将从 URL下载一个 PNG 文件到用户的桌面: http://10.10.10.10/img/tryhackme_connect.png。让我们执行该文件,看看这是否属实。 二进制文件启动后,等待文本" "出现,然后按下载文件。Hello THM DEMO BinaryEnter
注意: 我们仅执行二进制文件,因为我们处于沙盒环境中;不建议在主机上执行未知二进制文件。
执行文件后,我们可以观察到它已下载到桌面,并且消息按预期打印到屏幕上。此外,使用 PNG Paint的默认应用程序执行并打开下载的文件。太好了,我们成功逆向了 代码流程。