Bypass Cylance Memory Exploise Defense&Script Cntrl

最新漏洞 3个月前 (08-27) 590 人围观 0

Cylance是市场上更加突出的EDR解决方案之一。Cylance强调利用机器智能来遏制恶意行为者损害您的计算机的能力。我们来介绍一下Cylance服务如何实施的具体细节。用户区组件由一系列.NET程序集组成,它们管理Cylance的大部分功能,包括记录所有事件,检测和阻止内存中的恶意活动,以及隔离异常或受感染文件。Cylance还使用一个过滤器驱动程序,负责将内存开发防御库(CyMemDef)注入到每个新进程中。用户级服务通过IOCTL维护与过滤器驱动程序的通信。IOCTL调用可以包括进程创建,内存I / O以及远程或本地线程创建的详细信息。

现在我们简要介绍了Cylance的检测和预防功能,我们将回顾CLR Heap在这个旁路中的作用。在每个托管应用程序中都存在堆。堆包含在应用程序执行期间创建的所有引用对象。这些对象可以是类实例,类成员或字段,并且它们不断被垃圾收集器创建,修改和删除。当CLR需要为新对象分配空间时,它将调用VirtualAlloc来创建由多个对象共享的内存区域。当一个对象被销毁时使用VirtualFree。要了解有关托管堆的更多信息,请看这里

所以在这一点上,我们知道,一旦CylanceSvc启动,它的所有对象都存储在托管堆中。为了方便起见,有一个来自Microsoft的开源项目,允许您遍历堆并查看所有受管对象。ClrMD是一个.NET库,可以作为调试器附加到托管应用程序,并查看堆的内容,以及类实例或方法。要找到起点,我们可以查看服务创建的日志文件。幸运的是,Cylance非常慷慨,并在他们的日志文件中提供了大量的细节。

Cylance日志文件片段

每一行括号内的名称与装配体内的特定类有关。之后,是该类中的特定方法,然后是日志消息。使用这些信息,我们可以返回找到Cylance.Host.MemDef.MemDef类的相应程序集。该类负责定义所有需要警告和/或进程终止的违规内存操作,以及响应从驱动程序发送的违规事件。我们可以通过加载dnSpy中的所有程序集,然后搜索所需的类来查找此类。

dnSpy搜索

在Assembly Explorer窗格中打开此类,您可以看到有一些有趣的类方法。在所有方法之后,将显示特定于MemDef类的事件和字段。对我来说,一个领域是“IsMemDefEnabled”字段。关于dnSpy的一个好处是我们可以分析这个字段,并找到它被分配和读取的位置。

MemDef分析

EventParser

IsEnabledCheck

当接收到事件之前,在处理MemDef消息的任何逻辑之前,会检查是否启用了脚本控制或内存开发防范。如果没有,则跳过所有消息分析逻辑,然后该方法将控制权返回给调用方法。所以我们可以推断,如果我们能够将“IsMemDefEnabled”和“IsScriptControlEnabled”两者设置为false,我们可以绕过任何逻辑来警告恶意活动。一些更积极的政策不仅会警惕这种活动,而且还会终止违规行为。这对过滤器驱动程序没有任何影响。仍然会向服务发送可疑内存操作的邮件。

所以要做到这一点,我们需要满足两个先决条件。

  1. 我们需要在一个更高的上下文中。CylanceSvc进程作为NT AUTHORITY \ SYSTEM执行。
  2. 我们需要有能力写入CylanceSvc进程,并在必要时调整内存权限。

首先,我们扫描CylanceSvc进程的托管堆以找到“Cylance.Host.MemDef.MemDef”对象/类。一旦我们找到这个对象,我们可以获得我们的目标字段的位置。ClrMD程序集包含GetHeap()和Heap.EnumerateObjectAddresses()方法来完成此操作。一旦我们引用了该字段,如果'HasSimpleValue'属性为true,我们可以使用GetFieldValue方法来获取它的当前值。

HasSimpleValue

不幸的是,ClrMD不提供更改字段值的能力。但是,我们可以在内存中获取该字段的地址。一旦我们有了地址,我们可以通过VirtualProtectEx和WriteProcessMemory写出所需的值。注意:该特定字段的内存区域不可写。.NET应用程序中还有其他存储区域具有RWX权限。这是JIT编译器的必需品,因此不需要VirtualProtectEx。

现在,值已被更改,如果内存操作被认为是恶意的,Cylance将简单地忽略任何违规进程。此外,脚本控制防止powershell.exe进程启动。禁用时,powershell.exe将执行,但仍将生成警报。我会留给读者调查如何补救。已经有一些关于操作.NET应用程序的研究。如果你有兴趣,你应该看看@ malwareunicorn的劫持.NET 演讲,以及@ttimzen的研究。@subtee还有一个实用的例子来解锁这里的约束语言模式。

你可能会问你的自我,为什么不用sc.exe CylanceSvc停止?那么这个服务是由过滤器驱动程序支持的。为了使服务停止,司机必须卸载。但是,如果FilterUnloadCallback未注册,则无法卸载驱动程序。因此,服务无法停止。这可能不是Cylance的情况,但仍然是一种可能性。即使注册了FilterUnloadCallback,如果它是非强制卸载,则驱动程序也不会卸载。非强制性卸载来自调用FilterUnload函数或其他内核驱动程序的用户模式应用程序。甚至可以防止强制卸载成功。调用FltRegisterFilter函数时,可以在FLT_REGISTRATION结构中设置一个特殊标志(FLTFL_REGISTRATION_DO_NOT_SUPPORT_SERVICE_STOP),以防止强制卸载。使用sc或net命令时会发生强制卸载。最终,sc或net命令在命令行审核解决方案中受到更多的关注。这个旁路功能可以作为一种更为操纵的方式来消除服务。

最后一点,CyMemDef dll不存在于CylanceSvc进程中。我不知道这是否是监督,或者在这种情况下是否需要例外。

您可以在这里找到PoC的源代码

现在为了快速演示....