SSRF漏洞攻防实战:从原理到绕过技巧与防御策略

📅 2026/7/4 0:10:40 👁️ 阅读次数 📝 编程学习
SSRF漏洞攻防实战:从原理到绕过技巧与防御策略

1. 项目概述:从“内部请求”到“内网漫游”的SSRF攻防实战

在渗透测试和红队评估的实战中,我们常常会遇到一种看似“温和”实则威力巨大的漏洞:服务器端请求伪造。它不像SQL注入那样直接操作数据库,也不像命令注入那样能瞬间拿到Shell,但SSRF却像一把能打开内网大门的“万能钥匙”。想象一下,你发现一个网站的功能是帮你获取网络图片的缩略图,你输入一个公网图片URL,它就能正常显示。但如果你输入的是http://127.0.0.1:8080/admin呢?如果服务器毫无防备地代你发出了这个请求,那么你就能以服务器的身份,“看到”它本地端口上的管理后台。这就是SSRF最核心的玩法——让服务器成为你的“代理”或“跳板”,去访问那些原本对你不可见的内部系统。

我遇到过不少案例,一个简单的图片上传或URL预览功能,因为对用户输入缺乏严格的校验,最终导致攻击者能够扫描内网、攻击Redis/Memcached服务、甚至通过云服务元数据接口窃取实例的临时密钥。尤其是在云原生和微服务架构普及的今天,内网服务间信任关系复杂,一旦边界被SSRF突破,往往意味着整片内网区域沦陷。因此,无论是作为攻击方进行漏洞挖掘,还是作为防御方进行代码审计和安全加固,深入理解SSRF的绕过技巧、攻击面挖掘和防御策略,都是一项至关重要的技能。接下来,我将结合多年实战经验,为你拆解SSRF漏洞的完整攻防链条。

2. SSRF漏洞核心原理与攻击面深度解析

2.1 SSRF的本质:信任边界的错位

SSRF的根本原因在于服务器对用户提供的URL地址过于信任。应用程序的业务逻辑需要从远程获取资源(如图片、文件、RSS订阅),这个“获取”的动作由服务器后端代码执行。当攻击者能够控制这个目标URL参数时,他就可以诱导服务器向任意地址发起请求,包括其内部网络、本地回环地址,甚至是云平台的特殊元数据端点。

从技术架构上看,这暴露了一个常见的信任模型问题:外部用户输入域与内部网络信任域发生了不应有的交集。服务器通常位于受保护的网络环境中,可以自由访问数据库、缓存、管理接口等内部服务。而SSRF漏洞使得外部攻击者能够“借用”服务器的网络位置和权限,从而穿透网络边界。理解这一点,是后续所有绕过和利用手法的思想基础。

2.2 关键攻击向量与危害场景盘点

