DNS重绑定攻击漏洞报告
漏洞概述
在SSRF过滤器中存在DNS重绑定漏洞。该库验证主机名的IP地址,但随后将主机名传递给Net::HTTP.start(),后者会执行自己的DNS查询。攻击者可以控制DNS服务器,在验证期间返回安全的公共IP,然后在Net::HTTP稍后解析时返回127.0.0.1。
技术细节
漏洞代码
|
|
攻击原理
攻击者设置evil.com的DNS以交替响应:
- 第一次查询(验证期间)返回8.8.8.8
- 第二次查询(Net::HTTP内部查找)返回127.0.0.1
结果:SsrfFilter.get('http://evil.com:6379')绕过所有保护并访问本地主机上的内部服务。
修复方案
建议修复
直接连接到验证的IP而不是主机名:
- 将
Net::HTTP.start(uri.hostname, ...)改为Net::HTTP.start(validated_ip, ...) - 手动设置Host头:
headers['Host'] = uri.hostname - 使用
ssl_hostname: uri.hostname进行正确的TLS证书验证
版本对比分析
v1.1.2(安全)
|
|
Net::HTTP直接接收验证过的IP地址,防止DNS重绑定攻击。
v1.3.0(存在回归漏洞)
移除了uri.hostname = ip行,仅添加了ipaddr: ip到选项。Net::HTTP接收主机名而不是IP,允许DNS重绑定。
Ruby版本影响
Ruby 2.6.10
ipaddr参数被完全忽略- v1.1.2仍然安全,因为它使用
uri.hostname = ip方法
Ruby 3.3.0
ipaddr参数正常工作并防止DNS解析- v1.3.0传递原始主机名给Net::HTTP,完全依赖
ipaddr参数进行保护
概念验证代码
提供了完整的测试脚本,演示:
- v1.1.2的安全行为
- 当前主分支的漏洞行为
ipaddr选项不防止DNS解析的证据
防御建议
采用深度防御方法:
- 恢复v1.1.2中的
uri.hostname = ip行 - 与
ipaddr参数结合使用 - 提供两个独立的保护层
影响评估
该漏洞允许攻击者通过DNS重绑定绕过SSRF保护,访问内部服务,严重性评级为关键(10.0)。