接上篇Windows WDM 驱动漏洞挖掘(上)

蓝屏现象

简而言之,我们第一个真正的漏洞示例是微软Azure VFP扩展或vfpext.sys。故事从驱动程序的ioctl调度函数开始。在一些变量初始化之后,它调用一个方法来验证用户模式参数,然后调用一些内部逻辑。

12.png

图12-由Ida Pro反编译的SxStartDeviceIoControl函数,从vfpext.sys的disptachIoctl函数调用

我们真正拥有的是一个简单的代码,它执行以下操作:

从宏iogetcurrenttirpstacklocation (IRP)中获取一个指向CurrentStackLocation的指针;

验证缓冲区长度是否超过0x218;

以安全的方式创建一些Unicode字符串;

通过调用我们不关心的SxFindContextByName来进行查找操作;

问题是驱动程序在任何地方都不会检查给定的 ioctl IRP->AssociatedIrp 是什么。例如,SystemBuffer 是一个有效地址;它假定缓冲区的地址是有效的。

然而,回顾图 4,我们可以假设驱动程序期望获得一个带有TransferType的ioctl代码为METHOD_BUFFER或METHOD_IN_DIRECT或METHOD_OUT_DIRECT,因为它从IRP- bb0 AssociatedIrp.SystemBuffer读取输入缓冲区。

但是,如果它是 METHOD_NEITHER,那么 IRP->AssociatedIrp.SystemBuffer 对 IoManager 没有任何意义,它会将其设置为零,因为它会填充 IRP->Parameters.DeviceIoControl.Type3InputBuffer。

接下来,调用 SxInitUnicodeStringSafe ,我认为它应该是内核方法 RtlInitUnicodeString 的更安全版本;第二个参数是 SystemBuffer+8,即源字符串。

13.png

图13-Ida Pro 反编译的 SxInitUnicodeStringSafe 函数,接收 SystemBuffer,它可以指向无效内存

因此,SystemBuffer地址的地址将是0x10 = (0x0+sizeof(wchar_t *)+8)。因此,在调用RtlStringCbLengthW(顾名思义,它计算长度)时,将使用指向无效地址的系统缓冲区。它包含如下代码:

14.png

图14-这里发生了指针解引用

当 *SystemBuffer 解引用发生时,你解引用了一个无效地址,并且内核不会执行空指针。

15.webp.jpg

图15-只是由漏洞触发的蓝屏

这个漏洞检查只需要两行代码就可被触发:

16.png

图16-导致漏洞检查

在这种情况下,我们的漏洞是不可利用的,除非来自有限用户的 DoS。此漏洞也可能由受限用户和应用程序沙箱中触发,因为对设备没有任何保护。因此,每个人都可以得到一个句柄和BSoD。直到今天,这个漏洞还没有被修复; MSRC 的回应是:“我们已经完成了调查,并确定此报告是一个中等严重性的拒绝服务漏洞,很遗憾,这意味着它不符合我们在安全更新中提供服务的标准。”微软的回答很有趣,因为它不仅仅是一个常规的 DoS,而是一个系统的 DoS。从 CVSS 的角度来看,它应该是 7.3。除此之外,修复非常简单;在盲目使用之前检查ioctl代码,这将导致正确使用IRP的缓冲区。

内存漏洞

在了解了拒绝服务攻击后,我们应该继续讨论一个特殊的、隐秘的漏洞类。信息泄漏是指内核内存泄露给用户模式。它不会触发漏洞检查或任何异常,因此在驱动程序开发的常规管道中很难找到。与常规内存池漏洞相比,你也无法通过驱动程序验证程序找到它。

自Windows Vista发布以来,微软引入了KASLR缓解措施,这使得 Windows 内核开发非常具有挑战性。 KASLR是内核ASLR,它在启动时随机化驱动程序、模块、内核对象的基地址。这样,你就不能像过去那样滥用任意写入原语了。那时,你可以找到一个可以被内核调用的地址,比如HalDispatchTable,然后放置一个恶意的shellcode,可以进行令牌窃取,例如,可以由用户模式进程触发。因此,任意写入足以执行代码,或者你可以解 SMEP 作为记录。

如今,当地址被随机化时,人们不知道在哪里分配 shellcode,因为 HalDispatchTable 是在每次启动时随机化的。

漏洞利用编写者变得更聪明,并且很快就明白你可以调用 NtQuerySystemInformation 或 EnumDeviceDrivers 来获取 ntoskrnl 的基地址。这样,我们就绕过了 KASLR,使任意写入对于 LPE 来说已经足够了。当然,只有当被控制的进程具有中等完整性(大多数进程都具有中等完整性)时,才可以调用这些API;浏览器不是。除此之外,使用 PageEntry 攻击覆盖 HalDisptachTable 是无效的,因为 HVCI 等新的缓解措施仍然不是大多数 Windows 设备上的默认设置。

或者,可以直接从系统进程读取数据。例如,可能会读取完全加载到内存中的 SAM 文件。现在,假设你可以从内存中提取它。在这种情况下,你可能可以破解哈希并找到管理员密码,从而使你可以悄悄地实现完全的权限提升。由于你并没有真正接触磁盘,因此不会触发防攻击。

那么信息泄漏是什么样的呢?它主要以获取某些敏感内核对象的内核指针的形式出现,但它也可能看起来像公开未初始化的内核内存,例如在 RtsPer.sys Realtek 驱动程序中:

17.png

图17-rts_ctrl_dump_mem_log 包含严重的信息泄漏漏洞

乍一看,这里提供的代码似乎很可靠;驱动程序使用 METHOD_BUFFERED(因为它以 00 结尾)来传输数据,所以用户数据不能从它的缓冲区分离出;缓冲区长度是可信的(详见图11和上面的内容)。然而,即使使用METHOD_BUFFERED,它也不能保证代码无漏洞。

查找信息泄漏漏洞的最简单方法是查看返回的数据及其长度。由于我们处理的是 METHOD_BUFFERED,因此返回的数据是通过 SystemBuffer 进行的,并且 IRP->IoStatus.Information 指定了大小(不仅针对此传输类型)。由于IoManager 并没有在输入缓冲区的副本之外初始化系统缓冲区。换句话说,如果 OutputBufferLength > InputBufferLength,则 SystemBuffer 的剩余部分是未初始化的数据。因此,驱动程序编写者的工作是初始化系统缓冲区并返回它的正确长度。

图16中的SystemBuffer没有被初始化为零。我们没有检查输入/输出缓冲区的长度,这是我们完全可以控制的。另外,通过查看else块,我们可以检查漏洞的逻辑:

18.png

图18-不正确的缓冲区大小分配

事实证明,通过进入 else 块,你从内核中得到了 0x107c0 字节长度的内核数据。更准确地说,IoManager 复制了 OutputBufferLength 和 InputBufferLength 之间的增量:

OutBufferLength = 0x107c0,InputBufferLength = 1

因此,我们从System进程的内存空间中返回0x107c0,大约有64k的未初始化数据,允许你读取SAM文件的内容,查找系统的内核基地址以及更多内容。此外,你可以根据需要多次触发此行为,因为它不会引发异常。

漏洞利用代码非常简单,我们唯一担心的是找到设备名称,因为它是一个自动生成的数字,但你可以暴力破解它,因为只有大约 0x200 选项,类似于图 2 中所示的方式。我们的漏洞利用代码可以执行以下操作:

打开 RtsPer.sys 公开的设备的句柄;

分配一个大小为 0x107c0 的缓冲区;

调用 DeviceIoControl;

将内核数据写入文件;

19.png

图19-在 RtsPer.sys 中滥用信息泄漏的简短代码

这只是我们在RealTek 最近修复的此驱动程序中发现的众多漏洞之一。

似乎这些漏洞很容易检测,也相对容易修复,你需要做的就是在 else 块中将 IRP->IoStatus.Information 更改为零。此外,你可以通过改变设备的权限来防止所有这些漏洞,只允许管理用户或以上用户与它交互。

第三类漏洞

我们要研究的第三种类型的漏洞会导致完全权限提升,除非它是从低完整性进程中执行的。在内核中发现的一个更好且通常更有用的漏洞是任意写入。这个原语允许你在内核中的任何地方进行写入,这可能会让你覆盖你的访问令牌。

如果你不记得或不熟悉 Windows 操作系统,每个进程都有一个对应的内核对象,称为EPROCESS。每个 EPROCESS 对象都有一个代表其安全上下文的访问令牌。 System 进程实际上是内核,自然拥有操作系统中最强大的访问令牌。由于每个 EPROCESS 都驻留在内核空间中,我们不能随意更改 EPROCESS 的访问令牌,我们必须从内核本身开始。但假设我们有一个任意的写入原语,则可以更改任何进程的访问令牌,并将其替换为系统的进程访问令牌,这种技术被称为纯数据( data-only )攻击。与内存攻击技术相比,我们不会损坏任何页面池条目,这些条目容易受到 kCFG/HVCI/HyperGuard 等新缓解措施的影响。

假设是寻找漏洞的关键

找到任意写入漏洞是很重要的,但对于完全的本地权限升级来说还不够。

假设HVCI开启:

无论你的完整性级别如何,内核中的任意写入对于 LPE 来说都是不够的;你还需要一个读取原语来启用令牌中的正确权限。

如果HVCI关闭:

完整性级别为中(最常见),可以调用 EnumDeviceDrivers 和 NtQuerySystemInformation 来获取内核的基地址,这应该允许你在某些页面条目损坏的情况下覆盖 HalDisptachTable/SMEP,这对 LPE 来说已经足够了。

完整性级别低或不受信任(主要是浏览器),你不能调用上面提到的 API,因此,没有适合你的内核基地址。必须有一个额外的 LPE 原语。

任意写入漏洞是什么样的?通常,它涉及内存的解引用和受控缓冲区的复制操作,它可以有多种形式,比如memcpy/memmove ,任意指针解引用等,让我们看看一些比较流行的:

20.png

图20-在一个我们无法评论的驱动程序中发现的普通任意写入示例

假设我们的驱动程序使用METHOD_NEITHER作为传输类型,并且我们看到输入或输出缓冲区加载到寄存器中,这是一个任意指针解引用。此时,寄存器RAX和RCX都指向用户模式缓冲区。当然,你可以完全控制它们的内容,并且你事先知道它们在内存中的位置,因为你已经创建了它们。由于我们可以完全控制寄存器,我们可以写入 RAX 指向的内存地址,RCX 指向的 shellcode 地址。换句话说,我们有一个 write-what-where 类型的漏洞或任意写入。

如果我们有METHOD_NEITHER传输类型,何时使用缓冲区以及以何种方式使用。图 19 中的这种模式有点少见,但仍不时出现。

攻击功能的来源

谈到任意写入漏洞时,我们不能不提到一个关键函数,这个函数通常是其根源:不正确地使用任何一个memcpy例程。驱动程序开发人员使用的memcpy函数或宏RtlCopyMemory在设计上是不安全的。它不处理越界写入或内存重叠,源或目标位于同一内存中。有一个函数处理内存重叠,它是memmove或宏rtlmovmemory。这仍然不能解决越界写入的问题。此外,任何一个参数的不正确使用都可能导致漏洞。

让我们检查一个驱动程序中一个很容易看到的漏洞,该漏洞应该是无名的:

21.webp.jpg

图21-有问题的驱动逻辑,看起来很糟糕

这里显示的反编译代码有点像Ida,这通常会使我们的工作容易得多,并且在区分IO_STACK_LOCATION结构成员(如果它们是union)时犯了很多错误。乍一看,这会给我们带来一些困惑。让我们忽略 ioctl 0x26DC03 出现的漏洞,即不正确使用 ProbeForRead,甚至不使用缓冲区。幸运的是,熟悉内核内部的每个人都可以看到事情看起来很奇怪:

22.png

图22-更正变量名称和类型

经典的可怕的漏洞

为了使它看起来更好,我们按ALT-Y来选择IO_STACK_LOCATION的正确联合成员的正确字段;让我们看看它是什么样的:

23.webp.jpg

图23-ida应该如何表示调度函数的反编译输出

更改后,我们可以看到反编译的输出看起来像普通的 C。我们对 memmove 进行了几次调用,这是我在查看调度函数时建议做的第一件事。SystemBuffer似乎是一个由源字段、大小字段和目标字段组成的结构,它们被盲目地提供给memmove方法,我称之为最好的安全性。我们可以看到有三个对memmove的调用,ioctl 0x26DC04表示在内核中对任意内容进行写入操作。相反,ioctl 0x26FC08允许从内核读取,因为它稍后将被分配给SystemBuffer(不在图22中)并返回给用户。总而言之,该驱动程序提供了所有读/写功能,这允许攻击者通过系统令牌升级为特权帐户。当然,HVCI与上述示例无关。唯一可用的是这个驱动程序不能从普通用户权限级别访问,只能从管理员和更高级别访问。因此,它限制了升级目的的有用性。然而,这个驱动程序带有灵活内核原语的签名驱动程序,仍可以被利用。

修复这个驱动程序意味着重写调度例程的整个逻辑。供应商没有这样做,而是改变了设备的ACL,以防止非管理员用户干扰它。

本文,我们介绍了如何开始寻找WDM驱动程序中的漏洞。最重要的事情就是获得设备句柄。接着,我们继续分析IRP_MJ_DEVICE_CONTROL的调度例程,然后查看imanager如何处理用户数据。之后,我们讨论了一些漏洞以及如何找到它们并利用它们。

接上篇Windows WDM 驱动漏洞挖掘(上)

蓝屏现象

简而言之,我们第一个真正的漏洞示例是微软Azure VFP扩展或vfpext.sys。故事从驱动程序的ioctl调度函数开始。在一些变量初始化之后,它调用一个方法来验证用户模式参数,然后调用一些内部逻辑。

12.png

图12-由Ida Pro反编译的SxStartDeviceIoControl函数,从vfpext.sys的disptachIoctl函数调用

我们真正拥有的是一个简单的代码,它执行以下操作:

从宏iogetcurrenttirpstacklocation (IRP)中获取一个指向CurrentStackLocation的指针;

验证缓冲区长度是否超过0x218;

以安全的方式创建一些Unicode字符串;

通过调用我们不关心的SxFindContextByName来进行查找操作;

