在GitHub上看到了一个利用SilentProcessExit机制dump内存的项目,于是学习了一下,于是今天来聊一聊利用SilentProcessExit机制dump内存,首先我们知道,在程序崩溃时或者系统崩溃时会产生崩溃后的文件。比如之前就有一篇文章,介绍的就是利用蓝屏崩溃来绕过卡巴斯基dump lsass进程(https://www.mrwu.red/web/2000.html),而在win7之后,windows引入一些进程退出的相关机制,即Selftermination的ExitProcess.与Crossprocesstermination的TerminateProcess.而我们今天所说的则是Silent Process Exit,即静默退出。而这种调试技术,可以派生 werfault.exe进程,可以用来运行任意程序或者也可以用来转存任意进程的内存文件或弹出窗口。若派生新进程的话其进程树如下:
而利用这种机制,我们便可以用它来转储任意进程的内存,比如对我们比较有用的lsass进程。在这之前我们来看看如果想要做这些操作需要如何实现。由于该功能默认不开启,我们需要对注册表进行操作,来开启该功能,主要的注册表项为:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Option
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit
首先就是第一个注册表,根据MSDN上所说,我们需要设置一个指定进程的名字,并开启 silent process exit monitoring,即200.
代码中也有相关体现:
另外就是第二个注册表,这个主要是设置dump内存的一些细节问题,比如dump的位置、崩溃后操作的类型,这类选择的是LOCAL_DUMP,即0x2也就是为导致终止的进程和终止的进程创建一个转储文件,而需要注意的是
我们这里需要的是MiniDumpWithFullMemory,其都定义在MINIDUMP_TYPE之中,其结构体如下:
ypedef enum _MINIDUMP_TYPE {
MiniDumpNormal,
MiniDumpWithDataSegs,
MiniDumpWithFullMemory,
MiniDumpWithHandleData,
MiniDumpFilterMemory,
MiniDumpScanMemory,
MiniDumpWithUnloadedModules,
MiniDumpWithIndirectlyReferencedMemory,
MiniDumpFilterModulePaths,
MiniDumpWithProcessThreadData,
MiniDumpWithPrivateReadWriteMemory,
MiniDumpWithoutOptionalData,
MiniDumpWithFullMemoryInfo,
MiniDumpWithThreadInfo,
MiniDumpWithCodeSegs,
MiniDumpWithoutAuxiliaryState,
MiniDumpWithFullAuxiliaryState,
MiniDumpWithPrivateWriteCopyMemory,
MiniDumpIgnoreInaccessibleMemory,
MiniDumpWithTokenInformation,
MiniDumpWithModuleHeaders,
MiniDumpFilterTriage,
MiniDumpWithAvxXStateContext,
MiniDumpWithIptTrace,
MiniDumpScanInaccessiblePartialPages,
MiniDumpValidTypeFlags
} MINIDUMP_TYPE;
而MiniDumpWithFullMemory对应的则是0x2。代码的整个构造函数则都在实现上述的注册表操作:
下面就是使进程崩溃了,而lsass进程为系统进程,强制关闭,系统则会蓝屏。而这个时候我们就用到了RtlReportSilentProcessExit这个api,该API将与Windows错误报告服务(WerSvcGroup下的WerSvc)通信,告诉服务该进程正在执行静默退出。然后,WER服务将启动WerFault.exe,该文件将转储现有进程。值得注意的是,调用此API不会导致进程退出。其定义如下:
NTSTATUS (NTAPI * RtlReportSilentProcessExit )(
_In_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);
那么到此为止整个过程我们就理清了,为例方便理解,我这里画了个图,方便大家理解。
作者的代码中,提供了两种方法来实现崩溃,一种是直接调用RtlReportSilentProcessExit,而另一种则是使用CreateRemoteThread()来进行实现,后来在测试过程中发现,第二种并不能成功的dump,于是我对代码进行了简单修改,使其可以正常dump,最后的代码已上传至Github。
https://github.com/lengjibo/RedTeamTools/tree/master/windows/LsassSilentProcessExit
演示过程如下。
而该方法的字符串问题,可以用我之前写的C++库来实现。
而该方法也支持权限维持,就不展开来说了。
参考文章:
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/registry-entries-for-silent-process-exit
https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess
https://www.deepinstinct.com/2021/02/16/lsass-memory-dumps-are-stealthier-than-ever-before-part-2/
https://github.com/deepinstinct/LsassSilentProcessExit
https://www.hexacorn.com/blog/2019/09/19/silentprocessexit-quick-look-under-the-hood/
https://docs.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-createremotethread
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms686736(v=vs.85)
https://scorpiosoftware.net/2018/09/21/silent-process-exit-is-it-really/
https://www.hexacorn.com/blog/category/research-fails/
https://stackoverflow.com/questions/58561951/returning-from-exe-entry-point-does-not-terminate-the-process-on-windows-10
https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
▼
更多精彩推荐,请关注我们
▼