Nginx暴露危漏洞CVE-2021-23017

日前著名Web服务器和反向代理服务器Nginx暴严重漏洞NS解析器Off-by-One堆写入漏洞,该漏洞存在于Nginx的DNS解析模块ngx_resolver_copy()。攻击者可以利用该漏洞进行远程DDos攻击,甚至远程执行。

概述

ngx_resolver_copy()在处理DNS响应时出现一个off-by-one错误,利用该漏洞网络攻击者可以在堆分配的缓冲区中写一个点字符(.’, 0x2E)导致超出范围。 所有配置解析器语法的(resolver xxxx)Nginx实例可以通过DNS响应(响应来自Nginx的DNS请求)来触发该漏洞。 特制数据包允许使用0x2E覆盖下一个堆块元数据的最低有效字节,利用该漏洞攻击者,可以实现Ddos拒绝服务,甚至可能实现远程代码执行。

由于Nginx中缺乏DNS欺骗缓解措施,并且在检查DNS事务ID之前调用了易受攻击的功能,因此远程攻击者可能能够通向中毒服务器注入受毒的DNS响应来利用此漏洞。

漏洞影响

严重等级: 高

漏洞向量: 远程/DNS

确认的受影响版本: 0.6.18-1.20.0

确认的修补版本: 1.21.0,1.20.1

供应商: F5,Inc.

状态: 公开

CVE: CVE-2021-23017

CWE: 193

CVSS得分: 8.1

CVSS向量:CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C

漏洞分析

当Nginx配置中设置resolver时,Nginx DNS解析器(core/ngx_resolver.c)用于通过DNS解析多个模块的主机名。

Nginx中通过ngx_resolver_copy()调用来验证和解压缩DNS响应中包含的每个DNS域名,接收网络数据包作为输入和指向正在处理的名称的指针,并在成功后返回指向包含未压缩名称的新分配缓冲区的指针。调用整体上分两步完成的,

  • 计算未压缩的域名大小的长度len并验证输入包的合法性,丢弃包含大于128个指针或包含超出输入缓冲区边界的域名。
  • 分配输出缓冲区,并将未压缩的域名复制到其中。

第1部分中的大小计算与第2部分中的未压缩的域名之间的不匹配,导致一个len的一个off-by-one错误,导致允许以一个字节为单位写一个点字符超出name->data的边界。