问题是驱动程序在任何地方都不会检查给定的 ioctl IRP->AssociatedIrp 是什么。例如,SystemBuffer 是一个有效地址;它假定缓冲区的地址是有效的。

然而,回顾图 4,我们可以假设驱动程序期望获得一个带有TransferType的ioctl代码为METHOD_BUFFER或METHOD_IN_DIRECT或METHOD_OUT_DIRECT,因为它从IRP- bb0 AssociatedIrp.SystemBuffer读取输入缓冲区。

但是,如果它是 METHOD_NEITHER,那么 IRP->AssociatedIrp.SystemBuffer 对 IoManager 没有任何意义,它会将其设置为零,因为它会填充 IRP->Parameters.DeviceIoControl.Type3InputBuffer。

接下来,调用 SxInitUnicodeStringSafe ,我认为它应该是内核方法 RtlInitUnicodeString 的更安全版本;第二个参数是 SystemBuffer+8,即源字符串。

13.png

图13-Ida Pro 反编译的 SxInitUnicodeStringSafe 函数,接收 SystemBuffer,它可以指向无效内存

因此,SystemBuffer地址的地址将是0x10 = (0x0+sizeof(wchar_t *)+8)。因此,在调用RtlStringCbLengthW(顾名思义,它计算长度)时,将使用指向无效地址的系统缓冲区。它包含如下代码:

14.png

图14-这里发生了指针解引用

当 *SystemBuffer 解引用发生时,你解引用了一个无效地址,并且内核不会执行空指针。

15.webp.jpg

图15-只是由漏洞触发的蓝屏

这个漏洞检查只需要两行代码就可被触发:

16.png

图16-导致漏洞检查

在这种情况下,我们的漏洞是不可利用的,除非来自有限用户的 DoS。此漏洞也可能由受限用户和应用程序沙箱中触发,因为对设备没有任何保护。因此,每个人都可以得到一个句柄和BSoD。直到今天,这个漏洞还没有被修复; MSRC 的回应是:“我们已经完成了调查,并确定此报告是一个中等严重性的拒绝服务漏洞,很遗憾,这意味着它不符合我们在安全更新中提供服务的标准。”微软的回答很有趣,因为它不仅仅是一个常规的 DoS,而是一个系统的 DoS。从 CVSS 的角度来看,它应该是 7.3。除此之外,修复非常简单;在盲目使用之前检查ioctl代码,这将导致正确使用IRP的缓冲区。

内存漏洞

在了解了拒绝服务攻击后,我们应该继续讨论一个特殊的、隐秘的漏洞类。信息泄漏是指内核内存泄露给用户模式。它不会触发漏洞检查或任何异常,因此在驱动程序开发的常规管道中很难找到。与常规内存池漏洞相比,你也无法通过驱动程序验证程序找到它。

自Windows Vista发布以来,微软引入了KASLR缓解措施,这使得 Windows 内核开发非常具有挑战性。 KASLR是内核ASLR,它在启动时随机化驱动程序、模块、内核对象的基地址。这样,你就不能像过去那样滥用任意写入原语了。那时,你可以找到一个可以被内核调用的地址,比如HalDispatchTable,然后放置一个恶意的shellcode,可以进行令牌窃取,例如,可以由用户模式进程触发。因此,任意写入足以执行代码,或者你可以解 SMEP 作为记录。

如今,当地址被随机化时,人们不知道在哪里分配 shellcode,因为 HalDispatchTable 是在每次启动时随机化的。

漏洞利用编写者变得更聪明,并且很快就明白你可以调用 NtQuerySystemInformation 或 EnumDeviceDrivers 来获取 ntoskrnl 的基地址。这样,我们就绕过了 KASLR,使任意写入对于 LPE 来说已经足够了。当然,只有当被控制的进程具有中等完整性(大多数进程都具有中等完整性)时,才可以调用这些API;浏览器不是。除此之外,使用 PageEntry 攻击覆盖 HalDisptachTable 是无效的,因为 HVCI 等新的缓解措施仍然不是大多数 Windows 设备上的默认设置。

或者,可以直接从系统进程读取数据。例如,可能会读取完全加载到内存中的 SAM 文件。现在,假设你可以从内存中提取它。在这种情况下,你可能可以破解哈希并找到管理员密码,从而使你可以悄悄地实现完全的权限提升。由于你并没有真正接触磁盘,因此不会触发防攻击。

那么信息泄漏是什么样的呢?它主要以获取某些敏感内核对象的内核指针的形式出现,但它也可能看起来像公开未初始化的内核内存,例如在 RtsPer.sys Realtek 驱动程序中:

17.png

图17-rts_ctrl_dump_mem_log 包含严重的信息泄漏漏洞

乍一看,这里提供的代码似乎很可靠;驱动程序使用 METHOD_BUFFERED(因为它以 00 结尾)来传输数据,所以用户数据不能从它的缓冲区分离出;缓冲区长度是可信的(详见图11和上面的内容)。然而,即使使用METHOD_BUFFERED,它也不能保证代码无漏洞。

查找信息泄漏漏洞的最简单方法是查看返回的数据及其长度。由于我们处理的是 METHOD_BUFFERED,因此返回的数据是通过 SystemBuffer 进行的,并且 IRP->IoStatus.Information 指定了大小(不仅针对此传输类型)。由于IoManager 并没有在输入缓冲区的副本之外初始化系统缓冲区。换句话说,如果 OutputBufferLength > InputBufferLength,则 SystemBuffer 的剩余部分是未初始化的数据。因此,驱动程序编写者的工作是初始化系统缓冲区并返回它的正确长度。

图16中的SystemBuffer没有被初始化为零。我们没有检查输入/输出缓冲区的长度,这是我们完全可以控制的。另外,通过查看else块,我们可以检查漏洞的逻辑:

18.png

图18-不正确的缓冲区大小分配

事实证明,通过进入 else 块,你从内核中得到了 0x107c0 字节长度的内核数据。更准确地说,IoManager 复制了 OutputBufferLength 和 InputBufferLength 之间的增量:

OutBufferLength = 0x107c0,InputBufferLength = 1

因此,我们从System进程的内存空间中返回0x107c0,大约有64k的未初始化数据,允许你读取SAM文件的内容,查找系统的内核基地址以及更多内容。此外,你可以根据需要多次触发此行为,因为它不会引发异常。

漏洞利用代码非常简单,我们唯一担心的是找到设备名称,因为它是一个自动生成的数字,但你可以暴力破解它,因为只有大约 0x200 选项,类似于图 2 中所示的方式。我们的漏洞利用代码可以执行以下操作:

打开 RtsPer.sys 公开的设备的句柄;

分配一个大小为 0x107c0 的缓冲区;

调用 DeviceIoControl;

将内核数据写入文件;

19.png

图19-在 RtsPer.sys 中滥用信息泄漏的简短代码

这只是我们在RealTek 最近修复的此驱动程序中发现的众多漏洞之一。

似乎这些漏洞很容易检测,也相对容易修复,你需要做的就是在 else 块中将 IRP->IoStatus.Information 更改为零。此外,你可以通过改变设备的权限来防止所有这些漏洞,只允许管理用户或以上用户与它交互。

第三类漏洞

我们要研究的第三种类型的漏洞会导致完全权限提升,除非它是从低完整性进程中执行的。在内核中发现的一个更好且通常更有用的漏洞是任意写入。这个原语允许你在内核中的任何地方进行写入,这可能会让你覆盖你的访问令牌。

如果你不记得或不熟悉 Windows 操作系统,每个进程都有一个对应的内核对象,称为EPROCESS。每个 EPROCESS 对象都有一个代表其安全上下文的访问令牌。 System 进程实际上是内核,自然拥有操作系统中最强大的访问令牌。由于每个 EPROCESS 都驻留在内核空间中,我们不能随意更改 EPROCESS 的访问令牌,我们必须从内核本身开始。但假设我们有一个任意的写入原语,则可以更改任何进程的访问令牌,并将其替换为系统的进程访问令牌,这种技术被称为纯数据( data-only )攻击。与内存攻击技术相比,我们不会损坏任何页面池条目,这些条目容易受到 kCFG/HVCI/HyperGuard 等新缓解措施的影响。

假设是寻找漏洞的关键

找到任意写入漏洞是很重要的,但对于完全的本地权限升级来说还不够。

假设HVCI开启:

无论你的完整性级别如何,内核中的任意写入对于 LPE 来说都是不够的;你还需要一个读取原语来启用令牌中的正确权限。

如果HVCI关闭:

完整性级别为中(最常见),可以调用 EnumDeviceDrivers 和 NtQuerySystemInformation 来获取内核的基地址,这应该允许你在某些页面条目损坏的情况下覆盖 HalDisptachTable/SMEP,这对 LPE 来说已经足够了。

完整性级别低或不受信任(主要是浏览器),你不能调用上面提到的 API,因此,没有适合你的内核基地址。必须有一个额外的 LPE 原语。

任意写入漏洞是什么样的?通常,它涉及内存的解引用和受控缓冲区的复制操作,它可以有多种形式,比如memcpy/memmove ,任意指针解引用等,让我们看看一些比较流行的:

20.png

图20-在一个我们无法评论的驱动程序中发现的普通任意写入示例

假设我们的驱动程序使用METHOD_NEITHER作为传输类型,并且我们看到输入或输出缓冲区加载到寄存器中,这是一个任意指针解引用。此时,寄存器RAX和RCX都指向用户模式缓冲区。当然,你可以完全控制它们的内容,并且你事先知道它们在内存中的位置,因为你已经创建了它们。由于我们可以完全控制寄存器,我们可以写入 RAX 指向的内存地址,RCX 指向的 shellcode 地址。换句话说,我们有一个 write-what-where 类型的漏洞或任意写入。

如果我们有METHOD_NEITHER传输类型,何时使用缓冲区以及以何种方式使用。图 19 中的这种模式有点少见,但仍不时出现。

攻击功能的来源

谈到任意写入漏洞时,我们不能不提到一个关键函数,这个函数通常是其根源:不正确地使用任何一个memcpy例程。驱动程序开发人员使用的memcpy函数或宏RtlCopyMemory在设计上是不安全的。它不处理越界写入或内存重叠,源或目标位于同一内存中。有一个函数处理内存重叠,它是memmove或宏rtlmovmemory。这仍然不能解决越界写入的问题。此外,任何一个参数的不正确使用都可能导致漏洞。

让我们检查一个驱动程序中一个很容易看到的漏洞,该漏洞应该是无名的:

21.webp.jpg

图21-有问题的驱动逻辑,看起来很糟糕

这里显示的反编译代码有点像Ida,这通常会使我们的工作容易得多,并且在区分IO_STACK_LOCATION结构成员(如果它们是union)时犯了很多错误。乍一看,这会给我们带来一些困惑。让我们忽略 ioctl 0x26DC03 出现的漏洞,即不正确使用 ProbeForRead,甚至不使用缓冲区。幸运的是,熟悉内核内部的每个人都可以看到事情看起来很奇怪:

22.png

图22-更正变量名称和类型

经典的可怕的漏洞

为了使它看起来更好,我们按ALT-Y来选择IO_STACK_LOCATION的正确联合成员的正确字段;让我们看看它是什么样的:

23.webp.jpg

图23-ida应该如何表示调度函数的反编译输出

更改后,我们可以看到反编译的输出看起来像普通的 C。我们对 memmove 进行了几次调用,这是我在查看调度函数时建议做的第一件事。SystemBuffer似乎是一个由源字段、大小字段和目标字段组成的结构,它们被盲目地提供给memmove方法,我称之为最好的安全性。我们可以看到有三个对memmove的调用,ioctl 0x26DC04表示在内核中对任意内容进行写入操作。相反,ioctl 0x26FC08允许从内核读取,因为它稍后将被分配给SystemBuffer(不在图22中)并返回给用户。总而言之,该驱动程序提供了所有读/写功能,这允许攻击者通过系统令牌升级为特权帐户。当然,HVCI与上述示例无关。唯一可用的是这个驱动程序不能从普通用户权限级别访问,只能从管理员和更高级别访问。因此,它限制了升级目的的有用性。然而,这个驱动程序带有灵活内核原语的签名驱动程序,仍可以被利用。

修复这个驱动程序意味着重写调度例程的整个逻辑。供应商没有这样做,而是改变了设备的ACL,以防止非管理员用户干扰它。

本文,我们介绍了如何开始寻找WDM驱动程序中的漏洞。最重要的事情就是获得设备句柄。接着,我们继续分析IRP_MJ_DEVICE_CONTROL的调度例程,然后查看imanager如何处理用户数据。之后,我们讨论了一些漏洞以及如何找到它们并利用它们。

驱动程序中的每一个漏洞本质上都是Windows内核中的一个漏洞,因为每个驱动程序都共享内核的内存空间。拥有了在内核中运行代码、从模型寄存器读写或复制特权访问令牌的能力实际上是拥有了系统。本文将介绍在WDM驱动程序中发现漏洞的方法,然后通过kAFL利用内核模糊。大多数漏洞似乎都在WDM或KMDF中。

在本博客的每一部分中,我们都将从基础开始,比如熟悉相关的API和数据结构。

WDM

Windows驱动程序模型(WDM)是最古老的,也是最常用的驱动程序框架。每个驱动本质上都是一个WDM驱动;较新的框架WDF (Windows Driver framework)封装了WDM,简化了WDM的开发过程,解决了WDM的多种技术难题。在检查WDM驱动程序时,我们关心的主要事情是如何与它们通信;几乎驱动程序中的每个漏洞都涉及到一些从非特权用户到驱动程序本身的通信。

在示例中,这是名为“testy”的驱动程序的入口点:

1.png

经典的DriverEntry代码,注意,对IoCreateDevice的调用没有FILE_DEVICE_SECURE_OPEN标志

这段代码是每个WDM驱动都有的DriverEntry函数的普通架构。第一个参数是DriverObject结构指针,用于设备创建和调度例程初始化。接下来,驱动程序有MajorFunction成员,它是一个函数指针数组,用于为不同的事件分配调度例程。此外,我们还有将在下一节中介绍的关键设备创建例程。

设备创建和初始化

