接上篇:
内核地址泄漏
在绝大多数漏洞利用中,攻击者使用内核指针泄漏原语来调整漏洞利用。在除CVE-2019-1458之外的所有漏洞利用中,此泄漏原语都是众所周知的HMValidateHandle技术。
HMValidateHandle()是user32.dll的内部未导出函数,可通过isMenu()等各种函数加以利用,并且可用于获取所有Windows版本(直到Windows10RS4)中不同Window对象的内核地址。这项技术是众所周知的,甚至早在2011年就已使用,因此大多数开发教程都选择专门解析isMenu()来查找HMValidateHandle()的地址。
令人惊讶的是,在可用于查找HMValidateHandle()的数十种不同函数中,攻击者只是按照众所周知的教程选择了也使用isMenu()。更令人惊讶的是,这种常见的利用技术多年来仍然很有效,没有激励攻击者通过选择更先进的诸如CheckMenuRadioItem()来尝试“隐藏”。
该泄漏为研究人员提供了以下痕迹信息:
- 窗口的内核地址;
- THREAD_INFO的内核地址(pti字段);
在利用过程中的多个步骤中将使用此痕迹信息:
- 在指向/创建伪内核结构时使用地址;
- 确保研究人员的内核地址是有效的Unicode字符串(不包含两个连续的“\x00”字节);
- pti用于定位有效的EPROCESS,然后在令牌交换阶段使用它;
与PlayBit的比较:PlayBit选择通过直接访问用户模式桌面堆来实现此函数。
令牌互换
该攻击的最终目标是根据给定的PID参数将系统特权授予所需的进程,按着常规的思路实现这一点的方法是用系统进程的令牌替换EPROCESS/KPROCESS结构中的进程的令牌。
下面有一些常用的技术可以做到这一点,你会惊讶地发现有这么多不同的选项可以实现此函数。
使用Ps符号
Windows内核包含以下函数和与进程相关的函数的全局变量:
- PsLookupProcessByProcessId:检索指向进程的EPROCESS的指针;
- PsInitialSystemProcess:包含指向系统EPROCESS的指针的全局变量;
- PsReferencePrimaryToken–返回一个指向进程主要令牌的指针;
通过以内核模式执行这些函数,给定的shellcode可以轻松定位SYSTEM的令牌,但仍不能解决如何在所需的EPROCESS中分配令牌的问题。
有两种常见的解决方案:
- 使用特定于版本的偏移量直接在EPROCESS中访问正确的偏移量;
- 扫描EPROCESS以查找研究人员自己的指针(先前调用PsReferencePrimaryToken所知道的指针),并在找到匹配项后替换该条目;
此技术需要以内核模式执行代码,因此除非部署了其他SMEP绕过,否则它将被SMEP保护阻止。
扫描PsList
查找目标进程和系统进程的EPROCESS的常见替代方法是扫描被称为PsList的双链接进程列表,此技术涉及的步骤为:
- 使用泄漏的pti字段,定位初始EPROCESS;
- 扫描PsList以查找具有目标PID的EPROCESS;
- 通过查找PID为4或名称为SYS来扫描PsList,以搜索SYSTEM的EPROCESS;
- 提取令牌并将其放置在目标进程中的匹配偏移量中;
谨慎更新SYSTEM令牌的引用计数。
Volodya漏洞利用Arbitrary-Read原语搜索SYS,如Cutter所示
这种技术需要PsList的主令牌和LIST_ENTRY的偏移量,基本上要求它们都作为版本特定配置的一部分进行存储。
该技术的主要优点是,尽管它仍可以在内核模式下作为简单的shellcode执行,如在CVE-2017-0263的利用中所做的那样),但它也可以在用户模式下完全实现。为此,你需要两个利用原语,一个用于任意读取(来自内核空间),另一个用于任意写入(进入内核空间)。在用户模式下运行可以解决研究人员之前针对SMEP所详述的问题,从而使这种保护对于这种利用原语毫无用处。
由于令牌是一个引用计数对象,因此正确注册刚添加的引用非常重要,这样可以避免在提升进程终止时出现蓝屏死亡(BSOD)。实际上,有两个不同的引用计数:
- 令牌是一个EX_FAST_REF对象,较低的指针位被用作引用计数;
- OBJECT_HEADER存储在令牌之前,并保留另一个引用计数;
由于攻击者选择更新后一个引用计数字段,因此需要执行以下步骤:
- 屏蔽掉令牌指针的引用计数位:在32位进程中应对齐8个字节,在64位进程中应对齐16个字节。
- 减去指向OBJECT_HEADER的引用计数字段所需的常量;
- 读取值(使用任意读取漏洞利用原语);
- 相应地增加它;
- 回写更新后的值;
但是,如图9所示,研究人员在包含此函数的所有32位漏洞利用程序中发现了以下漏洞:
32位漏洞利用中的引用计数更新中实现的漏洞
读取引用计数值时的对齐掩码为8字节的对齐方式,而回写更新后的值时使用不同的掩码。如果令牌将存储在对齐8个字节而不对齐16个字节的内存地址中,则写入操作将更新漏洞的字段。
尽管CVE-2016-0040和CVE-2016-0167使用Ps技术,但到目前为止,扫描PsList是研究人员发现的攻击者最喜欢的执行令牌交换的方式了,在他们的8种利用中都使用了这种方式。在其中的7个中,他们使用了用户模式下的任意读取和任意写入。
与PlayBit的比较:在他们的所有示例中,研究人员会经常看到PlayBit使用Ps函数进行令牌交换。这个决定迫使攻击者采取了一些SMEP绕过措施,将它们集成到CVE-2016-7255和CVE-2018-8453的后续漏洞中。这种设计选择说明了为什么攻击者不愿意将适当的任意读取原语作为漏洞利用的一部分。PlayBit始终使用0x300或0x600作为搜索上限,不是对EPROCESS中的令牌偏移使用特定于版本的配置,而是始终扫描EPROCESS进行搜索。
值得注意的是,PlayBit在不同漏洞利用中使用的内存损坏技术也被Duqu2.0使用,并在微软于2015年发布的VB演讲中进行了分析。通过这种内存损坏,它们可以触发一些内存读取/写入操作。
PlayBit漏洞扫描EPROCESS以搜索令牌,如Cutter所示
尽管研究人员还可以从其他方面来讨论这个问题,例如每个攻击者在开发过程中喜欢使用的不同系统调用,对Windows和ScrollBars之类的已创建对象的命名约定。但研究人员相信上面的列表已经清楚地证明了研究人员方法的效率或有效性。从上面的列表可以看出,几乎每个漏洞的每个方面都可以通过几种不同的方式实现。尽管如此,研究人员所发现的两个攻击者在各自使用的攻击方法上都非常一致,每个人都坚持自己喜欢的方式。
在整个研究过程中,研究人员希望专注于漏洞编写者本身,无论是Volodya,PlayBit还是其他人。但是,研究人员认为,通过查看漏洞利用开发者的客户群,也有很多值得学习的东西。Volodya的客户列表各不相同,包括Ursnif等银行木马开发者,GandCrab,Cerber和Magniber等勒索软件开发者,以及Turla,APT28和Buhtrap等APT组织,这些组织最初从事网络犯罪,后来都发展为网络间谍活动。有趣的是,研究人员可以看到Volodya的零日漏洞更有可能卖给PT组织,而一日漏洞是由多个犯罪软件组织购买的。由于没有更多的信息,研究人员只能假设一旦安全行业检测到零日漏洞,该漏洞便被回收并以较低的价格出售。
APT的客户Turla,APT28和Buhtrap都通常来自于俄罗斯,而且有趣的是,即使是这些高级团队也购买了漏洞利用程序,而不是内部开发。这些事实进一步加强了研究人员的假设,即书面漏洞(written exploit)利用可以被视为恶意软件的被利用的前奏。
下表总结并显示了来自于Volodya的CVE,以及使用这些漏洞发现的客户或恶意软件组。标有蓝色的CVE为零日漏洞,自然更昂贵。左侧突出显示的组被视为APT。
Volodya的客户和他们使用的CVE
综上所述,研究人员在检查了一段时间内的漏洞样本后发现,他们还不能讨论还没有发现的零日漏洞。此外,研究人员只能尝试将示例的日期追溯到被捕获之前的时期,但可悲的事实是,研究人员通常会确定在野外首次发现这种攻击行为的日期。此外,值得一提的是,Volodya在开发CVE-2015-2546的第一个漏洞时,从一开始就已经非常专业了。例如,它有一个唯一的任意编写原语,研究人员无法跟踪到任何其他漏洞利用指南。
在对漏洞利用程序进行分析以及对研究人员收集的数十个恶意软件示例进行分析期间,研究人员注意到了一个有趣的变化。早期的Volodya漏洞是作为嵌入到恶意软件中的源代码出售的,而后期的漏洞利用程序则作为接受某个API的外部实用程序来出售,这种变化可能表明Volodya正在采取更多的反检测措施。
在2015年至2019年的这段时间内,研究人员还注意到Volodya的技术技能有了显着改善。随着该组织变得更好和更有经验,Volodya开始使用更有效的任意读写原语,他们甚至修复了这些原语之间的错误。
CVE-2015-2546和CVE-2016-0165,而且,随着大型函数被拆分为较小的子例程,漏洞利用代码变得更加模块化。此外,他们在各种结构中搜索和访问特定偏移量的技术也得到了改进,并且在最近的实现中,它可以更好地处理Windows次要版本中的更改,因此变得更加动态和安全。
这不仅显示了攻击者的学习能力愈来愈强,也暗示了他们的技能也在提高。查找并可靠利用Windows内核漏洞的能力确实不是那么简单。相比之下,研究人员可以看到PlayBit在2015-2018年期间在这个市场上非常活跃,他们的重点是出售一日漏洞,其中之一是Volodya的零日漏洞(CVE-2016-7255)。
总结
研究人员的研究方法是对漏洞利用开发者的特征进行线索识别,然后再将这些特征用作唯一的搜索签名。在追踪Volodya和PlayBit的漏洞时,研究人员两次使用了这项技术。有了这两个成功的测试示例,研究人员相信该研究方法可用于搜索其他漏洞利用程序开发者。研究人员建议其他研究人员尝试本文讲的技术,并将其用作其武器库中的其他工具。
在此研究过程中,研究人员重点研究了APT攻击和流行的恶意软件(尤其是勒索软件)中不同恶意软件家族所使用或嵌入的漏洞。
研究人员能够反复使用研究人员的技术来跟踪由两个不同攻击者编写和出售的16种WindowsLPE漏洞,这一点非常令人惊讶。考虑到其中有15个是在2015-2019年的时间范围内,因此可以假设它们构成了漏洞利用市场的重要份额,尤其是WindowsLPE漏洞。
最后,研究人员不可能知道Windows内核零日漏洞的总量。话虽如此,研究人员仍然可以通过回顾所捕获的漏洞窥一斑而知全豹。去年,卡巴斯基报告,有一个攻击者传播了一个漏洞利用框架,其中包括另外3个零日漏洞。将这些数字加起来,研究人员发现15个零日漏洞中有8个(占“市场份额”的一半以上)仅来自于两个开发团队。这意味着研究人员的研究技术有可能被用来追踪可见市场中的许多攻击者。
本文翻译自:https://research.checkpoint.com/2020/graphology-of-an-exploit-volodya/