NativeDump 允许仅使用 NTAPI 转储 lsass 进程,生成一个仅包含 Mimikatz 或 Pypykatz 等工具解析所需流(SystemInfo、ModuleList 和 Memory64List 流)的 Minidump 文件。

该程序有一个可选参数用于输出文件,默认文件名为“proc_<PID>.dmp”:
NativeDump.exe [DUMP_FILE]

该工具已在最新版本的 Windows 上经过常见安全解决方案(Microsoft Defender for Endpoints、CrowdStrike...)的测试,运行良好,但隐蔽性取决于你选择的“风味”:使用不常见的语言并自定义二进制文件可获得最佳效果!但是,如果启用了 PPL 或 PEB 结构不可读,则无法运行。更新:现在可以在不读取 PEB 的情况下执行程序,请查看 peb-unreadable 分支 :)
此技术的一些优点包括:
你可以找到不同“风味”(或语言)的项目:
main - .NET 基本实现(此分支)
python-flavour - Python 实现,包含 3 种 ntdll.dll 覆盖方法 + 外泄到远程机器
golang-flavour - Golang 实现,包含 3 种 ntdll.dll 覆盖方法 + 外泄到远程机器
c-flavour - C/C++ 实现,包含 3 种 ntdll.dll 覆盖方法
bof-flavour - BOF 文件,包含 3 种 ntdll.dll 覆盖方法
rust-flavour - Rust 实现,作者 @safedv
crystal-flavour - Crystal 实现,具有 ntdll.dll 覆盖能力
nim-flavour - Nim 实现,具有 ntdll.dll 覆盖能力
其他有趣的 .NET 分支:
remote - 外泄到远程机器 + 3 种 ntdll.dll 覆盖方法 + 动态函数解析 + 字符串 AES 加密 + XOR 编码 Minidump 内容
all-modules - 获取所有模块的信息(不仅仅是 lsasrv.dll)
peb-unreadable - 不读取 lsass PEB 结构的实现 + 3 种 ntdll.dll 覆盖方法
在阅读了 Minidump 未文档化的结构后,其结构可以总结为:

我创建了一个解析工具,可能会有所帮助:MinidumpParser。我们将专注于创建一个有效的文件,仅包含头部、流目录以及 Mimikatz/Pypykatz 解析 Minidump 文件所需的仅三个流:SystemInfo、ModuleList 和 Memory64List 流所需的值。
头部是一个 32 字节的结构,在 C# 中可以定义为:
public struct MinidumpHeader
{
public uint Signature;
public ushort Version;
public ushort ImplementationVersion;
public ushort NumberOfStreams;
public uint StreamDirectoryRva;
public uint CheckSum;
public IntPtr TimeDateStamp;
}
所需的值是:
流目录中的每个条目是一个 12 字节的结构,因此有 3 个条目时大小为 36 字节。C# 中条目的结构定义为:
public struct MinidumpStreamDirectoryEntry
{
public uint StreamType;
public uint Size;
public uint Location;
}
字段“StreamType”表示流的类型(整数或 ID),一些最相关的如下:
第一个流是 SystemInformation 流,ID 为 7。大小为 56 字节,位于偏移量 68(0x44),即流目录之后。其 C# 定义为:
public struct SystemInformationStream
{
public ushort ProcessorArchitecture;
public ushort ProcessorLevel;
public ushort ProcessorRevision;
public byte NumberOfProcessors;
public byte ProductType;
public uint MajorVersion;
public uint MinorVersion;
public uint BuildNumber;
public uint PlatformId;
public uint UnknownField1;
public uint UnknownField2;
public IntPtr ProcessorFeatures;
public IntPtr ProcessorFeatures2;
public uint UnknownField3;
public ushort UnknownField14;
public byte UnknownField15;
}
所需的值是:
第二个流是 ModuleList 流,ID 为 4。位于 SystemInformation 流之后偏移量 124(0x7C)处,大小也是固定的,为 112 字节,因为它只包含一个模块的条目,这是解析正确所需的唯一模块:“lsasrv.dll”。
该流的典型结构是一个 4 字节的值(包含条目数量),后面跟着每个模块的 108 字节条目:
public struct ModuleListStream
{
public uint NumberOfModules;
public ModuleInfo[] Modules;
}
由于只有一个模块,它简化为:
public struct ModuleListStream
{
public uint NumberOfModules;
public IntPtr BaseAddress;
public uint Size;
public uint UnknownField1;
public uint Timestamp;
public uint PointerName;
public IntPtr UnknownField2;
public IntPtr UnknownField3;
public IntPtr UnknownField4;
public IntPtr UnknownField5;
public IntPtr UnknownField6;
public IntPtr UnknownField7;
public IntPtr UnknownField8;
public IntPtr UnknownField9;
public IntPtr UnknownField10;
public IntPtr UnknownField11;
}
所需的值是:
第三个流是 Memory64List 流,ID 为 9。位于 ModuleList 流和 Unicode 字符串之后偏移量 298(0x12A)处,其大小取决于模块数量。
public struct Memory64ListStream
{
public ulong NumberOfEntries;
public uint MemoryRegionsBaseAddress;
public Memory64Info[] MemoryInfoEntries;
}
每个模块条目是一个 16 字节的结构:
public struct Memory64Info
{
public IntPtr Address;
public IntPtr Size;
}
所需的值是:
遍历 lsass.exe 进程的内存区域有一些先决条件,这些条件仅使用 NTAPI 即可解决:
有了这些,就可以通过调用以下函数遍历进程内存:
经过前面的步骤,我们已经拥有创建 Minidump 文件所需的一切。我们可以在本地创建一个文件,或者将字节发送到远程机器,并且可以在此之前对字节进行编码或加密。其中一些可能性已在 delegates 分支 中编码实现,该分支中本地创建的文件可以使用 XOR 编码;以及 remote 分支,该分支中文件可以在发送到远程机器之前使用 XOR 编码。
对于避免创建 Minidump 文件的替代方法,请查看 TrickDump:它生成三个 JSON 文件和一个 ZIP 存档,Minidump 在攻击者的机器上重建。这有助于规避那些监控 Minidump 创建或外泄的安全解决方案。
| ID | 流类型 |
|---|
| 0x00 | UnusedStream |
| 0x01 | ReservedStream0 |
| 0x02 | ReservedStream1 |
| 0x03 | ThreadListStream |
| 0x04 | ModuleListStream |
| 0x05 | MemoryListStream |
| 0x06 | ExceptionStream |
| 0x07 | SystemInfoStream |
| 0x08 | ThreadExListStream |
| 0x09 | Memory64ListStream |
| 0x0A | CommentStreamA |
| 0x0B | CommentStreamW |
| 0x0C | HandleDataStream |
| 0x0D | FunctionTableStream |
| 0x0E | UnloadedModuleListStream |
| 0x0F | MiscInfoStream |
| 0x10 | MemoryInfoListStream |
| 0x11 | ThreadInfoListStream |
| 0x12 | HandleOperationListStream |
| 0x13 | TokenStream |
| 0x16 | HandleOperationListStream |