驱动程序首先通过调用 IoCreateDevice 创建设备,这将在对象管理器中创建一个 DEVICE_OBJECT。在 Windows 中,设备对象表示驱动程序处理 I/O 请求的逻辑、虚拟或物理设备。所有这些听起来都不错,但如果我们希望它从普通用户的角度进行交流,这还不够;为此,我们调用 IoCreateSymbolicLink,它将在对象管理器中创建一个 DoS 设备名称,使用户能够通过该设备与驱动程序进行通信。但是,有些设备没有正常的名称;它们具有自动生成的名称(在 PDO 中完成)。对于没有经验的检测人员来说,它们可能看起来很奇怪,所以如果你在你最喜欢的设备中第一次看到它们,请查看软件,并在设备名称列中查看 8 位十六进制。这些设备可以像其他所有命名设备一样进行交互。

2.webp.jpg

展示 WinObjEx 设备命名空间

在设备创建例程中要注意的最重要的事情是程序员是否为设备分配了 ACL 以及 DeviceCharacteristics 的值。

不幸的是,IoCreateDevice方法不允许程序员指定任何ACL,这是不好的。因此,开发人员必须在注册表或驱动程序的ini文件中定义一个ACL。如果他们不能这样做,任何用户都可以访问设备。然而,使用IoCreateDeviceSecure方法可以缓解这种情况。

除此之外,我们还需要查看第五个参数,即 DeviceCharacteristics 。如果 DeviceCharacteristics 的值没有与 0x00000100 或 FILE_DEVICE_SECURE_OPEN 进行 OR 运算,我们可能会面临安全漏洞(除非我们讨论文件系统驱动程序或任何支持名称结构的驱动程序)。这背后的原因是 Windows 对待设备的方式;每个设备都有自己的命名空间。设备命名空间中的名称是以设备名称开头的路径。对于名为 \Device\DeviceName 的设备,其命名空间由“\Device\DeviceName\anyfile”形式的任何名称组成。

如图1所示,没有FILE_DEVICE_SECURE_OPEN标志的IoCreateDevice调用意味着设备ACL不应用于打开设备命名空间内文件的文件请求。换句话说,即使我们在通过IoCreateDeviceSecure或其他方式创建设备时指定了强ACL,该ACL也不会应用于打开文件请求。结果,我们并没有真正得到我们想要的,所以使用 \Device\testydrv 调用 CreateFile 会失败,但使用“\device\testydrv\anyfile”调用会成功,因为 IoManager 没有应用设备 ACL到创建请求(因为它假设它是一个文件系统驱动程序)。对于初学者来说,它被认为是一个值得修复的漏洞。此外,这将导致非管理员用户尝试读/写设备,执行 DeviceIoControl 请求等等,这通常是你不希望非管理员用户做的事情。

更好的用户保护

我们可以通过调用IoCreateDeviceSecure(或WdmlibIoCreateDeviceSecure;它是相同的函数),使用安全描述符防止非管理员用户打开设备句柄,并在创建例程中使用FILE_DEVICE_SECURE_OPEN值。这也将为我们省去在注册表中声明设备权限的麻烦,就像我们在 IoCreateDevice 中需要的那样。

3.png

我们应该如何创建设备

从寻找漏洞的角度来看,我们应该列举系统中每一个可能的设备,然后尝试用GENERIC_READ | GENERIC_WRITE打开它,这允许我们过滤掉不能与之通信的设备。

调度方法

创建设备很好,但仅仅与驱动程序通信是不够的,还需要 IRP。驱动程序代表 IoManager 接收 IRP、I/O 请求数据包以用于特定触发器。例如,如果应用程序尝试打开设备句柄,IoManager 将调用分配给驱动程序对象的相关调度方法。因此,它允许每个驱动程序为其创建的每个设备支持多个不同的 MajorFunction。大约有 30 种不同的 MajorFunction。如果算上已弃用的 IRP_MJ_PNP_POWER,每个都代表不同的事件。我们将只关注其中两个 MajorFunction 方法,并添加关于其余方法的简短描述,这是我们在寻找漏洞时应该注意的地方。

4.png

基本的驱动程序调度表分配

调用IRP_MJ_CREATE

在我们深入研究最有趣的目标之前,即 IRP_MJ_DEVICE_CONTROL,我们将从 IRP_MJ_CREATE 开始。每个内核模式驱动程序都必须在驱动程序调度回调函数中处理 IRP_MJ_CREATE。驱动程序必须实现 IRP_MJ_CREATE,因为没有它,你将无法打开设备或文件对象的句柄。

正如你可能猜到的,当你调用 NtCreateFile 或 ZwCreateFile 时会调用 IRP_MJ_CREATE 调度例程。在大多数情况下,它将是一个空存根,并根据设备的 ACL 返回一个带有请求的 DesiredAccess 的句柄。

5.png

典型的DistpachCreate强制方法

但是,在某些情况下,会涉及更复杂的代码,即使你满足设备的 ACL 标准,你也可能会收到类似 STATUS_INVALID_PARAMETER 的状态漏洞,因为你在调用 NtCreateFile 时使用了不正确的参数。

不幸的是,这表明你不能盲目打开设备,希望通过DeviceIoControl与驱动程序通信;你首先需要了解它的预期参数。通常,DispatchCreate 需要一些 ExtendedAttributes(不能为此使用常规 CreateFile)或特定文件名(除了设备名称)。因此,我们必须访问 DispatchCreate 方法。

6.webp.jpg

显示检查是否存在名为“StorVsp-v2”的扩展属性以及值字段的长度是否为 0x19 字节长。因此,驱动程序是 StorVsp.sys

除了打开句柄之外,你还可以在DispatchCreate中查找漏洞。函数变得越复杂,内存分配和释放漏洞的可能性就越高,特别是因为DispatchCreate并不经常被检查。

我们在寻找驱动程序中的漏洞时采取的一般方法是:

枚举每个设备对象:

尝试使用最宽松的 DesiredAccess 打开它;

如果失败,检查状态码;如果不是 STATUS_ACCESS_DENIED,你可能仍然可以通过做一些手动工作并更改一些参数来打开句柄;

通过遵循这个简单的算法,我们将拥有一个包含大约 70 个设备的列表,我们可以从非管理员的角度与之交谈。当然,这个数字会因不同的 Windows 设备而异,因为 OEM 驱动程序和许多类型的软件也会安装驱动程序。

使用ioctls控制设备

虽然ioctls很少让你完全控制设备/驱动程序,但它实际上是应用程序与驱动程序通信的方式。驱动程序可以创建两种ioctl调度例程:

7.png

设备控制方法的典型用法

唯一重要的方法是TestyDispatchIoctl,因为我们不能用任意参数发起对IoBuildDeviceIoControlRequest或IIoAllocateIrp的调用,这是触发IRP_MJ_INTERNAL_DEVICE_CONTROL主函数的函数。如果是,那是因为内部调度方法很少经过适当的测试。

与DriverObject的任何调度方法一样,它从IoManager接收两个参数。

8.png

WDM驱动程序中的每个调度方法共享相同的函数签名

第一个是我们对其执行 CreateFile 操作的设备对象,第二个是指向 IRP 的指针。从漏洞研究的角度来看,IRP 封装了用户数据和我们并不真正关心的许多其他内容。我们在这里关心的主要是从用户模式发送哪些参数。如果我们看一下 NtDeviceIoControlFile 的签名,我们可以猜测在寻找驱动程序中的漏洞时我们关心哪些字段:

9.png

DeviceIoControl API

这种方法的主要问题是输入/输出缓冲区、它们的长度和Ioctl代码本身。我们从Ioctl代码开始,它是一个充当说明符的32位数字;它描述了缓冲区和长度如何被使用/复制到内核,所需的DesiredAccess(当你打开一个设备句柄时)和一个函数指示器。示例如下:

10.webp.jpg

FileTest.exe工具的图像,显示了32 Ioctl编号的位域

我们可以看到ioctl代码是0x1000,翻译过来就是:

DeviceType: FileDevice_0:它与我们无关;

Function: 0:与我们无关;

Method: METHOD_NEITHER:它与我们相关,因为它描述了imanager如何将数据传输到内核;

Access: FILE_ANY_ACCESS:它与我们相关,因为它定义了你需要对句柄拥有的所需访问权限。如果你没有正确的访问权限,那么 IoManager 将不允许调用发生并返回 AccessDenied。有四个不同的值:

FILE_ANY_ACCESS:无论 DesiredAccess 参数如何,你始终拥有设备句柄;

FILE_READ_DATA:你使用 GENERIC_READ 请求了一个句柄并获得了一个有效的句柄;

FILE_WRITE_DATA:你使用 GENERIC_WRITE 请求了一个句柄并获得了一个有效的句柄;FILE_READ_DATA | FILE_WRITE_DATA:不言自明;你需要这两种权利;

在 \Device\VfpExt 的句柄上运行此 DeviceIoControl 请求将导致 BSoD,无论你的权限级别如何,在理解了图3中的Method字段之后,我们将看到其中的原因。

Method/TransferType

Method/TransferType被称为万恶之母,这听起来有些夸大其词,但不幸的是,事实确实如此。传输类型的方法,即ioctl 32位数中的两个最低有效位,指示 IoManager 在内核中引用参数(缓冲区和长度)的方式。与访问字段一样,有四个不同的选项:

(1) METHOD_NEITHER,两个位都是打开的:IoManager 是惰性的,不对缓冲区及其长度进行检查。缓冲区不会复制到驱动程序并驻留在用户模式下。因此,用户可以随意操纵缓冲区的长度并释放/分配他们的页面,这将导致许多糟糕的事情:系统崩溃和权限提升,除非正确探测缓冲区。如果你看到一个驱动程序没有探测缓冲区,而是使用METHOD_NEITHER,那肯定存在漏洞。

(2) METHOD_BUFFERED,没有一个位是打开的:IoManager将输入/输出缓冲区及其长度复制到内核,这使得它更加安全,因为用户不能随意换出缓冲区或更改它们的内容和长度。之后,输入/输出缓冲区指针被分配给IRP。

(3) METHOD_IN_DIRECT和(4)METHOD_OUT_DIRECT两个位中的一个是打开的:这两个非常相似;imanager会像METHOD_BUFFERED那样分配输入缓冲区。对于输出缓冲区,IoManager探测缓冲区并检查虚拟地址在当前访问模式下是否可写或可读。然后,它锁定内存页并将指针传递给 IRP。

让我们看看驱动程序如何访问用户模式缓冲区并查看一个快速漏洞,它说明了在驱动程序中没有进行适当的安全检查的漏洞。

11.png

在这里我们可以看到我们应该如何关联驱动程序中的每个缓冲区关于描述方法和传输类型的 Ioctl 代码

由于驱动程序通常可以支持多个 ioctl 代码,因此对于每个不同的 ioctl 代码,它都有一个大的 switch case,影响缓冲区在内存中的存储位置。在下一节中,我们将看到如果我们不注意会发生什么。

驱动程序中的每一个漏洞本质上都是Windows内核中的一个漏洞,因为每个驱动程序都共享内核的内存空间。拥有了在内核中运行代码、从模型寄存器读写或复制特权访问令牌的能力实际上是拥有了系统。本文将介绍在WDM驱动程序中发现漏洞的方法,然后通过kAFL利用内核模糊。大多数漏洞似乎都在WDM或KMDF中。

在本博客的每一部分中,我们都将从基础开始,比如熟悉相关的API和数据结构。

WDM

Windows驱动程序模型(WDM)是最古老的,也是最常用的驱动程序框架。每个驱动本质上都是一个WDM驱动;较新的框架WDF (Windows Driver framework)封装了WDM,简化了WDM的开发过程,解决了WDM的多种技术难题。在检查WDM驱动程序时,我们关心的主要事情是如何与它们通信;几乎驱动程序中的每个漏洞都涉及到一些从非特权用户到驱动程序本身的通信。

在示例中,这是名为“testy”的驱动程序的入口点:

1.png

经典的DriverEntry代码,注意,对IoCreateDevice的调用没有FILE_DEVICE_SECURE_OPEN标志

这段代码是每个WDM驱动都有的DriverEntry函数的普通架构。第一个参数是DriverObject结构指针,用于设备创建和调度例程初始化。接下来,驱动程序有MajorFunction成员,它是一个函数指针数组,用于为不同的事件分配调度例程。此外,我们还有将在下一节中介绍的关键设备创建例程。

设备创建和初始化

驱动程序首先通过调用 IoCreateDevice 创建设备,这将在对象管理器中创建一个 DEVICE_OBJECT。在 Windows 中,设备对象表示驱动程序处理 I/O 请求的逻辑、虚拟或物理设备。所有这些听起来都不错,但如果我们希望它从普通用户的角度进行交流,这还不够;为此,我们调用 IoCreateSymbolicLink,它将在对象管理器中创建一个 DoS 设备名称,使用户能够通过该设备与驱动程序进行通信。但是,有些设备没有正常的名称;它们具有自动生成的名称(在 PDO 中完成)。对于没有经验的检测人员来说,它们可能看起来很奇怪,所以如果你在你最喜欢的设备中第一次看到它们,请查看软件,并在设备名称列中查看 8 位十六进制。这些设备可以像其他所有命名设备一样进行交互。

2.webp.jpg

展示 WinObjEx 设备命名空间

在设备创建例程中要注意的最重要的事情是程序员是否为设备分配了 ACL 以及 DeviceCharacteristics 的值。

不幸的是,IoCreateDevice方法不允许程序员指定任何ACL,这是不好的。因此,开发人员必须在注册表或驱动程序的ini文件中定义一个ACL。如果他们不能这样做,任何用户都可以访问设备。然而,使用IoCreateDeviceSecure方法可以缓解这种情况。

除此之外,我们还需要查看第五个参数,即 DeviceCharacteristics 。如果 DeviceCharacteristics 的值没有与 0x00000100 或 FILE_DEVICE_SECURE_OPEN 进行 OR 运算,我们可能会面临安全漏洞(除非我们讨论文件系统驱动程序或任何支持名称结构的驱动程序)。这背后的原因是 Windows 对待设备的方式;每个设备都有自己的命名空间。设备命名空间中的名称是以设备名称开头的路径。对于名为 \Device\DeviceName 的设备,其命名空间由“\Device\DeviceName\anyfile”形式的任何名称组成。