SSRF的危害远不止“访问一下内网页面”那么简单,其攻击面可以横向扩展到多个层面:

  1. 内网资产探测与端口扫描:这是最直接的利用方式。通过构造指向内网IP(如192.168.1.1)和不同端口(如22, 80, 3306, 6379)的URL,根据服务器的响应时间、状态码或返回内容差异,可以判断目标主机和端口的开放情况,绘制内网地图。
  2. 攻击内部脆弱服务:许多内部服务默认缺乏强认证。
    • 数据库与缓存服务:攻击未授权访问的Redis(默认6379端口)可导致数据泄露甚至远程代码执行(通过写SSH公钥或Webshell)。Memcached、MongoDB等也存在类似风险。
    • 应用管理后台:许多框架(如Spring Boot Actuator, Jenkins, Docker Registry)的管理界面部署在内网,通过SSRF可直接访问并进行未授权操作。
  3. 云平台元数据服务攻击:这是云环境下SSRF的“高价值目标”。云厂商(如AWS, Azure, GCP, 阿里云,腾讯云)会为每个云实例提供一个内部端点(如http://169.254.169.254/),用于查询实例的元数据,其中可能包含临时访问凭证(AccessKey/SecretKey)。一旦通过SSRF获取这些凭证,攻击者就能以该实例的身份在云平台上进行任意操作,危害范围从当前实例扩大到整个云账户。
  4. 协议滥用与文件读取:除了HTTP/HTTPS,许多网络库支持其他协议,可能带来意外风险。
    • file://协议:可能用于读取服务器本地的敏感文件,如/etc/passwd, 应用配置文件,甚至源码。
    • dict://,gopher://协议:这些协议可以用于与更多服务(如Redis, Telnet)进行交互,构造出更复杂的攻击载荷。例如,Gopher协议可以封装完整的TCP数据流,是攻击内网无Web界面的服务的利器。
  5. 请求重定向与二次攻击:有时应用程序会对URL进行基础校验(如禁止内网IP),但允许访问一个外部URL,而这个外部URL返回一个302重定向,指向内网地址。如果服务器在发起请求时自动跟随重定向,且未对重定向后的地址进行二次校验,漏洞依然会被触发。

注意:在实际测试中,务必在授权范围内进行。对内网或云元数据的探测和攻击可能对业务造成严重影响,甚至违反法律法规和服务条款。

3. 绕过IP限制与黑名单的进阶技巧

现代应用和WAF(Web应用防火墙)通常会部署一些基础的SSRF防护,最常见的就是IP地址黑名单或白名单校验。直接使用127.0.0.1192.168.1.1会被拦截。这时,就需要一些“花式”绕过技巧。

3.1 利用URL解析的歧义性

不同的URL解析库(如Java的java.net.URL, Python的urllib, PHP的cURL)在处理URL时可能存在差异,攻击者可以利用这些差异绕过简单的字符串匹配。

  1. 利用@符号:在URL中,@符号用于分隔认证信息(用户名密码)和主机。解析器通常将@之后的部分识别为主机。例如:
    • http://foo@127.0.0.1-> 主机是127.0.0.1
    • http://abc.com@127.0.0.1-> 主机依然是127.0.0.1,但黑名单可能只匹配abc.com
  2. 利用#号片段#后面的内容是片段标识符,通常不会发送到服务器。但有些解析器处理不当。
    • http://127.0.0.1#.evil.com-> 弱校验可能只检查.evil.com而放过。
  3. 利用问号查询字符串?后面是查询参数。
    • http://evil.com?x=http://127.0.0.1-> 有些自定义校验逻辑可能错误地提取第一个主机名evil.com
  4. 利用反斜杠和中文句号127。0。0。1(中文句号)或127.0.0.1\在某些场景下可能被某些库或系统“标准化”为正确的IP。
  5. IPv6与IPv4兼容地址
    • IPv6本地地址:[::][::1]等价于127.0.0.1
    • IPv4映射IPv6地址:[::ffff:127.0.0.1][::ffff:7f00:1]
    • 十进制IP表示:2130706433127.0.0.1的十进制形式。http://2130706433可能被直接访问。
    • 八进制IP表示:0177.0.0.010177是八进制的127)。
    • 十六进制IP表示:0x7f.0x0.0x0.0x1
    • 混合表示:127.1(省略中间的0),127.0.1

3.2 利用DNS重绑定技术

这是绕过IP黑名单的“杀手锏”级技巧,尤其对付在“发起请求前”进行一次性DNS解析和IP校验的防御机制非常有效。其原理是利用DNS解析的时效性和校验时机差

攻击流程如下:

  1. 攻击者控制一个域名(如evil.attacker.com),并配置其DNS记录具有极短的TTL(如1秒)。
  2. 首次DNS解析时,该域名指向一个合法的、允许访问的外网IP(如1.2.3.4)。应用程序进行DNS解析,得到IP1.2.3.4,校验通过(因为是外网IP)。
  3. 应用程序校验通过后,准备发起实际的HTTP请求。就在这“校验后”到“请求前”的短暂间隙,攻击者快速修改DNS记录,将evil.attacker.com指向目标内网IP(如192.168.1.1)。
  4. 由于应用程序可能使用了不缓存DNS的客户端,或者DNS缓存因TTL极短而失效,在真正发起请求时,会重新解析域名,此时得到的就是内网IP192.168.1.1
  5. 请求成功发往内网地址,绕过校验。

