Nativedump-仅使用本机API通过手工制作Minidump文件(无MinidumpWritedUmp!)来转储LSASS!

Nativedump-仅使用本机API通过手工制作Minidump文件(无MinidumpWritedUmp!)来转储LSASS!

Nativedump仅使用本机API通过手工制作Minidump文件无MinidumpWritedUmp来转储LSASS-1.png

NativedUmp允许仅使用NTAPIS生成小型文件,仅使用Mimikatz或Pypykatz(SystemInInfo,Modulelist和Memory64List流)来解析的流式文件。
Nativedump仅使用本机API通过手工制作Minidump文件无MinidumpWritedUmp来转储LSASS-2.png

ntopenprocesstoken和ntadjustprivilegetoken获得“ sedebugprivilege”特权rtlgetversion以获取操作系统版本的详细信息(主要版本,次要版本和构建编号)。这对于SystemInfo流ntqueryInformationProcess和ntreadVirtualMemory才能获取LSASRV.DLL地址是必不可少的。这是模块流ntopenprocess为LSASS Process NtqueryVirtualMemory和NtreadVirtualMemory旋转循环并转储所有可能的模块,并倾倒所有可能的模块,并倾倒所有可能的模块。同时,它填充了存储器64list流usage:
nativedump.exe [dump_file]默认文件名是'proc_.dmp':
Nativedump仅使用本机API通过手工制作Minidump文件无MinidumpWritedUmp来转储LSASS-1.png

该工具已针对Windows 10和11设备进行了测试,该设备具有最常见的安全解决方案(Microsoft Defender的端点,CrowdStrike .),并且目前尚未被发现。但是,如果系统中启用了PPL,则无效。
该技术的一些好处是:-它不使用众所周知的dbghelp!minidumpWritedump函数- 它仅使用ntdll.dll的函数,因此可以通过重新映射库来绕过API挂钩- 微型文件不必写入磁盘,您可以将其bytes bytes(Encoded或Encormented Machine)传输到远程计算机上)
该项目目前有三个分支
ntdlloverwrite -oftrrite ntdll.dll的'.text'部分,使用磁盘上的dll文件中的干净版本
委托-Drite ntdll.dll +动态函数分辨率+字符串加密使用AES + XOR编码
远程- 覆盖ntdll.dll +动态函数分辨率+带有AES +将文件发送到远程计算机+ XOR编码的字符串加密

Technique in detail: Creating a minimal Minidump file​

在阅读微型未证明的结构后,其结构可求和到:
header:信息,例如签名('mdmp'),流目录的位置以及每个流的流量流目录:一个条目,其中包含每个流中的类型,大小和位置,每个流中的每个流中的每个流中的每个流中的总尺寸和位置,每个流都包含与过程的不同信息,并且可以从每个流程中读取其自身格式的区域3333333333333333333333333333333
Nativedump仅使用本机API通过手工制作Minidump文件无MinidumpWritedUmp来转储LSASS-3.png

我创建了一个解析工具,可以有用: MinidumPlasser。
我们将专注于创建一个有效的文件,仅具有标题,流目录的必要值以及由Mimikatz/pypykatz: SystemInfo,Modemulelist和Memory64List流对小型文件解析所需的仅有的3个流。

A. Header​

标题是一个32字节结构,可以在C#AS:中定义
公共结构小型铅
{
公共UINT签名;
公共Ushort版本;
公共USHORT实施者;
公共ushort numberofstreams;
公共UINT StreamDirectoryRva;
公共UINT校验和
公共intptr Timedatamtamp;
} The required values are: - Signature: Fixed value0x504d44d ('MDMP' string) - Version: Fixed value0xa793 (Microsoft constant MINIDUMP_VERSION) - NumberOfStreams: Fixed value 3, the three Streams required for the file - StreamDirectoryRVA: Fixed value0x20 or 32 bytes, the size of the标题

B. Stream Directory​

流目录中的每个条目是一个12字形结构,因此具有3个条目的大小为36字节。条目的C#结构定义IS:
公共结构MinidumpStreamDirectoryEntry
{
公共UINT流型;
公共UINT尺寸;
公共UINT位置;
}字段'streamType'表示流的类型作为整数或ID,其中一些最相关的IS:
ID流类型0x00 UNUSESTREAM0x01保留stream00x02 revervedStream10x03 threadListStream0x04 ModuleListStream0x05 MemoryListStream0x06 extceptionsTream0x07 SystemInfoStream0x07 HandleDataStream0x0D FunctionTableStream0x0E UnloadedModuleListStream0x0F MiscInfoStream0x10 MemoryInfoListStream0x11 ThreadInfoListStream0x12 HandleOperationListStream0x13 TokenStream0x16 HandleOperationListStream

C. SystemInformation Stream​