如图1所示,没有FILE_DEVICE_SECURE_OPEN标志的IoCreateDevice调用意味着设备ACL不应用于打开设备命名空间内文件的文件请求。换句话说,即使我们在通过IoCreateDeviceSecure或其他方式创建设备时指定了强ACL,该ACL也不会应用于打开文件请求。结果,我们并没有真正得到我们想要的,所以使用 \Device\testydrv 调用 CreateFile 会失败,但使用“\device\testydrv\anyfile”调用会成功,因为 IoManager 没有应用设备 ACL到创建请求(因为它假设它是一个文件系统驱动程序)。对于初学者来说,它被认为是一个值得修复的漏洞。此外,这将导致非管理员用户尝试读/写设备,执行 DeviceIoControl 请求等等,这通常是你不希望非管理员用户做的事情。

更好的用户保护

我们可以通过调用IoCreateDeviceSecure(或WdmlibIoCreateDeviceSecure;它是相同的函数),使用安全描述符防止非管理员用户打开设备句柄,并在创建例程中使用FILE_DEVICE_SECURE_OPEN值。这也将为我们省去在注册表中声明设备权限的麻烦,就像我们在 IoCreateDevice 中需要的那样。

3.png

我们应该如何创建设备

从寻找漏洞的角度来看,我们应该列举系统中每一个可能的设备,然后尝试用GENERIC_READ | GENERIC_WRITE打开它,这允许我们过滤掉不能与之通信的设备。

调度方法

创建设备很好,但仅仅与驱动程序通信是不够的,还需要 IRP。驱动程序代表 IoManager 接收 IRP、I/O 请求数据包以用于特定触发器。例如,如果应用程序尝试打开设备句柄,IoManager 将调用分配给驱动程序对象的相关调度方法。因此,它允许每个驱动程序为其创建的每个设备支持多个不同的 MajorFunction。大约有 30 种不同的 MajorFunction。如果算上已弃用的 IRP_MJ_PNP_POWER,每个都代表不同的事件。我们将只关注其中两个 MajorFunction 方法,并添加关于其余方法的简短描述,这是我们在寻找漏洞时应该注意的地方。

4.png

基本的驱动程序调度表分配

调用IRP_MJ_CREATE

在我们深入研究最有趣的目标之前,即 IRP_MJ_DEVICE_CONTROL,我们将从 IRP_MJ_CREATE 开始。每个内核模式驱动程序都必须在驱动程序调度回调函数中处理 IRP_MJ_CREATE。驱动程序必须实现 IRP_MJ_CREATE,因为没有它,你将无法打开设备或文件对象的句柄。

正如你可能猜到的,当你调用 NtCreateFile 或 ZwCreateFile 时会调用 IRP_MJ_CREATE 调度例程。在大多数情况下,它将是一个空存根,并根据设备的 ACL 返回一个带有请求的 DesiredAccess 的句柄。

5.png

典型的DistpachCreate强制方法

但是,在某些情况下,会涉及更复杂的代码,即使你满足设备的 ACL 标准,你也可能会收到类似 STATUS_INVALID_PARAMETER 的状态漏洞,因为你在调用 NtCreateFile 时使用了不正确的参数。

不幸的是,这表明你不能盲目打开设备,希望通过DeviceIoControl与驱动程序通信;你首先需要了解它的预期参数。通常,DispatchCreate 需要一些 ExtendedAttributes(不能为此使用常规 CreateFile)或特定文件名(除了设备名称)。因此,我们必须访问 DispatchCreate 方法。

6.webp.jpg

显示检查是否存在名为“StorVsp-v2”的扩展属性以及值字段的长度是否为 0x19 字节长。因此,驱动程序是 StorVsp.sys

除了打开句柄之外,你还可以在DispatchCreate中查找漏洞。函数变得越复杂,内存分配和释放漏洞的可能性就越高,特别是因为DispatchCreate并不经常被检查。

我们在寻找驱动程序中的漏洞时采取的一般方法是:

枚举每个设备对象:

尝试使用最宽松的 DesiredAccess 打开它;

如果失败,检查状态码;如果不是 STATUS_ACCESS_DENIED,你可能仍然可以通过做一些手动工作并更改一些参数来打开句柄;

通过遵循这个简单的算法,我们将拥有一个包含大约 70 个设备的列表,我们可以从非管理员的角度与之交谈。当然,这个数字会因不同的 Windows 设备而异,因为 OEM 驱动程序和许多类型的软件也会安装驱动程序。

使用ioctls控制设备

虽然ioctls很少让你完全控制设备/驱动程序,但它实际上是应用程序与驱动程序通信的方式。驱动程序可以创建两种ioctl调度例程:

7.png

设备控制方法的典型用法

唯一重要的方法是TestyDispatchIoctl,因为我们不能用任意参数发起对IoBuildDeviceIoControlRequest或IIoAllocateIrp的调用,这是触发IRP_MJ_INTERNAL_DEVICE_CONTROL主函数的函数。如果是,那是因为内部调度方法很少经过适当的测试。

与DriverObject的任何调度方法一样,它从IoManager接收两个参数。

8.png

WDM驱动程序中的每个调度方法共享相同的函数签名

第一个是我们对其执行 CreateFile 操作的设备对象,第二个是指向 IRP 的指针。从漏洞研究的角度来看,IRP 封装了用户数据和我们并不真正关心的许多其他内容。我们在这里关心的主要是从用户模式发送哪些参数。如果我们看一下 NtDeviceIoControlFile 的签名,我们可以猜测在寻找驱动程序中的漏洞时我们关心哪些字段:

9.png

DeviceIoControl API

这种方法的主要问题是输入/输出缓冲区、它们的长度和Ioctl代码本身。我们从Ioctl代码开始,它是一个充当说明符的32位数字;它描述了缓冲区和长度如何被使用/复制到内核,所需的DesiredAccess(当你打开一个设备句柄时)和一个函数指示器。示例如下:

10.webp.jpg

FileTest.exe工具的图像,显示了32 Ioctl编号的位域

我们可以看到ioctl代码是0x1000,翻译过来就是:

DeviceType: FileDevice_0:它与我们无关;

Function: 0:与我们无关;

Method: METHOD_NEITHER:它与我们相关,因为它描述了imanager如何将数据传输到内核;

Access: FILE_ANY_ACCESS:它与我们相关,因为它定义了你需要对句柄拥有的所需访问权限。如果你没有正确的访问权限,那么 IoManager 将不允许调用发生并返回 AccessDenied。有四个不同的值:

FILE_ANY_ACCESS:无论 DesiredAccess 参数如何,你始终拥有设备句柄;

FILE_READ_DATA:你使用 GENERIC_READ 请求了一个句柄并获得了一个有效的句柄;

FILE_WRITE_DATA:你使用 GENERIC_WRITE 请求了一个句柄并获得了一个有效的句柄;FILE_READ_DATA | FILE_WRITE_DATA:不言自明;你需要这两种权利;

在 \Device\VfpExt 的句柄上运行此 DeviceIoControl 请求将导致 BSoD,无论你的权限级别如何,在理解了图3中的Method字段之后,我们将看到其中的原因。

Method/TransferType

Method/TransferType被称为万恶之母,这听起来有些夸大其词,但不幸的是,事实确实如此。传输类型的方法,即ioctl 32位数中的两个最低有效位,指示 IoManager 在内核中引用参数(缓冲区和长度)的方式。与访问字段一样,有四个不同的选项:

(1) METHOD_NEITHER,两个位都是打开的:IoManager 是惰性的,不对缓冲区及其长度进行检查。缓冲区不会复制到驱动程序并驻留在用户模式下。因此,用户可以随意操纵缓冲区的长度并释放/分配他们的页面,这将导致许多糟糕的事情:系统崩溃和权限提升,除非正确探测缓冲区。如果你看到一个驱动程序没有探测缓冲区,而是使用METHOD_NEITHER,那肯定存在漏洞。

(2) METHOD_BUFFERED,没有一个位是打开的:IoManager将输入/输出缓冲区及其长度复制到内核,这使得它更加安全,因为用户不能随意换出缓冲区或更改它们的内容和长度。之后,输入/输出缓冲区指针被分配给IRP。

(3) METHOD_IN_DIRECT和(4)METHOD_OUT_DIRECT两个位中的一个是打开的:这两个非常相似;imanager会像METHOD_BUFFERED那样分配输入缓冲区。对于输出缓冲区,IoManager探测缓冲区并检查虚拟地址在当前访问模式下是否可写或可读。然后,它锁定内存页并将指针传递给 IRP。

让我们看看驱动程序如何访问用户模式缓冲区并查看一个快速漏洞,它说明了在驱动程序中没有进行适当的安全检查的漏洞。

11.png

在这里我们可以看到我们应该如何关联驱动程序中的每个缓冲区关于描述方法和传输类型的 Ioctl 代码

由于驱动程序通常可以支持多个 ioctl 代码,因此对于每个不同的 ioctl 代码,它都有一个大的 switch case,影响缓冲区在内存中的存储位置。在下一节中,我们将看到如果我们不注意会发生什么。

BlackCat 勒索软件,也称为 ALPHV,是一种普遍的威胁,也是日益增长的勒索软件即服务 (RaaS) 经济的典型代表。值得注意的是,它的非传统编程语言(Rust)、多个目标设备和可能的入口点,以及与大量威胁活动组的关联。虽然 BlackCat 的到达和执行因部署它的攻击者而异,但结果是相同的。即目标数据被加密,并泄露未缴纳赎金用户的隐私,及“双重勒索”。

BlackCat 于 2021 年 11 月首次被发现,最初成为头条新闻,因为它是最早用 Rust 编程语言编写的勒索软件家族。通过使用现代语言作为其有效负载,该勒索软件试图逃避检测,尤其是传统的安全解决方案。 BlackCat 还可以针对多个设备和操作系统发起攻击。 Microsoft 已观察到针对 Windows 和 Linux 设备以及 VMWare 实例的成功攻击。

如上所述,RaaS附属模型由多个攻击者组成:访问代理,他们攻击网络并维护持久性,开发工具的RaaS操作员,以及RaaS附属机构,这些机构在最终发布勒索病毒之前,会进行其他活动,比如在网络上横向移动和窃取数据。因此,作为一个RaaS有效负载,BlackCat进入目标组织网络的方式是不同的,这取决于部署它的RaaS附属机构。例如,虽然这些攻击者的常见入口向量包括远程桌面应用程序和被攻击的凭据,但我们也看到了一个攻击者利用Exchange服务器漏洞来获得目标网络访问。此外,至少有两个已知的附属公司正在采用BlackCat: DEV-0237(以前部署 Ryuk、Conti 和 Hive)和 DEV-0504(以前部署 Ryuk、REvil、BlackMatter 和 Conti)。

这种变化和采用显着增加了组织遇到 BlackCat 的风险,并在检测和防御它方面带来挑战,因为这些攻击者和组织有不同的策略、技术和程序 (TTP)。因此,没有两个 BlackCat 的部署看起来相同。

人为操作的勒索软件攻击(例如部署 BlackCat 的那些攻击)继续发展,并且仍然是攻击者通过攻击获利的首选方法之一。组织应考虑使用 Microsoft 365 Defender 等综合解决方案补充其安全最佳实践和策略,该解决方案提供与各种威胁信号相关联的保护功能,以检测和阻止此类攻击及其后续活动。

1.png

BlackCat 有效负载部署选项

2.png

BlackCat有效负载可以运行的命令列表

用户帐户控制 (UAC) 绕过

BlackCat 可以绕过 UAC,这意味着即使负载从非管理员上下文中运行,它也会成功运行。如果勒索软件没有以管理权限运行,它会在 dllhost.exe 下运行一个辅助进程,该进程具有加密系统上最大数量的文件所需的足够权限。

域和设备枚举

勒索软件可以确定给定系统的计算机名称、设备上的本地驱动器以及设备上的 AD 域名和用户名。该恶意软件还可以识别用户是否具有域管理员权限,从而提高其勒索更多设备的能力。

自我传播

BlackCat 发现所有连接到网络的服务器。该过程首先广播 NetBIOS 名称服务 (NBNC) 消息来检查这些附加设备。然后,勒索软件尝试使用配置中指定的凭据通过 PsExec 在应答服务器上复制自身。

阻碍恢复的办法

BlackCat 有许多阻碍恢复的办法。以下是有效负载可能启动的命令及其用途:

修改引导加载程序

3.png

删除卷影副本

4.png

清除 Windows 事件日志

5.png

识别可能导致 BlackCat 勒索软件的攻击

与 RaaS 模型一致,攻击者利用 BlackCat 作为其正在进行的活动的额外负载。虽然它们的 TTP 基本保持不变(例如,使用 Mimikatz 和 PsExec 等工具部署勒索软件有效负载),但与 BlackCat 相关的攻击具有不同的入口向量,具体取决于进行攻击的勒索软件附属机构。因此,这些攻击的勒索步骤也可能明显不同。

例如,部署 BlackCat 的一家附属机构利用未打补丁的 Exchange 服务器或使用被盗凭据访问目标网络。

案例研究1:通过未打补丁的Exchange进入

在此案例中,攻击者利用未打补丁的Exchange服务器进入目标组织。

6.png

通过Exchange漏洞利用观察到BlackCat勒索软件攻击链

在利用Exchange漏洞时,攻击者启动了以下发现命令,以收集有关他们攻击的设备信息:

Cmd.exe,ver,systeminfo ——用于收集操作系统信息;

net.exe——确定环境中的域计算机、域控制器和域管理员;

执行这些命令后,攻击者浏览目录并发现了一个密码文件夹,该文件夹授予他们访问帐户凭据的权限,他们可以在攻击的后续阶段使用。他们还使用 del 命令删除与他们最初的泄露活动相关的文件。

然后,攻击者利用网络使用和窃取的凭证来安装一个网络共享,并开始使用多种方法的组合来寻找潜在的横向移动目标。首先,他们使用之前收集的设备名称作为节点的WMIC.exe,启动命令whoami /all,并ping google.com以检查网络连接。然后,结果的输出被写入挂载的共享上的.log文件。其次,攻击者使用PowerShell.exe和cmdlet Get-ADComputer以及一个过滤器来收集最后一次登录事件。

扩大攻击面

两天半后,攻击者通过交互式登录使用泄露的凭据登录了他们在初始发现工作中发现的目标设备。他们选择了一种凭据盗窃技术,该技术不需要删除防病毒产品可能检测到的 Mimikatz 之类的文件。相反,他们打开了 Taskmgr.exe,创建了 LSASS.exe 进程的转储文件,并将文件保存到 ZIP 压缩文件中。

