CVSS评分
8.1
漏洞概述及影响
在处理DNS响应时,ngx_resolver_copy()中的一个off-by-one错误将允许网络攻击者在堆分配的缓冲区中写入超出边界的点字符(‘.’, 0x2E)。配置解析程序原语时,响应nginx服务器DNS请求的DNS响应可能会触发该漏洞。精心构造的数据包可以通过使用0x2E覆盖下一个堆块元数据的最低有效字节,此时,能够向nginx服务器提供DNS响应的网络攻击者可以实现拒绝服务攻击或远程代码执行攻击。
由于nginx中缺少DNS欺骗防御措施,并且在检查DNS事务ID之前调用了易受攻击的函数,因此远程攻击者可以通过在可行的时间内向目标服务器发送恶意DNS响应来利用该漏洞实施攻击。
漏洞成因分析
nginx的DNS解析器(core/ngx_resolver.c)可以在设置解析器原语时,通过DNS解析多个模块的主机名。
ngx_resolver_copy()会被调用以验证和解压缩DNS响应中包含的每个DNS域名,接收作为输入的网络包和指向正在处理的域名的指针,并在成功时返回指向包含未压缩域名的新分配缓冲区的指针。整个过程分为两步执行:
计算未压缩域名的大小len并验证输入数据包,丢弃包含128个以上指针或超出输入缓冲区边界指针的域名。
分配一个输出缓冲区,并将未压缩的域名复制到其中。
第1部分中的大小计算和第2部分中的域名解压之间的不匹配会导致len中的off-by-one错误,从而允许在name->data数据边界之外写入一个点字符。
当压缩域名的最后一部分包含指向NULL字节的指针时,就会发生计算错误的情况。虽然计算步骤只考虑标签之间的点,但每次处理标签并且下一个字符不是NULL时,解压缩步骤都会写入一个点字符。当标签后跟指向NULL字节的指针时,解压缩过程将如下:
// 1) copy the label to the output buffer,
ngx_strlow(dst, src, n);
dst +=