First stream is a SystemInformation Stream, with ID 7. The size is 56个字节,并将位于流目录之后的偏移68(0x44)。它的C#定义IS:
公共结构SystemInformationsTream
{
公共USHORT处理学结构;
公共ushort processorlevel;
公共ushort加工审理;
公共字节编号流程;
公共字节producttype;
公共UINT Majorversion;
公共UINT次要转换;
公共UINT buildnumber;
公共UINT PlatformID;
公共Uint Unknownfield1;
公共Uint Unknownfield2;
公共INTPTR处理器;
公共Intptr ProcessorFeatures2;
公共Uint Unknownfield3;
公共Unkning Fieldfield14;
公共字节Unknownfield15;
}所需的值为: -ProcessOrarchitecture: 9用于64位,为32位Windows系统- 主要版本,次要版本和BuildNumber:硬编码或通过kernel32!getVersionex!

D. ModuleList Stream​

第二流是一个模块化流,具有ID 4。它位于系统信息信息流之后的Offset 124(0x7C),它也将具有112个字节的固定尺寸,因为它将具有单个模块的条目,即单个模块,唯一需要正确的一个模块。
该流的典型结构是一个4字节值,包含条目数量,然后是每个模块的108字节条目3:
公共结构调节流程
{
公共UINT编号模块;
公共模块[]模块;
}只有一个,它被简化为:
公共结构调节流程
{
公共UINT编号模块;
公共intptr baseaddress;
公共UINT尺寸;
公共Uint Unknownfield1;
公共UINT时间戳;
公共Uint Pointername;
public intptr unknownfield2;
public int intptr unknownfield3;
公共intptr unknownfield4;
public int intptr unknownfield5;
公共intptr unknownfield6;
公共intptr unknownfield7;
public int intptr unknownfield8;
公共intptr unknownfield9;
公共intptr unknownfield10;
公共intptr unknownfield11;
}所需的值为: -numberOfstreams:固定值1-使用psapi!getModulebasename或Ntdll!ntqueryInformationProcess和ntdll! 4096字节(0x1000),其他库的.TEXT部分-Pointertoname:'c: \ Windows \ windows \ system32 \ lsasrv.dll'字符串,位于流本身本身at offset 236(0xec)之后

E. Memory64List Stream​

第三流是Memory64List流,具有ID 9。它位于Offset 298(0x12a)之后,在模块流式流和Unicode字符串之后,其大小取决于模块的数量。
公共结构内存64ListStream
{
公共乌隆数字;
公共uint memoryRegionsBaseadDress;
public Memory64Info [] MemoryInfoentries;
}每个模块条目是16个Bytes结构:
公共结构内存64Info
{
公共INTPTR地址;
公共intptr尺寸;
}所需的值为: -numberOfentries:内存区域数,在循环内存区域后获得- 内存baseaddress:内存区域开始的位置,在添加所有16 bytes内存条目的大小后,计算了每个有效区域的大小,在添加所有有效区域后,计算了每个有效区域的大小。

F. Looping memory regions​

有前提条件可以循环lsass.exe过程的内存区域,该过程只能使用NTAPIS:解决
获得“ Sedebugprivilege”许可。我们将使用ntdll!ntopenprocesstoken,ntdll!ntadjustprivilegemoken,而不是典型的Advapi!OpenProcessToken,Advapi!lookupprivilegevalue和advapi!aDjittokePrivilege,而不是ntdll!例如,使用ntdll!ntgetNextProcess循环所有进程,使用ntdll!ntqueryInformationProcess获取PEB地址,并使用ntdll!ntreadvirtualmemory读取processParameters中的imagePathName字段。为了避免过度复杂的POC,我们将使用.NET的Process.getProcessesbyName()打开一个过程句柄。使用ntdll!openprocess与权限process_query_information(0x0400)一起检索过程信息和process_vm_read(0x0010)以读取使用此过程的内存字节,可以通过调用: -ntddll! region - If the memory protection is not PAGE_NOACCESS (0x01) and the memory state is MEM_COMMIT (0x1000), meaning it is accessible and committed, the base address and size populates one entry of the Memory64List stream and bytes can be added to the file - If the base address equals lsasrv.dll base address, it is used to calculate the size of lsasrv.dll in memory - ntdll!ntreadvirtualmemory:在memory64list流之后,将该区域的字节添加到小型文件

G. Creating Minidump file​

之后,我们拥有创建小型文件所需的一切。我们可以在本地创建一个文件或将字节发送到远程计算机,并可能在以前编码或加密字节。其中一些可能性是在代表分支中编码的,在该分支机构中,可以在本地编码XOR的文件,然后在远程分支中编码文件,该文件可以在发送到远程计算机之前使用XOR编码。
 
后退
顶部