实操要点

  • 你需要一个支持API动态更新DNS记录的域名服务商。
  • 编写一个简单的服务,在收到特定请求后立即变更DNS记录。
  • 这种攻击对编程语言或网络库的DNS缓存行为非常敏感,需要多次尝试。

3.3 利用URL重定向

如前所述,如果应用程序允许访问外部URL并跟随重定向,且不对重定向目标做检查,那么可以:

  1. 在攻击者控制的服务器上(http://attacker.com/redirect)部署一个页面,返回302 Found状态码,Location头设置为http://127.0.0.1/admin
  2. 向漏洞点提交http://attacker.com/redirect
  3. 服务器校验attacker.com通过,请求该URL,收到重定向响应后,直接请求127.0.0.1/admin,攻击成功。

3.4 利用非HTTP协议和少用端口

黑名单可能只覆盖了常见端口(80, 443)或HTTP/HTTPS协议。

  • 端口:尝试非Web端口,如http://127.0.0.1:22(SSH),http://127.0.0.1:6379(Redis),这些端口可能开放且返回有特征的信息。
  • 协议:尝试file:///etc/passwd,dict://127.0.0.1:6379/infogopher://127.0.0.1:6379/_...。能否成功取决于后端使用的网络库是否支持这些协议。

4. 漏洞挖掘方法论与实战经验

发现SSRF漏洞需要敏锐的观察力和系统的测试方法。它很少像IDOR(不安全的直接对象引用)那样明显,更多隐藏在看似正常的业务功能背后。

4.1 关键功能点挖掘

在审计或测试时,重点关注以下类型的参数和功能:

  • URL或地址参数:功能名中带有url,link,path,src,target,redirect,api,feed,load,fetch,remote,share,download等字段的输入点。
  • 文件处理相关
    • 图片/文件上传后的远程下载功能(从指定URL下载)。
    • 文档处理服务,如将网页转换为PDF,将Word文档在线预览。
    • 头像设置,支持从网络URL设置头像。
  • 数据获取与导入
    • 订阅RSS/Atom源。
    • 从外部API获取天气、股票、汇率数据。
    • 社交媒体分享预览(抓取URL的元信息,如Open Graph标签)。
  • 内部系统集成点
    • Webhook配置(允许用户设置一个接收通知的URL)。
    • SSO(单点登录)回调地址。
    • 支付网关回调通知。
  • 开发与调试功能
    • 网站测速、ping、traceroute工具。
    • API测试工具,允许用户向任意端点发送请求。

4.2 手工测试与探测流程

  1. 基础探测:发现可疑参数后,首先尝试最基本的Payload。

    • http://127.0.0.1http://localhost
    • http://169.254.169.254/latest/meta-data/(AWS元数据,其他云厂商类似)
    • file:///etc/passwd
    • 观察响应:是直接返回内容,还是返回错误信息(如“无法访问”、“禁止内网IP”),或是触发延迟(端口开放vs关闭响应时间不同)。
  2. 盲SSRF探测:很多时候,请求的结果不会直接回显到前端(盲SSRF)。这时需要借助带外技术

    • DNS带外:使用http://your-unique-id.burpcollaborator.net这样的地址。如果服务器尝试解析这个域名,你的Burp Collaborator或DNSLog平台就会收到记录,证明漏洞存在。
    • HTTP带外:使用一个你完全控制的、能记录访问日志的Web服务器地址。提交http://your-server.com/ssrf-test,然后查看你的服务器访问日志,如果有来自目标服务器IP的请求,即证明成功。
  3. 端口扫描与协议探测:确认存在SSRF后,进行内网探测。

    • 使用Burp Suite的IntruderSSRFmap等工具,对内网IP段(如192.168.0.0/24,10.0.0.0/8)和常见端口进行批量探测。
    • 重点端口:22(SSH), 80/443(Web), 3306(MySQL), 5432(PostgreSQL), 6379(Redis), 27017(MongoDB), 9200(Elasticsearch), 11211(Memcached), 8080/8081/8443(各类管理后台)。
    • 根据Banner信息识别服务。

4.3 自动化工具辅助

手工测试是基础,但自动化工具能提升效率。

  • Burp Suite Professional
    • Collaborator:用于盲SSRF探测,无可替代。
    • Intruder:用于端口扫描和模糊测试。
    • Extensions:SSRF Scanner,AutoSSRF等插件可以自动化部分检测流程。
  • ffuf / gobuster:这些快速的Web模糊工具也可以用于SSRF的路径发现,如果你已经通过SSRF访问到一个内网Web服务,可以用它们来发现隐藏的目录和文件。
  • Gopherus:一个专门生成攻击各种服务(如Redis, MySQL, FastCGI等)的Gopher协议Payload的工具,在SSRF利用阶段非常有用。
  • SSRFmap:一个功能强大的自动化SSRF利用框架,集成了探测、端口扫描、攻击Payload生成(针对Redis, Postgres, 云元数据等)于一体。

5. 从漏洞验证到深入利用的完整链条

找到SSRF点只是第一步,如何将其转化为实际的危害,需要更深入的利用技巧。

5.1 信息收集与内网测绘

利用SSRF进行内网端口扫描时,要注意技巧:

  • 基于时间的盲探测:通过比较请求不同端口的响应时间差异来判断端口状态。开放的端口通常会更快地返回连接拒绝或服务Banner,而过滤的端口可能直接超时。
  • 基于响应差异的探测:即使响应内容不直接回显,但HTTP状态码、响应头、错误信息可能有区别。例如,连接到一个开放的Redis端口(6379)可能返回-ERR wrong number of arguments for 'get' command或一个+号开头的行,而连接到一个关闭的端口会直接报连接错误。
  • 记录所有响应:将每次探测的原始响应(包括Header和Body)保存下来,仔细分析。一个看似乱码的响应,可能是某个二进制协议的握手信息,能帮你识别出未知服务。

5.2 攻击特定后端服务实例

假设我们通过SSRF发现内网有一台开放的Redis服务(192.168.1.10:6379)。

利用思路

  1. 信息泄露:直接通过dict://192.168.1.10:6379/info或构造HTTP请求体为INFO\r\n的Gopher请求,获取Redis配置和运行信息。
  2. 未授权写文件:目标是获取服务器权限。经典方法是写SSH公钥或Webshell。
    • 写SSH公钥:这需要Redis运行用户有写~/.ssh/authorized_keys文件的权限。通过SSRF发送Redis命令,将你的公钥写入目标服务器的该文件。
    • 写Webshell:如果知道Web目录路径,可以通过Redis的config set dirconfig set dbfilename设置目录和文件名,然后set一个键,值为Webshell内容,最后通过save命令将内存数据持久化到文件(如shell.php)。
  3. 主从复制RCE:这是更高级的攻击方式。通过FTP或HTTP服务,在攻击者机器上部署一个恶意的Redis RDB文件,然后利用SSRF让目标Redis设置自己为从节点(SLAVEOF),指向攻击者控制的“主节点”。当目标Redis同步恶意RDB文件时,就可能触发反序列化等漏洞执行命令。

实操难点与注意

  • 通过SSRF攻击Redis,需要将Redis协议的命令封装成HTTP或其他协议能发送的形式。Gopher协议是天然适合的,因为它能封装任意TCP流。如果后端只支持HTTP,则需要利用HTTP协议的一些特性来“夹带”Redis命令,例如在POST Body中发送,或者利用CRLF注入将Redis命令注入到HTTP请求头中(这取决于后端如何处理请求)。
  • 命令执行的成功率高度依赖于目标Redis的配置(是否以root运行)、权限和网络可达性。

5.3 云元数据服务利用实战

这是SSRF在云环境下的“高价值目标”。以最常见的AWS为例:

  1. 探测元数据端点:访问http://169.254.169.254/。如果存在,通常会返回一个目录列表(如latest/,user-data等)。
  2. 遍历获取信息:逐步访问路径,获取元数据。
    • http://169.254.169.254/latest/meta-data/:获取实例基本信息(主机名、IP、实例ID等)。
    • http://169.254.169.254/latest/meta-data/iam/security-credentials/这是关键!访问这个路径,它会返回当前实例关联的IAM角色名称。
    • http://169.254.169.254/latest/meta-data/iam/security-credentials/[角色名]:访问上一步返回的角色名对应的路径,即可获取该角色的临时安全凭证(AccessKeyId, SecretAccessKey, Token)。
  3. 利用凭证:使用获取到的临时凭证,通过AWS CLI或SDK,即可在凭证有效期内(通常几小时)以该IAM角色的权限执行任何操作。角色的权限可能从S3读写到创建EC2实例,甚至管理整个账户。

重要心得:在测试云元数据时,务必使用只读的探测方式。避免访问http://169.254.169.254/latest/user-data并执行其中的脚本,也不要去动http://169.254.169.254/latest/api/token(这是IMDSv2的令牌端点,不当操作可能导致实例无法访问元数据)。你的目标是证明可以获取凭证,而不是破坏环境。

6. 防御策略与代码审计要点

知道了如何攻击,才能更好地防御。防御SSRF需要多层次、纵深化的策略。

6.1 输入校验:白名单优于黑名单

  • 方案选择:如果业务逻辑明确,只允许访问少数几个固定的外部资源(如指定的CDN图片域名),那么白名单是最佳选择。只允许域名或IP在白名单内的请求通过。
  • 黑名单的陷阱:使用黑名单(禁止内网IP、回环地址)很容易被绕过,如前文所述的种种技巧。它只能作为辅助防御,不能作为唯一依赖。
  • 校验时机与位置:校验必须在URL解析最终确定之后进行。即,需要先对用户输入的URL进行标准化(解析出最终的主机名、端口、协议),然后对标准化后的结果进行白名单校验。这个标准化过程需要使用语言标准库或权威的URL解析库,避免自己写正则导致解析歧义。

6.2 网络层与架构隔离

  • 出站网络限制:在服务器或容器级别,使用防火墙(如iptables, nftables)或安全组策略,严格限制服务器发起的出站连接。只允许访问业务必须的外部IP和端口,阻断所有到内网RFC 1918地址段(10.0.0.0/8,172.16.0.0/12,192.168.0.0/16)和回环地址(127.0.0.0/8)的连接。对于云元数据端点(如169.254.169.254),也应直接阻断。
  • 使用网络策略:在Kubernetes中,可以使用NetworkPolicy来限制Pod之间的通信,防止一个被入侵的Pod通过SSRF攻击其他Pod。
  • 跳板机或代理:让所有需要访问外部资源的请求都经过一个统一的、严格管控的出站代理或网关。在这个网关上实施统一的URL过滤和审计策略。

6.3 应用程序层加固

  • 禁用危险协议:明确禁止使用file://,gopher://,dict://等非必要且高风险的协议。在Java中,可以设置jdk.http.auth.tunneling.disabledSchemes;在PHP的cURL中,使用CURLOPT_PROTOCOLS限制允许的协议。
  • 控制重定向:如果业务不需要,则禁用HTTP客户端自动跟随重定向(如cURL的CURLOPT_FOLLOWLOCATION设为false)。如果需要,则必须对重定向后的URL进行与原始URL同样严格的校验。
  • 使用主机名而非IP:在配置内部服务连接时,尽量使用内部DNS主机名(如redis.internal.svc.cluster.local),而不是直接使用IP地址。这样即使存在SSRF,攻击者也需要猜测或爆破主机名,增加了难度。
  • 云服务最佳实践
    • 使用IMDSv2:AWS的实例元数据服务v2版本要求先获取一个有时间限制的令牌,才能查询元数据,这增加了SSRF利用的难度。
    • 最小权限原则:为云实例分配IAM角色时,遵循最小权限原则,只授予其运行所必需的最低权限。即使凭证泄露,危害也有限。
    • 使用代理访问元数据:有些安全方案建议在实例内部运行一个代理,应用程序不直接访问元数据端点,而是通过这个代理,由代理实施访问控制和审计。

6.4 代码审计中的危险函数与模式

在代码审计时,要像条件反射一样关注以下模式:

  • Java
    • new URL(userInput).openStream()
    • HttpClient.execute(new HttpGet(userInput))
    • ImageIO.read(new URL(userInput))
    • OkHttpClient,RestTemplate等HTTP客户端库,如果其目标URL由用户控制。
  • Python
    • urllib.request.urlopen(user_input)
    • requests.get(user_input)
    • aiohttp.ClientSession().get(user_input)
  • PHP
    • file_get_contents($_GET['url'])
    • curl_init($_POST['link'])及后续的curl_exec
    • fsockopen()
  • Node.js
    • require('http').get(userInput, callback)
    • require('request').get(userInput)
    • require('axios').get(userInput)
  • .NET
    • WebRequest.Create(userInput).GetResponse()
    • HttpClient.GetAsync(userInput)

审计时,不仅要看这些函数是否被直接调用,还要追踪用户输入是否经过层层传递,最终到达这些危险函数。重点关注参数名、变量名,并查看其上下游是否有有效的过滤和校验。

7. 实战案例复盘与疑难问题排查

7.1 案例一:社交媒体链接预览功能中的SSRF

某社交应用有一个“分享链接生成预览”的功能,后端会抓取用户提交的URL,提取标题和缩略图。初步测试发现,提交http://127.0.0.1返回错误“禁止访问内网地址”。尝试使用十进制IPhttp://2130706433,同样被拦截。使用DNS重绑定,由于应用有DNS缓存,未成功。

绕过过程

  1. 尝试http://localhost:80@attacker.com,发现应用校验了attacker.com的IP是外网,通过。
  2. 但请求后返回的是attacker.com的内容,说明它最终请求的是attacker.com。看来它正确解析了主机部分。
  3. 尝试利用碎片,提交http://127.0.0.1#.attacker.com。这次返回了“无法访问”的错误,而不是“禁止内网地址”!这是一个重要信号,说明校验逻辑可能只检查了#之前或第一个点号之前的部分?校验可能不完整。
  4. 进一步测试http://127.0.0.1?.attacker.com,直接返回了本机Apache的默认页“It works!”。漏洞触发成功!原来,应用的校验逻辑是:提取URL中第一个?之前、最后一个@之后的部分作为主机进行校验。对于http://127.0.0.1?.attacker.com,它提取出的主机是127.0.0.1?.attacker.com,这个字符串不在内网IP黑名单里(黑名单是完整的IP匹配),所以校验通过。但底层网络库(如cURL)在发起请求时,会正确地将127.0.0.1识别为主机,?.attacker.com作为查询字符串的一部分,从而成功请求到本地服务。

经验:永远不要相信简单的字符串匹配或正则表达式来做安全校验。必须使用标准库进行URL解析,并对解析后的标准化组件进行校验。

7.2 案例二:盲SSRF结合DNS重绑定攻击内网Kubernetes API

在一个漏洞赏金项目中,发现一个PDF生成服务,接受一个URL参数来抓取网页内容生成PDF。响应中不返回任何远程内容,是典型的盲SSRF。使用DNSLog平台确认漏洞存在。

利用过程

  1. 目标系统部署在云上(例如AWS)。我们的目标是访问其Kubernetes的API Server(通常在内网,如https://10.100.0.1)。
  2. 直接提交https://10.100.0.1无任何带外记录,可能被网络策略阻断或需要HTTPS证书。
  3. 尝试DNS重绑定。搭建一个服务,控制域名rebind.attacker.com。配置两条A记录:一条指向我的外网服务器IP(1.2.3.4),TTL=1;另一条指向目标内网IP10.100.0.1,TTL=1。
  4. 向PDF服务提交http://rebind.attacker.com
  5. 在我的外网服务器上,观察到来自目标服务器IP的HTTP请求(第一次解析到外网IP,校验通过)。
  6. 同时,我监控10.100.0.1的80端口(假设K8s API Server 8080端口未授权开放,但我们需要知道它是否收到了请求)。由于是盲SSRF,我需要让目标服务器在请求内网服务时,产生一个我能观测到的副作用。
  7. 这里利用一个技巧:如果K8s API Server存在未授权访问,我可以构造一个请求,让它向我的服务器发起一个回调(类似于SSRF中的SSRF)。但更简单的方法是,如果服务支持file://协议,我可以尝试让服务器读取一个我猜测存在的、内容独特的文件,并通过DNS带外泄露内容?不,这是盲的。
  8. 更实际的利用是,结合其他信息。例如,通过之前的侦察,我知道他们使用某个CI/CD工具。我构造一个请求到内网Jenkins的crumbIssuerAPI,如果成功,可能会在Jenkins日志中留下记录(但这需要其他途径验证)。或者,我专注于云元数据,提交http://169.254.169.254/latest/meta-data/,通过DNS重绑定,让服务器在第二次请求时访问元数据端点,然后我通过带外方式尝试窃取凭证?这需要元数据端点支持HTTP并返回数据到我的带外通道,这通常不行。
  9. 最终,在这个案例中,利用DNS重绑定成功让服务器请求了内网的http://10.100.0.1:8080/api/v1/namespaces,虽然我看不到响应,但通过精心构造的Payload,我诱使K8s API Server向我的另一个域名发起了一个请求(例如,在Pod创建命令中注入一个向我的Webhook发请求的指令),从而证明了漏洞的危害性。

排查心得:对于盲SSRF,思维要开阔。不能只想着直接回显数据。要思考如何将“对内网的请求”这个动作,转化成一个“我能观测到的信号”。DNS请求、HTTP请求到你的服务器、时间延迟差异、甚至利用内网服务向你的服务器发起二次请求(链式SSRF),都是可能的利用路径。

7.3 常见问题排查速查表

问题现象可能原因排查思路
提交http://127.0.0.1返回“连接被拒绝”或超时1. 漏洞不存在。
2. 漏洞存在,但目标端口没开服务。
3. 服务器有出站防火墙规则。
1. 先用DNSLog或Burp Collaborator确认是否有任何请求发出(盲测)。
2. 尝试其他端口(80, 443, 22, 8080)。
3. 尝试访问一个已知存在且可访问的公网地址,看功能是否正常。
提交任何包含内网IP的URL都返回固定错误页(如403)很可能存在IP黑名单过滤,且过滤在前,请求在后。尝试前文所述的各种绕过技巧:十进制IP、IPv6、利用@?、DNS重绑定、URL重定向。
提交公网URL正常,提交内网IP无响应(非固定错误页)可能请求已发出,但目标内网服务无响应或响应被应用丢弃。也可能是网络策略阻止。1. 使用时间盲注思路,对比请求开放端口和关闭端口的响应时间差异。
2. 尝试访问一个肯定会返回错误Banner的端口(如开放的Redis)。
3. 查看应用日志,是否有相关错误记录。
DNS重绑定攻击不成功1. 应用的DNS缓存时间很长。
2. 使用了操作系统的DNS缓存。
3. 校验和请求之间间隔极短,没有重绑定窗口。
1. 尝试将攻击域名的TTL设为0(如果支持)。
2. 使用多个子域名轮流尝试。
3. 尝试“双峰”攻击:让域名同时解析到两个IP,看客户端使用哪一个。
可以访问http://169.254.169.254但返回404或空1. 不是云服务器。
2. 是云服务器,但使用了IMDSv2且需要令牌。
3. 云厂商不同,元数据端点路径不同。
1. 确认服务器是否在云上。
2. 尝试访问http://169.254.169.254/latest/meta-data/
3. 尝试其他云厂商的元数据端点,如阿里云http://100.100.100.200
攻击内网Redis成功但无法执行命令1. Redis配置了密码认证。
2. Redis以低权限运行,无法写关键目录。
3. 网络限制,Redis无法向外连接(主从复制攻击需要)。
1. 尝试用AUTH命令爆破弱口令。
2. 尝试写其他可写目录,如/tmp
3. 尝试其他利用方式,如通过SLAVEOF配合SSRF将数据泄露到外网(如果Redis版本允许)。

挖掘和利用SSRF漏洞是一个需要耐心、创造力和对网络协议深刻理解的过程。它考验的不仅是技术,更是思维的发散性。从一个小小的URL参数入手,逐步深入,绕过重重限制,最终触及系统最脆弱的内核,这种挑战也正是网络安全工作的魅力所在。对于防御者而言,唯有深刻理解攻击者的所有伎俩,才能构建起真正有效的防线。记住,安全是一个持续的过程,而非一劳永逸的状态。