攻击者使用 ADRecon (ADRecon.ps1) 的 PowerShell 脚本版本继续他们之前的发现工作,该工具旨在收集有关 Active Directory (AD) 环境的大量信息。攻击者使用网络扫描工具跟进此操作,该工具在服务器消息块 (SMB) 和远程桌面协议 (RDP) 上打开与组织中设备的连接。对于发现的设备,攻击者试图导航到各种网络共享,并使用远程桌面客户端 (mstsc.exe) 登录这些设备,再次使用泄露的帐户凭据。

这些行为持续了好几天,攻击者登录整个组织的众多设备,转储凭据,并确定他们可以访问哪些设备。

窃取并公开信息

在攻击者登录的许多设备上,他们试图从该组织收集和窃取大量数据,包括域设置、信息和知识产权。为此,攻击者使用了MEGAsync和Rclone,它们被重命名为合法的Windows进程名称(例如,winlogon.exe, mstsc.exe)。

提取区域信息以识别横向运动目标

收集域信息允许攻击者进一步进行攻击,因为所述信息可以识别横向移动的潜在目标,或帮助攻击者发现勒索病毒有效负载的目标。为此,攻击者再次使用带有大量 PowerShell cmdlet 的 ADRecon.ps1,例如:

Get-ADRGPO——获取域中的组策略对象 (GPO);

Get-ADRDNSZone——获取域中的所有 DNS 区域和记录;

Get-ADRGPLink——获取应用于域中管理范围的所有组策略链接;

此外,攻击者释放并使用ADFind.exe命令来收集个人、计算机、组织单位和信任信息,并ping通数十个设备来检查连接。

双重勒索

为了双重勒索,攻击者以SQL数据库为目标,收集数据。他们还浏览了他们可以访问的每个设备的目录和项目文件夹,然后窃取了他们在这些设备中找到的数据。

赎金要求

攻击者从最初的攻击到部署勒索软件足足花了两周时间,因此,有必要对警报活动进行分类和检查,以了解攻击者从他们的活动中获得的账户和访问范围。使用PsExec.exe传播勒索软件负载被证明是最常见的攻击方法。

7.png

成功感染后,BlackCat显示的赎金提示

案例研究2:通过盗窃的凭证发起攻击

在这个案例中,研究人员发现了一个勒索软件附属公司通过一个面向互联网的远程桌面服务器使用被攻击的凭据登录获得了对环境的初始访问权。

8.png

通过被盗凭证观察到BlackCat勒索软件攻击链

扩大攻击面

一旦攻击者获得对目标环境的访问权,他们就使用SMB复制并启动Total Deployment Software管理工具,从而允许远程自动化软件部署。安装此工具后,攻击者使用它安装远程桌面软件应用程序 ScreenConnect(现称为 ConnectWise)。

窃取凭据

ScreenConnect用于在设备上建立远程会话,允许攻击者进行交互控制。在他们的控制下,攻击者使用cmd.exe来更新注册表,以允许通过WDigest进行明文认证,从而节省了攻击者不需要破解密码哈希值的时间。不久之后,他们使用任务管理器转储lasss .exe进程来窃取密码,现在是明文形式。

八小时后,攻击者重新连接到设备并再次窃取凭据。然而,这一次,他们放弃并启动了 Mimikatz 用于凭证盗窃例程,可能是因为它可以获取存储在 LSASS.exe 之外的凭证。攻击者随后退出。

持久性和加密

之后,攻击者使用他们新创建的用户帐户登录,并开始释放和启动勒索软件有效载荷。此帐户还将作为 ScreenConnect 及其在环境中的其他立足点之外的额外持久性手段,以允许他们在需要时重新建立自己的存在。如果访问权限未完全修复,勒索软件攻击者不会两次勒索同一组织。

Chrome.exe 用于导航到托管 BlackCat 有效负载的域。值得注意的是,文件夹结构包括组织名称,表明这是专门为组织预先准备的有效负载。最后,攻击者在设备上启动了 BlackCat 有效载荷来加密其数据。

勒索软件附属机构部署 BlackCat

除了前面讨论的事件外,我们还观察到与勒索软件部署相关的两个最多产的附属组织已转向部署 BlackCat。负载切换是一些RaaS附属公司的典型做法,以确保业务连续性或有更好的利润可能性。不幸的是,对于组织而言,这种采用进一步增加了检测相关威胁的挑战。

Microsoft 将这些附属组织命名为 DEV-0237。 DEV-0237 也称为 FIN12,该组织以传播Hive、Conti 和 Ryuk 勒索软件而闻名。研究人员观察到,该组织从2022年3月开始将BlackCat加入了他们的分布式有效负载清单。他们从上次使用的有效负载 (Hive) 切换到 BlackCat 被怀疑是由于围绕后者解密方法的公开讨论。

DEV-0504是另一个活跃的附属组织,我们看到他们转向BlackCat进行勒索软件攻击。像许多RaaS附属组一样,在DEV-0504攻击中可能会观察到以下TTP:

可能涉及附属机构远程登录到凭据被攻击的设备的入口向量,例如登录到运行允许远程工作的软件解决方案的设备;

攻击者利用他们的访问权限对域进行发现;

可能使用初始被盗帐户的横向移动;

使用 Mimikatz 和 Rubeus 等工具窃取凭据;

DEV-0504 通常会使用 StealBit 等恶意工具从组织中窃取他们入侵的设备上的数据——通常称为“send.exe”或“sender.exe”。然后使用 PsExec 传播勒索软件有效负载。观察到该组织在 2021 年 12 月开始采用 BlackCat 之前交付了以下赎金:

BlackMatter;

Conti;

LockBit 2.0;

Revil;

Ryuk;

BlackCat勒索软件的缓解措施

BlackCat勒索软件攻击已经变得越来越流行,因为它们通过RaaS附属模型不断增长的工业化和双重勒索的增加趋势。我们所观察到的与“BlackCat”勒索软件相关的事件利用了这两个因素,使得这种威胁对传统的安全和防御方法来说是持久的,这些方法只专注于检测勒索软件的有效负载。因此,组织必须改变他们的防御策略,以防止端到端攻击链。如上所述,虽然攻击者的入口点可能不同,但他们的 TTP 基本保持不变。此外,这些类型的攻击继续利用组织糟糕的错误配置来发起攻击。

截至目前,在观察到的与BlackCat相关的事件中,勒索软件附属机构的常见入口是通过被泄露的凭证来访问面向互联网的远程访问软件和未打补丁的Exchange服务器。因此,维护人员应该检查其组织的身份,仔细监视外部访问,并在其环境中找到易受攻击的Exchange服务器,以便尽快进行更新。

BlackCat 勒索软件,也称为 ALPHV,是一种普遍的威胁,也是日益增长的勒索软件即服务 (RaaS) 经济的典型代表。值得注意的是,它的非传统编程语言(Rust)、多个目标设备和可能的入口点,以及与大量威胁活动组的关联。虽然 BlackCat 的到达和执行因部署它的攻击者而异,但结果是相同的。即目标数据被加密,并泄露未缴纳赎金用户的隐私,及“双重勒索”。

BlackCat 于 2021 年 11 月首次被发现,最初成为头条新闻,因为它是最早用 Rust 编程语言编写的勒索软件家族。通过使用现代语言作为其有效负载,该勒索软件试图逃避检测,尤其是传统的安全解决方案。 BlackCat 还可以针对多个设备和操作系统发起攻击。 Microsoft 已观察到针对 Windows 和 Linux 设备以及 VMWare 实例的成功攻击。

如上所述,RaaS附属模型由多个攻击者组成:访问代理,他们攻击网络并维护持久性,开发工具的RaaS操作员,以及RaaS附属机构,这些机构在最终发布勒索病毒之前,会进行其他活动,比如在网络上横向移动和窃取数据。因此,作为一个RaaS有效负载,BlackCat进入目标组织网络的方式是不同的,这取决于部署它的RaaS附属机构。例如,虽然这些攻击者的常见入口向量包括远程桌面应用程序和被攻击的凭据,但我们也看到了一个攻击者利用Exchange服务器漏洞来获得目标网络访问。此外,至少有两个已知的附属公司正在采用BlackCat: DEV-0237(以前部署 Ryuk、Conti 和 Hive)和 DEV-0504(以前部署 Ryuk、REvil、BlackMatter 和 Conti)。

这种变化和采用显着增加了组织遇到 BlackCat 的风险,并在检测和防御它方面带来挑战,因为这些攻击者和组织有不同的策略、技术和程序 (TTP)。因此,没有两个 BlackCat 的部署看起来相同。

人为操作的勒索软件攻击(例如部署 BlackCat 的那些攻击)继续发展,并且仍然是攻击者通过攻击获利的首选方法之一。组织应考虑使用 Microsoft 365 Defender 等综合解决方案补充其安全最佳实践和策略,该解决方案提供与各种威胁信号相关联的保护功能,以检测和阻止此类攻击及其后续活动。

1.png

BlackCat 有效负载部署选项

2.png

BlackCat有效负载可以运行的命令列表

用户帐户控制 (UAC) 绕过

BlackCat 可以绕过 UAC,这意味着即使负载从非管理员上下文中运行,它也会成功运行。如果勒索软件没有以管理权限运行,它会在 dllhost.exe 下运行一个辅助进程,该进程具有加密系统上最大数量的文件所需的足够权限。

域和设备枚举

勒索软件可以确定给定系统的计算机名称、设备上的本地驱动器以及设备上的 AD 域名和用户名。该恶意软件还可以识别用户是否具有域管理员权限,从而提高其勒索更多设备的能力。

自我传播

BlackCat 发现所有连接到网络的服务器。该过程首先广播 NetBIOS 名称服务 (NBNC) 消息来检查这些附加设备。然后,勒索软件尝试使用配置中指定的凭据通过 PsExec 在应答服务器上复制自身。

阻碍恢复的办法

BlackCat 有许多阻碍恢复的办法。以下是有效负载可能启动的命令及其用途:

修改引导加载程序

3.png

删除卷影副本

4.png

清除 Windows 事件日志

5.png

识别可能导致 BlackCat 勒索软件的攻击

与 RaaS 模型一致,攻击者利用 BlackCat 作为其正在进行的活动的额外负载。虽然它们的 TTP 基本保持不变(例如,使用 Mimikatz 和 PsExec 等工具部署勒索软件有效负载),但与 BlackCat 相关的攻击具有不同的入口向量,具体取决于进行攻击的勒索软件附属机构。因此,这些攻击的勒索步骤也可能明显不同。

例如,部署 BlackCat 的一家附属机构利用未打补丁的 Exchange 服务器或使用被盗凭据访问目标网络。

案例研究1:通过未打补丁的Exchange进入

在此案例中,攻击者利用未打补丁的Exchange服务器进入目标组织。

6.png

通过Exchange漏洞利用观察到BlackCat勒索软件攻击链

在利用Exchange漏洞时,攻击者启动了以下发现命令,以收集有关他们攻击的设备信息:

Cmd.exe,ver,systeminfo ——用于收集操作系统信息;

net.exe——确定环境中的域计算机、域控制器和域管理员;

执行这些命令后,攻击者浏览目录并发现了一个密码文件夹,该文件夹授予他们访问帐户凭据的权限,他们可以在攻击的后续阶段使用。他们还使用 del 命令删除与他们最初的泄露活动相关的文件。

然后,攻击者利用网络使用和窃取的凭证来安装一个网络共享,并开始使用多种方法的组合来寻找潜在的横向移动目标。首先,他们使用之前收集的设备名称作为节点的WMIC.exe,启动命令whoami /all,并ping google.com以检查网络连接。然后,结果的输出被写入挂载的共享上的.log文件。其次,攻击者使用PowerShell.exe和cmdlet Get-ADComputer以及一个过滤器来收集最后一次登录事件。

扩大攻击面

两天半后,攻击者通过交互式登录使用泄露的凭据登录了他们在初始发现工作中发现的目标设备。他们选择了一种凭据盗窃技术,该技术不需要删除防病毒产品可能检测到的 Mimikatz 之类的文件。相反,他们打开了 Taskmgr.exe,创建了 LSASS.exe 进程的转储文件,并将文件保存到 ZIP 压缩文件中。

攻击者使用 ADRecon (ADRecon.ps1) 的 PowerShell 脚本版本继续他们之前的发现工作,该工具旨在收集有关 Active Directory (AD) 环境的大量信息。攻击者使用网络扫描工具跟进此操作,该工具在服务器消息块 (SMB) 和远程桌面协议 (RDP) 上打开与组织中设备的连接。对于发现的设备,攻击者试图导航到各种网络共享,并使用远程桌面客户端 (mstsc.exe) 登录这些设备,再次使用泄露的帐户凭据。

这些行为持续了好几天,攻击者登录整个组织的众多设备,转储凭据,并确定他们可以访问哪些设备。

窃取并公开信息

在攻击者登录的许多设备上,他们试图从该组织收集和窃取大量数据,包括域设置、信息和知识产权。为此,攻击者使用了MEGAsync和Rclone,它们被重命名为合法的Windows进程名称(例如,winlogon.exe, mstsc.exe)。

提取区域信息以识别横向运动目标

收集域信息允许攻击者进一步进行攻击,因为所述信息可以识别横向移动的潜在目标,或帮助攻击者发现勒索病毒有效负载的目标。为此,攻击者再次使用带有大量 PowerShell cmdlet 的 ADRecon.ps1,例如:

Get-ADRGPO——获取域中的组策略对象 (GPO);

Get-ADRDNSZone——获取域中的所有 DNS 区域和记录;

Get-ADRGPLink——获取应用于域中管理范围的所有组策略链接;

此外,攻击者释放并使用ADFind.exe命令来收集个人、计算机、组织单位和信任信息,并ping通数十个设备来检查连接。

双重勒索

为了双重勒索,攻击者以SQL数据库为目标,收集数据。他们还浏览了他们可以访问的每个设备的目录和项目文件夹,然后窃取了他们在这些设备中找到的数据。

赎金要求

攻击者从最初的攻击到部署勒索软件足足花了两周时间,因此,有必要对警报活动进行分类和检查,以了解攻击者从他们的活动中获得的账户和访问范围。使用PsExec.exe传播勒索软件负载被证明是最常见的攻击方法。

