图片:未飞溅如上
一篇有关
CVE-2019-0726的 文章 所述 ,有时搜索有关已知漏洞的详细信息会导致发现新漏洞。 在某些情况下,不只一个这样的新漏洞。
本文研究了dhcpcore.dll库的两个功能:偶然提到的UpdateDomainSearchOption和对其调用的DecodeDomainSearchListData的更详细的分析。 搜索漏洞时总是发生,即使最后重要的结论归结为一个或两个函数,在解析过程中,您也必须查看大量的代码。 有时,眼睛会紧贴琐事,这些琐事与当前任务无关,但可能具有独立意义或以后派上用场。 假设目前没有时间关注它们,但是这些琐事在皮层下被推迟了,如果经过一定时间后有机会回到他们那里并检查他们的猜测,他们又会突然意识到。
因此,这一次发生了。 在研究DhcpExtractFullOptions函数时,该函数负责处理来自服务器的DHCP响应中指定的所有选项,尤其是调用UpdateDomainSearchOption时,在256个元素的堆栈中的两个数组每个立即引起注意:

同时,没有任何限制这些数组的迭代器值的检查的存在。 由于那时我们正在分析另一个漏洞,因此此信息无关紧要。 因此,仅需记住代码中的这个位置,以便稍后返回。
分析方法
几周后,我们再次回想起早先引起注意的DhcpExtractFullOptions函数。 我们在反汇编程序中进行介绍,梳理先前未完全框架的代码段,并尝试了解为什么我们使用两个吸引我们的静态数组。
在函数执行的最开始,数组及其迭代器将清零:

该功能解析从DHCP服务器接收到的数据包中的所有选项,从中收集信息,然后进行处理。 此外,根据分析结果,她还将相应事件写入ETW(Windows事件跟踪)服务。 在事件日志记录中,我们感兴趣的缓冲区会参与其中。 它们与许多其他数据一起被传输到EtwEventWriteTransfer过程。 准备所有数据以进行日志记录的工作非常繁琐,并且对于我们正在考虑的漏洞没有多大影响,因此我们无需做任何说明。
确定如何填充这些缓冲区更为重要。 填充发生在选项解析循环中。 首先,对于当前要接收的要处理的选项,调用口语名称为ParseDhcpv4Option的函数,该函数要么根据接收的数据填充dhcp_pointers对象的字段,要么在遇到选项标识符且其值没有处理程序时记录不熟悉的选项。

从ParseDhcpv4Option返回后,当前option_tag的标识符值将写入all_tags数组的下一个元素,即我们感兴趣的第一个数组。 如果函数遇到未知选项,因此未设置is_known_option标志,则标识符值也将写入第二个数组的下一个元素-unknown_tags。 自然地,通过分析代码已经获得了本文中变量的有意义的名称。
因此,all_tags数组存储接收到的消息中所有选项的标签,而unknown_tags数组仅存储解析器不熟悉的选项的标签。 同时,根本没有验证这些数组的索引值。 因此,此类索引的值可能会超过256,并导致写入超出为内存阵列分配在堆栈上的限制。 为了使第一个阵列过满,从DHCP服务器发送选项数量超过256个的数据包就足够了,第二个阵列也是如此,唯一的区别是应该发送客户端无法处理的选项。
运作方式
现在让我们尝试使用一个实际的例子来确保我们的结论是正确的。 首先,我们注意一个事实,即选项标签占据一个字节,而数组元素的类型为int,即它们为四个字节。 因此,我们有一个溢出,其中我们控制每个第四个字节,而其余的则在重写时重置为零。

为了检验我们的假设,最简单的方法是在相关功能上覆盖安全性cookie,这将引发与安全性检查相关的异常。 让我们模拟DHCP服务器发送足够数量的选项进行重写的情况。 使其成为0x1a0(416)选项,标识符为0xaa,大小为零。 因此,每个选项占用两个字节,并且所有标头的总数据包大小为1100-1200字节。 该值在以太网的
MTU范围内,因此,有理由相信该消息不会被分段,这将使我们避免可能的不利影响。
我们响应于DHCP客户端的请求发送以上述方式形成的数据包,并在客户端计算机上相应的svchost.exe进程中捕获异常:

从堆栈跟踪中可以看到,堆栈cookie和函数的返回地址都被包中选项的标识符重写。
当然,针对此错误创建有效的利用程序将需要攻击者付出大量努力。 在现代系统上,由于所有现有防御机制,堆栈上的缓冲区溢出是一个相当复杂且需要大量人力的漏洞。 另一方面,不应忘记所有这些机制要么防止重写返回地址和异常处理程序,要么禁止在不打算用于此目的的内存区域中执行代码,或者干扰地址预测。 例如,它们无法以任何方式来覆盖覆盖溢出缓冲区和局部变量的返回地址之间的堆栈中存储的内容。 并且有问题的DhcpExtractFullOptions函数在此间隔中包含几个潜在的危险变量。
同样,我们将检测到的错误写给Microsoft。 经过大约一周的简短通信和对应用程序的分析,我们得到的答案是,正在为所描述的漏洞准备CVE标识符,计划在3月发布修复程序,并且有关该漏洞的信息已在Microsoft处获得,据某人先前报道。 一般来说,这一事实不足为奇,因为该错误实际上位于表面上,并且不包含索引边界检查的缓冲区始终首先引起人们的注意,并且通常可以由自动分析工具检测到。
正如所宣布的那样,3月发布了更新以更正所描述的错误,该更新收到标识
CVE-2019-0697 。 先前报告的研究员原来是Mitch Adair,同一位Microsoft员工曾在1月发现DHCP漏洞
CVE-2019-0547 。
积极技术应用分析专家Mikhail Tsvetkov
发布 。