当压缩名称的最后一部分包含一个指向NUL字节的指针时,就会发生计算错误。 尽管计算步骤仅考虑标签之间的点,但每次处理标签并且接着的字符为非NUL时,解压缩步骤都会写入一个点字符。当标签后跟指向NUL字节的指针时,解压缩过程将:

  1. // 1) copy the label to the output buffer, 
  2. ngx_strlow(dst, src, n); 
  3. dst += n; 
  4. src += n; 
  5. // 2) read next character, 
  6. n = *src++; 
  7. // 3) as its a pointer, its not NUL, 
  8. if (n != 0) { 
  9. // 4) so a dot character that was not accounted for is written out of bounds 
  10. *dst++ = '.'; 
  11. // 5) Afterwards, the pointer is followed, 
  12. if (n & 0xc0) { 
  13. n = ((n & 0x3f) << 8) + *src; 
  14. src = &buf[n]; 
  15. n = *src++; 
  16. // 6) and a NULL byte is found, signaling the end of the function 
  17. if (n == 0) { 
  18. name->len = dst - name->data; 
  19. return NGX_OK; 

如果计算的大小恰好与堆块大小对齐,则超出范围的点字符将覆盖下一个堆块长度的元数据中的最低有效字节。这可能会直接导致下一个堆块的大小写入,但还会覆盖3个标志,从而导致 PREV_INUSE被清除并 IS_MMAPPED被设置。

  1. ==7863== Invalid write of size 1 
  2. ==7863== at 0x137C2E: ngx_resolver_copy (ngx_resolver.c:4018) 
  3. ==7863== by 0x13D12B: ngx_resolver_process_a (ngx_resolver.c:2470) 
  4. ==7863== by 0x13D12B: ngx_resolver_process_response (ngx_resolver.c:1844) 
  5. ==7863== by 0x13D46A: ngx_resolver_udp_read (ngx_resolver.c:1574) 
  6. ==7863== by 0x14AB19: ngx_epoll_process_events (ngx_epoll_module.c:901) 
  7. ==7863== by 0x1414D4: ngx_process_events_and_timers (ngx_event.c:247) 
  8. ==7863== by 0x148E57: ngx_worker_process_cycle (ngx_process_cycle.c:719) 
  9. ==7863== by 0x1474DA: ngx_spawn_process (ngx_process.c:199) 
  10. ==7863== by 0x1480A8: ngx_start_worker_processes (ngx_process_cycle.c:344) 
  11. ==7863== by 0x14952D: ngx_master_process_cycle (ngx_process_cycle.c:130) 
  12. ==7863== by 0x12237F: main (Nginx.c:383) 
  13. ==7863== Address 0x4bbcfb8 is 0 bytes after a block of size 24 alloc'd 
  14. ==7863== at 0x483E77F: malloc (vg_replace_malloc.c:307) 
  15. ==7863== by 0x1448C4: ngx_alloc (ngx_alloc.c:22) 
  16. ==7863== by 0x137AE4: ngx_resolver_alloc (ngx_resolver.c:4119) 
  17. ==7863== by 0x137B26: ngx_resolver_copy (ngx_resolver.c:3994) 
  18. ==7863== by 0x13D12B: ngx_resolver_process_a (ngx_resolver.c:2470) 
  19. ==7863== by 0x13D12B: ngx_resolver_process_response (ngx_resolver.c:1844) 
  20. ==7863== by 0x13D46A: ngx_resolver_udp_read (ngx_resolver.c:1574) 
  21. ==7863== by 0x14AB19: ngx_epoll_process_events (ngx_epoll_module.c:901) 
  22. ==7863== by 0x1414D4: ngx_process_events_and_timers (ngx_event.c:247) 
  23. ==7863== by 0x148E57: ngx_worker_process_cycle (ngx_process_cycle.c:719) 
  24. ==7863== by 0x1474DA: ngx_spawn_process (ngx_process.c:199) 
  25. ==7863== by 0x1480A8: ngx_start_worker_processes (ngx_process_cycle.c:344) 
  26. ==7863== by 0x14952D: ngx_master_process_cycle (ngx_process_cycle.c:130) 

虽然目前还没有Poc出来,理论上该漏洞可以被用来进行远程代码执行。

攻击向量分析

DNS响应可以通过多种方式触发漏洞。

首先,Nginx必须发送了DNS请求,并且必须等待响应。 然后,可以在DNS响应的多个部分进行投毒:

  • DNS问题QNAME,
  • DNS回答名称,
  • DNS会回答RDATA以获得CNAME和SRV响应,
  • 通过使用多个中毒的QNAME,NAME或RDATA值制作响应,可以在处理响应时多次击中易受攻击的函数,从而有效地执行多次脱机写入。

此外,当攻击者提供中毒的CNAME时,它将以递归方式解决,从而在执行过程中触发了额外的OOB写操作 ngx_resolve_name_locked() 调用ngx_strlow()(ngx_resolver.c:594)和其他OOB读取期间 ngx_resolver_dup()(ngx_resolver.c:790)和 ngx_crc32_short()(ngx_resolver.c:596)。

用于“example.net”请求的DNS响应示例负载,其中包含被污染的CNAME:

稍微不同的有效负载(poc.py中的有效负载)填充了足够的字节以覆盖 next_chunk.mchunk_size带点的最低有效字节:

24字节的标签导致分配了24字节的缓冲区,该缓冲区填充有24字节+一个超出范围的点字符。

漏洞修复和解决

通过向域名解析时,在域名末尾写入的伪造的点字符分配一个额外的字节可以缓解此问题。

受漏洞影响的配置

  1. daemon off; 
  2. http{ 
  3. access_log logs/access.log; 
  4. server{ 
  5. listen 8080; 
  6. location / { 
  7. resolver 127.0.0.1:1053; 
  8. set $dns example.net; 
  9. proxy_pass $dns; 
  10. events { 
  11. worker_connections 1024; 

 

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/136534.html<

(0)
管理的头像管理
上一篇2025-03-02 03:22
下一篇 2025-03-02 03:23

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注