7.png

成功感染后,BlackCat显示的赎金提示

案例研究2:通过盗窃的凭证发起攻击

在这个案例中,研究人员发现了一个勒索软件附属公司通过一个面向互联网的远程桌面服务器使用被攻击的凭据登录获得了对环境的初始访问权。

8.png

通过被盗凭证观察到BlackCat勒索软件攻击链

扩大攻击面

一旦攻击者获得对目标环境的访问权,他们就使用SMB复制并启动Total Deployment Software管理工具,从而允许远程自动化软件部署。安装此工具后,攻击者使用它安装远程桌面软件应用程序 ScreenConnect(现称为 ConnectWise)。

窃取凭据

ScreenConnect用于在设备上建立远程会话,允许攻击者进行交互控制。在他们的控制下,攻击者使用cmd.exe来更新注册表,以允许通过WDigest进行明文认证,从而节省了攻击者不需要破解密码哈希值的时间。不久之后,他们使用任务管理器转储lasss .exe进程来窃取密码,现在是明文形式。

八小时后,攻击者重新连接到设备并再次窃取凭据。然而,这一次,他们放弃并启动了 Mimikatz 用于凭证盗窃例程,可能是因为它可以获取存储在 LSASS.exe 之外的凭证。攻击者随后退出。

持久性和加密

之后,攻击者使用他们新创建的用户帐户登录,并开始释放和启动勒索软件有效载荷。此帐户还将作为 ScreenConnect 及其在环境中的其他立足点之外的额外持久性手段,以允许他们在需要时重新建立自己的存在。如果访问权限未完全修复,勒索软件攻击者不会两次勒索同一组织。

Chrome.exe 用于导航到托管 BlackCat 有效负载的域。值得注意的是,文件夹结构包括组织名称,表明这是专门为组织预先准备的有效负载。最后,攻击者在设备上启动了 BlackCat 有效载荷来加密其数据。

勒索软件附属机构部署 BlackCat

除了前面讨论的事件外,我们还观察到与勒索软件部署相关的两个最多产的附属组织已转向部署 BlackCat。负载切换是一些RaaS附属公司的典型做法,以确保业务连续性或有更好的利润可能性。不幸的是,对于组织而言,这种采用进一步增加了检测相关威胁的挑战。

Microsoft 将这些附属组织命名为 DEV-0237。 DEV-0237 也称为 FIN12,该组织以传播Hive、Conti 和 Ryuk 勒索软件而闻名。研究人员观察到,该组织从2022年3月开始将BlackCat加入了他们的分布式有效负载清单。他们从上次使用的有效负载 (Hive) 切换到 BlackCat 被怀疑是由于围绕后者解密方法的公开讨论。

DEV-0504是另一个活跃的附属组织,我们看到他们转向BlackCat进行勒索软件攻击。像许多RaaS附属组一样,在DEV-0504攻击中可能会观察到以下TTP:

可能涉及附属机构远程登录到凭据被攻击的设备的入口向量,例如登录到运行允许远程工作的软件解决方案的设备;

攻击者利用他们的访问权限对域进行发现;

可能使用初始被盗帐户的横向移动;

使用 Mimikatz 和 Rubeus 等工具窃取凭据;

DEV-0504 通常会使用 StealBit 等恶意工具从组织中窃取他们入侵的设备上的数据——通常称为“send.exe”或“sender.exe”。然后使用 PsExec 传播勒索软件有效负载。观察到该组织在 2021 年 12 月开始采用 BlackCat 之前交付了以下赎金:

BlackMatter;

Conti;

LockBit 2.0;

Revil;

Ryuk;

BlackCat勒索软件的缓解措施

BlackCat勒索软件攻击已经变得越来越流行,因为它们通过RaaS附属模型不断增长的工业化和双重勒索的增加趋势。我们所观察到的与“BlackCat”勒索软件相关的事件利用了这两个因素,使得这种威胁对传统的安全和防御方法来说是持久的,这些方法只专注于检测勒索软件的有效负载。因此,组织必须改变他们的防御策略,以防止端到端攻击链。如上所述,虽然攻击者的入口点可能不同,但他们的 TTP 基本保持不变。此外,这些类型的攻击继续利用组织糟糕的错误配置来发起攻击。

截至目前,在观察到的与BlackCat相关的事件中,勒索软件附属机构的常见入口是通过被泄露的凭证来访问面向互联网的远程访问软件和未打补丁的Exchange服务器。因此,维护人员应该检查其组织的身份,仔细监视外部访问,并在其环境中找到易受攻击的Exchange服务器,以便尽快进行更新。

BlackCat 勒索软件,也称为 ALPHV,是一种普遍的威胁,也是日益增长的勒索软件即服务 (RaaS) 经济的典型代表。值得注意的是,它的非传统编程语言(Rust)、多个目标设备和可能的入口点,以及与大量威胁活动组的关联。虽然 BlackCat 的到达和执行因部署它的攻击者而异,但结果是相同的。即目标数据被加密,并泄露未缴纳赎金用户的隐私,及“双重勒索”。

BlackCat 于 2021 年 11 月首次被发现,最初成为头条新闻,因为它是最早用 Rust 编程语言编写的勒索软件家族。通过使用现代语言作为其有效负载,该勒索软件试图逃避检测,尤其是传统的安全解决方案。 BlackCat 还可以针对多个设备和操作系统发起攻击。 Microsoft 已观察到针对 Windows 和 Linux 设备以及 VMWare 实例的成功攻击。

如上所述,RaaS附属模型由多个攻击者组成:访问代理,他们攻击网络并维护持久性,开发工具的RaaS操作员,以及RaaS附属机构,这些机构在最终发布勒索病毒之前,会进行其他活动,比如在网络上横向移动和窃取数据。因此,作为一个RaaS有效负载,BlackCat进入目标组织网络的方式是不同的,这取决于部署它的RaaS附属机构。例如,虽然这些攻击者的常见入口向量包括远程桌面应用程序和被攻击的凭据,但我们也看到了一个攻击者利用Exchange服务器漏洞来获得目标网络访问。此外,至少有两个已知的附属公司正在采用BlackCat: DEV-0237(以前部署 Ryuk、Conti 和 Hive)和 DEV-0504(以前部署 Ryuk、REvil、BlackMatter 和 Conti)。

这种变化和采用显着增加了组织遇到 BlackCat 的风险,并在检测和防御它方面带来挑战,因为这些攻击者和组织有不同的策略、技术和程序 (TTP)。因此,没有两个 BlackCat 的部署看起来相同。

人为操作的勒索软件攻击(例如部署 BlackCat 的那些攻击)继续发展,并且仍然是攻击者通过攻击获利的首选方法之一。组织应考虑使用 Microsoft 365 Defender 等综合解决方案补充其安全最佳实践和策略,该解决方案提供与各种威胁信号相关联的保护功能,以检测和阻止此类攻击及其后续活动。

1.png

BlackCat 有效负载部署选项

2.png

BlackCat有效负载可以运行的命令列表

用户帐户控制 (UAC) 绕过

BlackCat 可以绕过 UAC,这意味着即使负载从非管理员上下文中运行,它也会成功运行。如果勒索软件没有以管理权限运行,它会在 dllhost.exe 下运行一个辅助进程,该进程具有加密系统上最大数量的文件所需的足够权限。

域和设备枚举

勒索软件可以确定给定系统的计算机名称、设备上的本地驱动器以及设备上的 AD 域名和用户名。该恶意软件还可以识别用户是否具有域管理员权限,从而提高其勒索更多设备的能力。

自我传播

BlackCat 发现所有连接到网络的服务器。该过程首先广播 NetBIOS 名称服务 (NBNC) 消息来检查这些附加设备。然后,勒索软件尝试使用配置中指定的凭据通过 PsExec 在应答服务器上复制自身。

阻碍恢复的办法

BlackCat 有许多阻碍恢复的办法。以下是有效负载可能启动的命令及其用途:

修改引导加载程序

3.png

删除卷影副本

4.png

清除 Windows 事件日志

5.png

识别可能导致 BlackCat 勒索软件的攻击

与 RaaS 模型一致,攻击者利用 BlackCat 作为其正在进行的活动的额外负载。虽然它们的 TTP 基本保持不变(例如,使用 Mimikatz 和 PsExec 等工具部署勒索软件有效负载),但与 BlackCat 相关的攻击具有不同的入口向量,具体取决于进行攻击的勒索软件附属机构。因此,这些攻击的勒索步骤也可能明显不同。

例如,部署 BlackCat 的一家附属机构利用未打补丁的 Exchange 服务器或使用被盗凭据访问目标网络。

案例研究1:通过未打补丁的Exchange进入

在此案例中,攻击者利用未打补丁的Exchange服务器进入目标组织。

6.png

通过Exchange漏洞利用观察到BlackCat勒索软件攻击链

在利用Exchange漏洞时,攻击者启动了以下发现命令,以收集有关他们攻击的设备信息:

Cmd.exe,ver,systeminfo ——用于收集操作系统信息;

net.exe——确定环境中的域计算机、域控制器和域管理员;

执行这些命令后,攻击者浏览目录并发现了一个密码文件夹,该文件夹授予他们访问帐户凭据的权限,他们可以在攻击的后续阶段使用。他们还使用 del 命令删除与他们最初的泄露活动相关的文件。

然后,攻击者利用网络使用和窃取的凭证来安装一个网络共享,并开始使用多种方法的组合来寻找潜在的横向移动目标。首先,他们使用之前收集的设备名称作为节点的WMIC.exe,启动命令whoami /all,并ping google.com以检查网络连接。然后,结果的输出被写入挂载的共享上的.log文件。其次,攻击者使用PowerShell.exe和cmdlet Get-ADComputer以及一个过滤器来收集最后一次登录事件。

扩大攻击面

两天半后,攻击者通过交互式登录使用泄露的凭据登录了他们在初始发现工作中发现的目标设备。他们选择了一种凭据盗窃技术,该技术不需要删除防病毒产品可能检测到的 Mimikatz 之类的文件。相反,他们打开了 Taskmgr.exe,创建了 LSASS.exe 进程的转储文件,并将文件保存到 ZIP 压缩文件中。

攻击者使用 ADRecon (ADRecon.ps1) 的 PowerShell 脚本版本继续他们之前的发现工作,该工具旨在收集有关 Active Directory (AD) 环境的大量信息。攻击者使用网络扫描工具跟进此操作,该工具在服务器消息块 (SMB) 和远程桌面协议 (RDP) 上打开与组织中设备的连接。对于发现的设备,攻击者试图导航到各种网络共享,并使用远程桌面客户端 (mstsc.exe) 登录这些设备,再次使用泄露的帐户凭据。

这些行为持续了好几天,攻击者登录整个组织的众多设备,转储凭据,并确定他们可以访问哪些设备。

窃取并公开信息

在攻击者登录的许多设备上,他们试图从该组织收集和窃取大量数据,包括域设置、信息和知识产权。为此,攻击者使用了MEGAsync和Rclone,它们被重命名为合法的Windows进程名称(例如,winlogon.exe, mstsc.exe)。

提取区域信息以识别横向运动目标

收集域信息允许攻击者进一步进行攻击,因为所述信息可以识别横向移动的潜在目标,或帮助攻击者发现勒索病毒有效负载的目标。为此,攻击者再次使用带有大量 PowerShell cmdlet 的 ADRecon.ps1,例如:

Get-ADRGPO——获取域中的组策略对象 (GPO);

Get-ADRDNSZone——获取域中的所有 DNS 区域和记录;

Get-ADRGPLink——获取应用于域中管理范围的所有组策略链接;

此外,攻击者释放并使用ADFind.exe命令来收集个人、计算机、组织单位和信任信息,并ping通数十个设备来检查连接。

双重勒索

为了双重勒索,攻击者以SQL数据库为目标,收集数据。他们还浏览了他们可以访问的每个设备的目录和项目文件夹,然后窃取了他们在这些设备中找到的数据。

赎金要求

攻击者从最初的攻击到部署勒索软件足足花了两周时间,因此,有必要对警报活动进行分类和检查,以了解攻击者从他们的活动中获得的账户和访问范围。使用PsExec.exe传播勒索软件负载被证明是最常见的攻击方法。

7.png

成功感染后,BlackCat显示的赎金提示

案例研究2:通过盗窃的凭证发起攻击

在这个案例中,研究人员发现了一个勒索软件附属公司通过一个面向互联网的远程桌面服务器使用被攻击的凭据登录获得了对环境的初始访问权。

8.png

通过被盗凭证观察到BlackCat勒索软件攻击链

扩大攻击面

一旦攻击者获得对目标环境的访问权,他们就使用SMB复制并启动Total Deployment Software管理工具,从而允许远程自动化软件部署。安装此工具后,攻击者使用它安装远程桌面软件应用程序 ScreenConnect(现称为 ConnectWise)。

窃取凭据

ScreenConnect用于在设备上建立远程会话,允许攻击者进行交互控制。在他们的控制下,攻击者使用cmd.exe来更新注册表,以允许通过WDigest进行明文认证,从而节省了攻击者不需要破解密码哈希值的时间。不久之后,他们使用任务管理器转储lasss .exe进程来窃取密码,现在是明文形式。

八小时后,攻击者重新连接到设备并再次窃取凭据。然而,这一次,他们放弃并启动了 Mimikatz 用于凭证盗窃例程,可能是因为它可以获取存储在 LSASS.exe 之外的凭证。攻击者随后退出。

持久性和加密

之后,攻击者使用他们新创建的用户帐户登录,并开始释放和启动勒索软件有效载荷。此帐户还将作为 ScreenConnect 及其在环境中的其他立足点之外的额外持久性手段,以允许他们在需要时重新建立自己的存在。如果访问权限未完全修复,勒索软件攻击者不会两次勒索同一组织。

Chrome.exe 用于导航到托管 BlackCat 有效负载的域。值得注意的是,文件夹结构包括组织名称,表明这是专门为组织预先准备的有效负载。最后,攻击者在设备上启动了 BlackCat 有效载荷来加密其数据。

勒索软件附属机构部署 BlackCat

除了前面讨论的事件外,我们还观察到与勒索软件部署相关的两个最多产的附属组织已转向部署 BlackCat。负载切换是一些RaaS附属公司的典型做法,以确保业务连续性或有更好的利润可能性。不幸的是,对于组织而言,这种采用进一步增加了检测相关威胁的挑战。

