许多nginx用户会使用Google 公共 DNS,OpenDNS 或ISP 的解析器解析器等解析程序指令来配置 nginx,但是这当中存在很大的风险,唯一安全的选择是在本地主机上运行一个解析器。 我发现,不仅 nginx 的存根 (stub) 解析器会生成非随机的或可预见的 DNS txids,连每个 nginx 的工作进程都会在每个 DNS 查询中使用相同的 UDP 源端口。 只要使用一个简短的脚本就可以在Linux (GNU C 库) 中预测Nginx 的 txids。 这些缺陷允许恶意攻击者发送欺骗性的 DNS 回复去感染解析程序缓存,导致 nginx 代理 HTTP 会向任何攻击者指定的上游服务器发送请求,从而访问到浏览器的恶意内容。 奇怪的是 nginx 开发人员并不认为这存在任何安全问题。在我向 [email protected] 报告之后,他们只修补一部分问题并且拒绝修补其他问题,也没有发布安全咨询。所以我觉得必须要公开我的调查结果,告知nginx 用户他们所面临的潜在风险 。 细节 Nginx 生成 DNS txids所使用的是用于在 Linux/Unix 上random() 和在 Windows 上 rand () 的宏ngx_random() 。 问题 1: 在 Windows 上,nginx 从来没有通过 srand()发送种子 PRNG ,所以 C盘会默认为 1,导致 txids 总是遵循同样的次序,而不是随机种子︰ 41,18467,6334、 26500,19169,15724...... 问题 2: 在 Linux 上,对于random() 的依靠使得 txids 变得可预测,因为特定配置下的 nginx 会将random() 值泄漏给远程用户:当ngx_mail_core_module 启用时通过 SMTP/POP3/IMAP CRAM-MD5盐功能,或有时会通过标头暴露客户的$request_id 变量。 问题 3; 在所有平台上,nginx的每个工作进程都允许 OS 选择随机的 UDP 源端口发送 DNS 查询。工作进程会重用遍又一遍的在同一端口发送所有查询,直到 nginx 重新启动。既然猜测 txid是可行的,攻击者只需要蛮力进入源端口就可以感染 nginx 的解析程序缓存。OS TCP/IP 堆栈通常会从Linux中的一系列的 28232 个端口和Windows 上的16384个 端口中选择。攻击者可以一次性确认正确端口。随后,他就可以使用一个假DNS 答复进行攻击,因为端口已知,txid也是可预测的。 攻击场景 首先,成功感染 nginx 的 DNS 缓存的要求是,攻击者需要︰ •知道nginx 尝试解析的主机名 ; •知道配置nginx 所使用的解析器 。 场景 1 此方案演示如何利用问题 1。 使用下面的nginx.conf 在 Windows 上运行Nginx︰
如果 Nginx 实例相对繁忙 (例如说每两次或更多次才能处理一个请求,以保持 nginx 每次在缓存项过期后不断解决后端名称问题),那么︰ 1.攻击者可以看到后端的主机名,并且能看见1 小时之内的TTL 。 2.现在他可以确定,当启动 nginx 代理第一次请求 t = 0时,它会用txid = 41发出一个 DNS 查询等。这是因为,正如我刚才所解释的那样,在 Windows 中nginx 未能种子 PRNG,因此始终会生成相同的序列。 3.攻击者确定 nginx 什么时候会启动,也知道它会用哪个txid来发送下一个 DNS 查询。 4.攻击者等待后端的 IP 地址在nginx 的缓存中过期。例如这可能在 t = 100 h发生,那么攻击者就会知道 nginx 将使用随机值序列中第 101随机值由 rand () 返回。当它再缓存中过期时,nginx可能需要几百毫秒查询 8.8.8.8才能作出答复。在同一时间攻击者可以随机地将多个诈骗 DNS 回复与预测 txid 发送到不同的 UDP 端口,在这段时间里他能够发送 1000次诈骗答复。 5.第一次的中毒尝试将可能失败,因为 Windows 从一系列的 16384 端口 (49152 – 65535)中只选择一个源端口。所以如果他失败了,攻击者下次尝试会再从 nginx 的缓存过期后端的 IP 地址进行无限量的尝试。 6.Nginx 将然后代理攻击者服务器的所有请求,直到 TTL 过期。下一次感染尝试就会简单得多,因为此时攻击者已经知道哪一组端口是无效的。 截至 2016 年 8 月 24 日,这种攻击在发布到目前为止的所有 nginx 版本上都有效。我的报告公布后,开发人员在 2016 年 8 月 4 日进行了修补,因此即将发布的1.11.4版本应该会包括此修复程序。然而 nginx 开发人员认为这不是一个安全漏洞,尽管一切都那么显而易见。 场景2 此方案演示如何利用问题 2。 它需要使用CRAM-MD5验证启用 (不是默认)将nginx 配置为 SMTP、 POP3 或 IMAP 这样它才能将$request_id 报告给客户端。 我选择在这里展示使用 SMTP 的终结点在 Linux/Unix 上运行Nginx的过程︰
最新评论
72小时资讯榜
2
群晖NAS出现重大漏洞 未及时更新会被C3RB3R
网安动态
196人已阅读
3
突发:全球最大的加密交易所币安热钱包被黑
网安动态
207人已阅读
4
高能预警:PHP惊现9.2级致命漏洞、Node.js
网安动态
513人已阅读
5
不买服务器也能异地组网:开源P2WLAN让两地
软件精选
1753人已阅读
6
AI真相:中国Token消耗第一是做短剧,美国T
AI动态
1078人已阅读
社区热门
1
━※☆※━★===二〇二六年论坛每日签到帖=
2026-03-13
2
凭“水”相逢现代汉语四字词语反接龙 回复
2026-10-27
3
2006年注册的老人泪流满面
2026-10-12
4
十几年没回来了,回来看看。顺便做个记号
2026-08-15
5
多年以后我又回来了,报道贴
2026-08-11
6
人工智能最终是否替代人类??人类该何去何
2026-07-22
|