CVE-2021-23017:nginx DNS解析漏洞PoC公开

admin 2021年9月1日20:12:44评论395 views字数 2282阅读7分36秒阅读模式

CVE-2021-23017:nginx DNS解析漏洞PoC公开

漏洞评级

高危漏洞

确认受影响版本

0.6.18 - 1.20.0

确认修复版本

1.21.0、1.20.1

厂商

F5, Inc

厂商官网

https://nginx.org/

厂商参考资料

https://mailman.nginx.org/pipermail/nginx-announce/2021/000300.html

漏洞CVE

CVE-2021-23017

CWE

193

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 += n;
            src += n;

// 2) read next character,

            n = *src++;
// 3) as its a pointer, its not NUL,

            if (n != 0) {

// 4) so a dot character that was not accounted for is written out of bounds

                *dst++ = '.';
            }
// 5) Afterwards, the pointer is followed,
        if (n & 0xc0) {
            n = ((n & 0x3f) << 8) + *src;
            src = &buf[n];
            n = *src++;
        }

// 6) and a NULL byte is found, signaling the end of the function
        if (n == 0) {
            name->len = dst - name->data;
            return NGX_OK;
        }

如果计算出的大小正好与堆块大小对齐,则写入的点字符超出边界,将覆盖下一个堆块大小元数据的最低有效字节。这可能会修改下一个堆块的大小,但也会覆盖3个标志,从而清除PREV_INUSE并设置IS_MMAPPED。

考虑到nginx中与用户控制器数据的丰富交互机会以及记录在案的先例,这个漏洞将有可能允许攻击者在某些操作系统和体系结构上执行远程代码。

漏洞利用PoC

漏洞利用PoC下载地址:

https://github.com/x41sec/advisories/blob/master/X41-2021-002/poc.py

广大研究人员可以通过valgrind并运行nginx来对该漏洞进行测试:

valgrind --trace-children=yes objs/nginx -p ../runtime -c conf/reverse-proxy.conf

接下来,运行DNS服务器(默认监听端口1053):

python poc.py

触发请求并发送至目标服务器:

curl http://127.0.0.1:8080/

根据漏洞被触发时的堆内存布局,可能会出现几种不同形式的日志:

corrupted size vs. prev_size

2021/04/16 13:35:15 [alert] 2501#0: worker process 2502 exited on signal 6 (core dumped)

malloc(): invalid next size (unsorted)

2021/04/16 13:35:34 [alert] 2525#0: worker process 2526 exited on signal 6 (core dumped)

不过,valgrind和AdressSanitizer都是能够检测到这种内存崩溃事件的。

本文始发于微信公众号(盾山实验室):CVE-2021-23017:nginx DNS解析漏洞PoC公开

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年9月1日20:12:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2021-23017:nginx DNS解析漏洞PoC公开https://cn-sec.com/archives/398067.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息