Microsoft 将这些附属组织命名为 DEV-0237。 DEV-0237 也称为 FIN12,该组织以传播Hive、Conti 和 Ryuk 勒索软件而闻名。研究人员观察到,该组织从2022年3月开始将BlackCat加入了他们的分布式有效负载清单。他们从上次使用的有效负载 (Hive) 切换到 BlackCat 被怀疑是由于围绕后者解密方法的公开讨论。

DEV-0504是另一个活跃的附属组织,我们看到他们转向BlackCat进行勒索软件攻击。像许多RaaS附属组一样,在DEV-0504攻击中可能会观察到以下TTP:

可能涉及附属机构远程登录到凭据被攻击的设备的入口向量,例如登录到运行允许远程工作的软件解决方案的设备;

攻击者利用他们的访问权限对域进行发现;

可能使用初始被盗帐户的横向移动;

使用 Mimikatz 和 Rubeus 等工具窃取凭据;

DEV-0504 通常会使用 StealBit 等恶意工具从组织中窃取他们入侵的设备上的数据——通常称为“send.exe”或“sender.exe”。然后使用 PsExec 传播勒索软件有效负载。观察到该组织在 2021 年 12 月开始采用 BlackCat 之前交付了以下赎金:

BlackMatter;

Conti;

LockBit 2.0;

Revil;

Ryuk;

BlackCat勒索软件的缓解措施

BlackCat勒索软件攻击已经变得越来越流行,因为它们通过RaaS附属模型不断增长的工业化和双重勒索的增加趋势。我们所观察到的与“BlackCat”勒索软件相关的事件利用了这两个因素,使得这种威胁对传统的安全和防御方法来说是持久的,这些方法只专注于检测勒索软件的有效负载。因此,组织必须改变他们的防御策略,以防止端到端攻击链。如上所述,虽然攻击者的入口点可能不同,但他们的 TTP 基本保持不变。此外,这些类型的攻击继续利用组织糟糕的错误配置来发起攻击。

截至目前,在观察到的与BlackCat相关的事件中,勒索软件附属机构的常见入口是通过被泄露的凭证来访问面向互联网的远程访问软件和未打补丁的Exchange服务器。因此,维护人员应该检查其组织的身份,仔细监视外部访问,并在其环境中找到易受攻击的Exchange服务器,以便尽快进行更新。

凭证数据(URL/用户名/密码)以明文格式存储在Chrome的内存中。除了登录特定Web应用程序时动态输入的数据外,攻击者还可以使浏览器将存储在密码管理器(“登录数据”文件)中的所有密码加载到内存中。

Cookie的数据(cookie的值+属性)以明文格式存储在Chrome的内存中(当相关应用程序被急活时),这包括敏感的会话cookie。

这些信息可以通过在本地设备上运行的标准(非提升)进程有效地提取,并直接访问Chrome的内存(使用OpenProcess+ReadProcessMemoryAPI)。

提取的数据可用于劫持用户的帐户,即使它们受到MFA机制的保护(使用“会话cookie”数据)。

Gmail、OneDrive和GitHub的示例会话劫持是“POC-ed”。

在MicrosoftEdge浏览器中发现了类似的漏洞(据推测,其他基于Chromium引擎的浏览器也会出现)。

本文描述了对浏览器的直接内存访问攻击。还有其他公开的窃取这些敏感数据的方法。

为什么这是一个重要问题:如果一个人接受“假设违规”范式,那么基于Chromium的浏览器处理敏感凭证数据的方式中的漏洞都应该被视为主要的安全风险。缓解措施应处理所有这些漏洞。

ProcessHacker工具(由WenJiaLiu编写)在这项研究中被证明非常有用。如果你怀疑某个特定字符串存储在进程的内存中,那么查找它的快速方法是:

在ProcessHacker.exe中打开该进程;

选择“内存”选项;

激活“字符串”子选项;

选择“过滤器”选项并在“包含...”框架中输入你要查找的字符串;

这是我查找已知密码时生成的输出示例(为了保密,我更改了它):

1.webp.jpg

ProcessHacker.exe在Chrome内存中识别的已知密码

如果你返回显示的内存布局(当你选择“内存”选项时),你会发现该字符串位于Private类型的内存部分中:

2.webp.jpg

查找已知密码存储在Chrome内存中的内存块

深入查看该内存块,密码存储在Private:Commit类型的内存部分中:

3.webp.jpg

查找已知密码存储在Chrome内存中的特定内存部分

根据MSDN,私有内存(MEMORY_BASIC_INFORMATIONType=MEM_PRIVATE)意味着:

4.webp.jpg

MSDN中的MEM_PRIVATE内存属性定义

人们可能会认为存储在此类内存页面中的数据不能被任何其他进程访问。令人惊讶的是,这些页面不能成为“共享内存”的一部分,但其他进程读取其中的数据没有问题(通过ReadProcessMemoryAPI)。

可以看到,上述ProcessHacker.exe作为标准进程运行,访问这些数据没有问题!

如果这些页面真的是私有的,那么这里描述的攻击向量将是不可能的。我想知道Chromium的创建者是否(在某些时候)认为敏感数据在存储在私有内存中时是安全的。

当然,在浏览器内存中查找已知字符串并不是什么大问题。寻找未知字符串怎么样?我决定只通过查看进程内存来尝试找到敏感数据(不尝试分析程序的开源代码)。

Chromium内存布局看起来像是被设计成一个“干草堆(haystack)”,因此很难找到和“理解”存储的数据(特别是密码和cookie值等敏感字符串)。我还遇到了各种蜜罐,它们看起来像是故意创建的,用于生成明文密码的误报识别。其中的困难包括:

1.相对大量的浏览器进程(例如chrome.exe)。

2.每个进程都分配了大量的虚拟内存(有些超过230GB)。

3.每个进程的内存由许多(有时数百个)“脱节”的小型已提交内存部分组成,这些部分由“保留”部分分隔。

4.大内存“组合”部分,包括许多如上所述的不相交的部分,这些部分实际上是“空的”(不是“真正”使用的)。

5.看起来像密码或cookie值的字符串(实际字符串的子字符串)。

6.将属于一个逻辑“记录”的项目(例如URL+用户名+密码)分散到远程存储位置。

这可能是所有看起来像是隐藏(“混淆”)的尝试,而只是正常操作的结果。如上所述,我没有查看代码,但我认为他们试图隐藏敏感数据。

从Chrome内存中提取的明文凭证数据类型

事实证明,通过标准的非特权进程可以很容易地从浏览器的内存中有效地提取明文凭证数据。实际上,这意味着:

1.它使用了合理数量的计算机资源(CPU能力、内存)。

2.执行在合理的时间内完成。

3.误报现象较少。

注意:当描述POC程序的部分时,我知道大多数读者会期望关键功能的技术细节和源代码片段。由于本博文结尾部分解释的原因,此信息不会被披露。已开发POC程序以提取以下类型的信息:

1、登录目标Web应用程序时使用的用户名+密码

该程序等待用户登录特定的Web应用程序(例如Gmail、OneDrive、GitHub等),然后分析捕获的内存快照以识别用于登录应用程序的用户名和密码。

这有点像一个有效的键记录程序可以实现的功能,但重要的区别是,之前存储的密码(例如,在浏览器的密码管理器工具中),它完全绕过了最初定义时没有运行的键记录程序,将被我们的程序发现。

该程序查看登录之前和之后立即拍摄的快照之间的差异,并查找仅出现在“after”内快照中并且看起来像潜在的用户名和密码字符串的新字符串。

注意:这是本研究中开发的最复杂的POC程序,它产生了相当多的误报结果,因为相当多的新字符串出现在“after”内存快照中。

排除这些假阳性案例是可能的(例如,通过识别出现在登录过程中的常见“单词”),并且如果想要努力,可以不断改进。具有讽刺意味的是,密码越强,就越容易从“噪音”假阳性案例中分离出来(例如,由小写和大写字符、数字和特殊符号组成的10个字符的字符串比只有小写字符的7个字符的字符串更有可能是密码)。

2、URL+用户名+密码在浏览器启动时自动加载到内存中

当浏览器启动时,“登录数据”文件(Chromium存储保存的密码)中的一些条目会自动加载到内存中。虽然并非“登录数据”中的所有条目都必须加载,但最近使用的条目是必须加载的。

“登录数据”数据库中的密码是DPAPI加密的,但是当它们“分散”到内存中时,它们会以明文格式保存。

与前一种情况(上面的“a”)不同,这里分析一组快照就足够了,因为加载的凭证数据静态地保留在内存中。

我们开发了一个有效的POC程序,可以从内存中提取这些数据。可能会生成少量误报项目。同样,过滤掉误报情况的算法可以得到显着和持续的改进。

3、登录数据中存储的所有URL+用户名+密码记录

可以使浏览器的密码管理器功能将其所有存储的记录加载到内存中。我们开发的POC程序可以提取所有加载的记录。在这种情况下,敏感数据以易于识别的结构排列。

因此,程序对提取的数据有很高的信心,并且在大多数情况下,几乎没有误报条目。

在这种情况下,所有保存的密码记录都加载到了Chrome的内存中。他还帮助我发现和分析了各种Chromium内存布局。

4.属于特定Web应用程序的所有cookie(包括会话cookie)

该程序等待用户登录到一个特定的应用程序(例如,Gmail, OneDrive, GitHub等)。当应用程序会话处于活动状态时,程序可以从Chrome的内存中提取属于该会话的所有cookie。这些被盗的cookie可以上传到不同设备上的浏览器中,并且会话可以被盗(绕过任何MFA机制)。

当窃取的cookie被用于劫持会话时,典型的应用程序(例如Gmail)无法识别连接是从新设备还是从新位置建立的。这是因为完全绕过了登录过程。根据cookie的内容,应用程序假定这是先前经过身份验证的会话的延续。

值得注意的是,某些应用程序鼓励其用户不要退出应用程序。例如,Gmail的会话cookie的有效期为自首次生成之日起两年。同样,MicrosoftOneDrive最近开始向其网络用户建议他们无需退出会话。在这些情况下,窃取会话cookie的攻击者可能会在很长一段时间内与真正的所有者“共享”该帐户。

误判极为罕见。

负责任的披露和供应商响应

我于2021年7月29日向Google报告了此问题:

10.webp.jpg

谷歌回应

该报告包括Gmail会话劫持的详细POC,包括从Chrome内存中提取cookie的程序的源代码。

Chromium.org的回复(WontFix)很快:

11.webp.jpg

Chromium.org以WontFix状态关闭问题

这种回应并不令人惊讶,因为其他类似“假设违规”漏洞的报告也收到了类似的回应。

14周后,Chromium公开了我的报告:

12.webp.jpg

谷歌向公众发布问题细节

总的来说,Chromium.org表示他们不会修复与物理本地攻击相关的问题,因为Chrome(或任何应用程序)没有办法防御一个以你的身份登录你的设备的恶意用户。虽然这种说法总体上可能是正确的(特别是如果你假设攻击者可以获得管理员权限),但我相信窃取敏感凭证应该不像今天这样容易。因此,如上所述,我的下一篇文章将提出几种缓解技术,使攻击更难执行。

在披露后大约一个月,我的程序未能提取cookie数据。事实证明,一般内存布局已被修改(在Chrome和Edge中)。大约两个月后,它再次失败。这一次,“敏感”数据的位置已经改变(同样,同时针对Chrome和Edge)。

最初的POC程序是为Chrome版本91.0.4472.164开发的:

13.webp.jpg

原始POC程序的Chrome版本

演示视频中的POC程序正在访问Chrome的96.0.4664.45版本:

14.webp.jpg

演示视频中用于POC程序的Chrome版本

如上所述,自从我们负责任地披露了这个漏洞以来,已经发现了内存布局以及cookie值在内存中存储方式的修改。但是,这些修改非常普遍,并没有使“凭证窃取”行文变得更加困难。

由于供应商未计划修复该漏洞,因此共享POC或源代码不会促进问题的解决,而是可能造成伤害或提升相关威胁。因此,我们决定不发布POC。

凭证数据(URL/用户名/密码)以明文格式存储在Chrome的内存中。除了登录特定Web应用程序时动态输入的数据外,攻击者还可以使浏览器将存储在密码管理器(“登录数据”文件)中的所有密码加载到内存中。

Cookie的数据(cookie的值+属性)以明文格式存储在Chrome的内存中(当相关应用程序被急活时),这包括敏感的会话cookie。

这些信息可以通过在本地设备上运行的标准(非提升)进程有效地提取,并直接访问Chrome的内存(使用OpenProcess+ReadProcessMemoryAPI)。

提取的数据可用于劫持用户的帐户,即使它们受到MFA机制的保护(使用“会话cookie”数据)。

Gmail、OneDrive和GitHub的示例会话劫持是“POC-ed”。

在MicrosoftEdge浏览器中发现了类似的漏洞(据推测,其他基于Chromium引擎的浏览器也会出现)。

本文描述了对浏览器的直接内存访问攻击。还有其他公开的窃取这些敏感数据的方法。

为什么这是一个重要问题:如果一个人接受“假设违规”范式,那么基于Chromium的浏览器处理敏感凭证数据的方式中的漏洞都应该被视为主要的安全风险。缓解措施应处理所有这些漏洞。

ProcessHacker工具(由WenJiaLiu编写)在这项研究中被证明非常有用。如果你怀疑某个特定字符串存储在进程的内存中,那么查找它的快速方法是:

在ProcessHacker.exe中打开该进程;

选择“内存”选项;

激活“字符串”子选项;

选择“过滤器”选项并在“包含...”框架中输入你要查找的字符串;

这是我查找已知密码时生成的输出示例(为了保密,我更改了它):

1.webp.jpg

ProcessHacker.exe在Chrome内存中识别的已知密码

如果你返回显示的内存布局(当你选择“内存”选项时),你会发现该字符串位于Private类型的内存部分中:

2.webp.jpg

查找已知密码存储在Chrome内存中的内存块

深入查看该内存块,密码存储在Private:Commit类型的内存部分中:

3.webp.jpg

查找已知密码存储在Chrome内存中的特定内存部分

根据MSDN,私有内存(MEMORY_BASIC_INFORMATIONType=MEM_PRIVATE)意味着:

4.webp.jpg

MSDN中的MEM_PRIVATE内存属性定义

人们可能会认为存储在此类内存页面中的数据不能被任何其他进程访问。令人惊讶的是,这些页面不能成为“共享内存”的一部分,但其他进程读取其中的数据没有问题(通过ReadProcessMemoryAPI)。

可以看到,上述ProcessHacker.exe作为标准进程运行,访问这些数据没有问题!

如果这些页面真的是私有的,那么这里描述的攻击向量将是不可能的。我想知道Chromium的创建者是否(在某些时候)认为敏感数据在存储在私有内存中时是安全的。

当然,在浏览器内存中查找已知字符串并不是什么大问题。寻找未知字符串怎么样?我决定只通过查看进程内存来尝试找到敏感数据(不尝试分析程序的开源代码)。

Chromium内存布局看起来像是被设计成一个“干草堆(haystack)”,因此很难找到和“理解”存储的数据(特别是密码和cookie值等敏感字符串)。我还遇到了各种蜜罐,它们看起来像是故意创建的,用于生成明文密码的误报识别。其中的困难包括:

1.相对大量的浏览器进程(例如chrome.exe)。

2.每个进程都分配了大量的虚拟内存(有些超过230GB)。

3.每个进程的内存由许多(有时数百个)“脱节”的小型已提交内存部分组成,这些部分由“保留”部分分隔。

4.大内存“组合”部分,包括许多如上所述的不相交的部分,这些部分实际上是“空的”(不是“真正”使用的)。

5.看起来像密码或cookie值的字符串(实际字符串的子字符串)。

6.将属于一个逻辑“记录”的项目(例如URL+用户名+密码)分散到远程存储位置。

这可能是所有看起来像是隐藏(“混淆”)的尝试,而只是正常操作的结果。如上所述,我没有查看代码,但我认为他们试图隐藏敏感数据。

从Chrome内存中提取的明文凭证数据类型

事实证明,通过标准的非特权进程可以很容易地从浏览器的内存中有效地提取明文凭证数据。实际上,这意味着:

1.它使用了合理数量的计算机资源(CPU能力、内存)。

2.执行在合理的时间内完成。

3.误报现象较少。

注意:当描述POC程序的部分时,我知道大多数读者会期望关键功能的技术细节和源代码片段。由于本博文结尾部分解释的原因,此信息不会被披露。已开发POC程序以提取以下类型的信息:

1、登录目标Web应用程序时使用的用户名+密码

该程序等待用户登录特定的Web应用程序(例如Gmail、OneDrive、GitHub等),然后分析捕获的内存快照以识别用于登录应用程序的用户名和密码。

这有点像一个有效的键记录程序可以实现的功能,但重要的区别是,之前存储的密码(例如,在浏览器的密码管理器工具中),它完全绕过了最初定义时没有运行的键记录程序,将被我们的程序发现。

该程序查看登录之前和之后立即拍摄的快照之间的差异,并查找仅出现在“after”内快照中并且看起来像潜在的用户名和密码字符串的新字符串。

注意:这是本研究中开发的最复杂的POC程序,它产生了相当多的误报结果,因为相当多的新字符串出现在“after”内存快照中。

排除这些假阳性案例是可能的(例如,通过识别出现在登录过程中的常见“单词”),并且如果想要努力,可以不断改进。具有讽刺意味的是,密码越强,就越容易从“噪音”假阳性案例中分离出来(例如,由小写和大写字符、数字和特殊符号组成的10个字符的字符串比只有小写字符的7个字符的字符串更有可能是密码)。

2、URL+用户名+密码在浏览器启动时自动加载到内存中

当浏览器启动时,“登录数据”文件(Chromium存储保存的密码)中的一些条目会自动加载到内存中。虽然并非“登录数据”中的所有条目都必须加载,但最近使用的条目是必须加载的。

“登录数据”数据库中的密码是DPAPI加密的,但是当它们“分散”到内存中时,它们会以明文格式保存。

与前一种情况(上面的“a”)不同,这里分析一组快照就足够了,因为加载的凭证数据静态地保留在内存中。

我们开发了一个有效的POC程序,可以从内存中提取这些数据。可能会生成少量误报项目。同样,过滤掉误报情况的算法可以得到显着和持续的改进。

3、登录数据中存储的所有URL+用户名+密码记录

可以使浏览器的密码管理器功能将其所有存储的记录加载到内存中。我们开发的POC程序可以提取所有加载的记录。在这种情况下,敏感数据以易于识别的结构排列。

因此,程序对提取的数据有很高的信心,并且在大多数情况下,几乎没有误报条目。

在这种情况下,所有保存的密码记录都加载到了Chrome的内存中。他还帮助我发现和分析了各种Chromium内存布局。

4.属于特定Web应用程序的所有cookie(包括会话cookie)

该程序等待用户登录到一个特定的应用程序(例如,Gmail, OneDrive, GitHub等)。当应用程序会话处于活动状态时,程序可以从Chrome的内存中提取属于该会话的所有cookie。这些被盗的cookie可以上传到不同设备上的浏览器中,并且会话可以被盗(绕过任何MFA机制)。

当窃取的cookie被用于劫持会话时,典型的应用程序(例如Gmail)无法识别连接是从新设备还是从新位置建立的。这是因为完全绕过了登录过程。根据cookie的内容,应用程序假定这是先前经过身份验证的会话的延续。

值得注意的是,某些应用程序鼓励其用户不要退出应用程序。例如,Gmail的会话cookie的有效期为自首次生成之日起两年。同样,MicrosoftOneDrive最近开始向其网络用户建议他们无需退出会话。在这些情况下,窃取会话cookie的攻击者可能会在很长一段时间内与真正的所有者“共享”该帐户。

误判极为罕见。

负责任的披露和供应商响应

我于2021年7月29日向Google报告了此问题:

10.webp.jpg

谷歌回应

该报告包括Gmail会话劫持的详细POC,包括从Chrome内存中提取cookie的程序的源代码。

Chromium.org的回复(WontFix)很快:

11.webp.jpg

Chromium.org以WontFix状态关闭问题

这种回应并不令人惊讶,因为其他类似“假设违规”漏洞的报告也收到了类似的回应。

14周后,Chromium公开了我的报告:

12.webp.jpg

谷歌向公众发布问题细节

总的来说,Chromium.org表示他们不会修复与物理本地攻击相关的问题,因为Chrome(或任何应用程序)没有办法防御一个以你的身份登录你的设备的恶意用户。虽然这种说法总体上可能是正确的(特别是如果你假设攻击者可以获得管理员权限),但我相信窃取敏感凭证应该不像今天这样容易。因此,如上所述,我的下一篇文章将提出几种缓解技术,使攻击更难执行。

在披露后大约一个月,我的程序未能提取cookie数据。事实证明,一般内存布局已被修改(在Chrome和Edge中)。大约两个月后,它再次失败。这一次,“敏感”数据的位置已经改变(同样,同时针对Chrome和Edge)。

最初的POC程序是为Chrome版本91.0.4472.164开发的:

13.webp.jpg

原始POC程序的Chrome版本

演示视频中的POC程序正在访问Chrome的96.0.4664.45版本:

14.webp.jpg

演示视频中用于POC程序的Chrome版本

如上所述,自从我们负责任地披露了这个漏洞以来,已经发现了内存布局以及cookie值在内存中存储方式的修改。但是,这些修改非常普遍,并没有使“凭证窃取”行文变得更加困难。

由于供应商未计划修复该漏洞,因此共享POC或源代码不会促进问题的解决,而是可能造成伤害或提升相关威胁。因此,我们决定不发布POC。

abstract_digital_router_server-1200x600.jpg

路由器(Router)是连接两个或多个网络的硬件设备,在网络间起网关的作用,是读取每一个数据包中的地址然后决定如何传送的专用智能性的网络设备。它能够理解不同的协议,例如某个局域网使用的以太网协议,因特网使用的TCP/IP协议。

路由器经常会成为被黑客攻击和感染的目标,并被用来渗透本地网络。自新冠疫情人们居家办公开始以来,路由器安全受到了更多的关注。许多公司为员工引入了远程办公,其中一些人再也没有回到办公室。如果说在大流行之前很少有人在家工作,那么现在在家工作的人的数量越来越多。

因此,攻击者现在将家庭路由器视为企业网络的网关,而公司则是潜在的攻击载体。近年来,网络设备中发现的漏洞数量急剧增加,这证明了网络设备受到越来越多的关注。

路由器的漏洞

根据 cve.mitre.org 的数据,在过去十年中,从移动设备到工业设备的各种路由器中发现的漏洞数量不断增加。然而,随着远程工作趋势的出现。在2020年至2021年期间,共发现500多个路由器漏洞。

1.png

2010-2022期间发现的路由器漏洞数量

nvd.nist.gov 网站提供了不同的数据,但它们也显示 2020 年和 2021 年发现的路由器漏洞数量显着增加。

2.png

2010-2022期间发现的路由器漏洞数量

通过分析nvd.nist.gov关于路由器漏洞的数据,我们计算出18%是关键的,超过一半(53.5%)是高优先级的。

3.png

2021 年路由器漏洞的优先级分布

关键漏洞是网关中的漏洞,入侵者可以通过这些漏洞侵入家庭或公司网络。它们使路由器更容易被黑客入侵,从而有机会获得全面的密码保护功能(例如 CAPTCHA 或有限的登录尝试次数)、运行第三方代码、绕过身份验证、向路由器发送远程命令甚至禁用它。例如,在 2022 年初,一名安全研究人员通过利用关键路由器和其他网络设备中未修补的漏洞,有效地切断了整个朝鲜的互联网。

不幸的是,并不是所有的供应商都急于修复关键的漏洞。截至撰写本文时,在2021年发布的87个关键漏洞中,超过四分之一(29.9%)的漏洞未被补丁或供应商报告:

4.png

2021年路由器厂商对产品漏洞的回应

请注意图表中的第三列:2021 年发布的所有关键路由器漏洞中有 26% 收到了供应商咨询。这些建议并不总是附带完整的补丁。在某些情况下,他们只建议易受攻击设备的所有者联系支持人员。

此外,尽管员工们或多或少已经掌握了保护笔记本电脑、台式电脑甚至移动设备的方法,但他们可能不知道如何应对针对路由器的攻击。根据英国公司Broadband Genie的一项调查,48%的用户根本没有改变路由器的任何设置,甚至包括控制面板和Wi-Fi网络密码。73%的人认为没有理由进行设置,20%的人不知道怎么做。尽管如此,路由器安全的情况正在逐渐改善:如果去年夏天 Shodan.io 使用默认密码搜索智能设备的点击量超过 27000 次,那么 2022 年 4 月的类似搜索仅返回 851 次。此外,大多数这些路由器的名称为 HACKED-ROUTER-HELP-SOS-DEFAULT-PASSWORD,表明它们已经被攻击。

5.png

2021 年 6 月 Shodan.io 搜索“默认密码”的结果

6.png

2022 年 4 月 Shodan.io 搜索“默认密码”的结果

这些结果很可能是由于许多供应商开始为每个单独的设备创建唯一的随机密码,而不是为所有设备创建标准的默认密码,任何人都可以使用。

以路由器为目标的恶意软件

为了找出攻击者攻击路由器的原因,我们首先要看看2021年物联网上测到的十大恶意软件。

7.png

2021 年,此恶意软件的攻击占对卡巴斯基物联网蜜罐的所有攻击的百分比

如表所示,大约一半的攻击属于Mirai家族。早在2016年就被发现,它仍然是感染物联网设备最常见的恶意软件。这种由路由器、智能摄像头和其他联网设备组成的僵尸网络是最持久的,因为受感染的设备无法通过任何防护技术治愈,而且用户通常不会注意到有什么地方出了问题。

Mirai僵尸网络最初是为对Minecraft服务器进行大规模DDoS攻击而设计的,后来被用于攻击其他资源。在其源代码发布后,攻击者开始传播它并使用受 Mirai 感染的设备进行 DDoS 攻击。

Mirai并不是唯一一个攻击路由器的DDoS恶意软件。2021年9月,俄罗斯公司Yandex、Sber和其他公司受到了迄今为止观察到的最大的DDoS攻击,攻击使用的是由MikroTik路由器组成的新的僵尸网络。研究人员将这种僵尸网络命名为Meris。据信,有20 - 25万台设备感染了这种新的恶意软件。

因此,攻击路由器的主要目标之一就是将它们招募到僵尸网络中以进行大规模的 DDoS 攻击。

但是我们不应该忘记路由器的主要功能:充当从本地网络到互联网的网关。攻击者可以侵入路由器,从而进入用户或公司的网络。

但是我们不应该忘记路由器的主要功能:作为从局域网到互联网的网关。攻击者可以侵入路由器,进入用户或公司的网络。这样的攻击在规模上比创建DDoS僵尸网络要小,因此它们不在最常见的路由器威胁名单中。也就是说,它们对公司来说,比 Mirai 造成的危险更多。

例如,有报道称 Sandworm APT 组织对小型办公室/家庭办公室 (SOHO) 网络设备进行了攻击。网络犯罪分子使用 Cyclops Blink 恶意软件感染了 WatchGuard 和华硕设备。尽管我们无法确定他们接下来打算做什么,但即使在出厂重置后,该恶意软件仍会保留在固件中,并使攻击者可以远程访问受感染的网络。

总结

近年来,人们对路由器安全越来越关注,主要是因为他们认为保护路由器是普通用户无法完成的任务。与此同时,远程工作允许攻击者通过利用员工家庭网络中的安全漏洞来渗透公司的基础设施。对于攻击者来说,这是一个令人垂涎的目标。

如果你想确保家庭路由器的安全,或为远程员工制定安全指南,我们建议如下:

1.将默认密码改为强密码(即长密码和复杂密码)。

2.禁用远程访问。为此,只需在接口中找到该设置并取消选中Remote Access。如果需要远程访问,在不使用时禁用它。

3.一定要更新固件。在购买路由器之前,请确保供应商定期发布固件更新,并及时安装在设备上。

4.为提高安全性,请使用静态 IP 地址并关闭 DHCP,并使用 MAC 过滤保护 Wi-Fi。所有这些都会使攻击过程变得更长、更复杂,因为你需要手动设置任何其他设备连接。但是攻击者要进入本地网络要困难得多。