SSRF
SSRF全称:Server-Side Request Forgery,即服务器端请求伪造。
是一个由攻击者构造请求,在目标服务端执行的一个安全漏洞。攻击者可以利用该漏洞使服务器端向攻击者构造的任意域发出请求,目标通常是从外网无法访问的内部系统。
简单来说就是利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网进行攻击。
原理
很多网站提供了从其他的服务器上获取数据的功能。通过指定的URL,网站可以从其他地方获取图片、下载文件、读取文件内容等。
SSRF的实质就是利用存在缺陷的Web站点作为代理攻击远程和本地的服务器。
**SSRF漏洞形成的原因大都是由于服务端提供了从其他服务器获取数据的功能但没有对目标地址做过滤与限制。**攻击者可以利用改漏洞获取内部系统的一些信息(因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内网系统)。
- 实例
漏洞场景:某网站有一个在线加载功能可以把指定的远程文章加载到本地,链接如下:
http://www.xxx.com/article.php?url=https://blog.csdn.net/qq_43531669/article/details/112498646
假如系统没有对url参数进行任何的检查,就可以构造其他的请求,例如:
http://www.xxx.com/article.php?url=http://127.0.0.1:22
http://www.xxx.com/article.php?url=file://etc/passwd
http://www.xxx.com/article.php?url=dict://127.0.0.1:22/data:data2 (dict可以向服务端口请求data data2)
http://www.xxx.com/article.php?url=gopher://127.0.0.1:2233/_test (向2233端口发送数据test,同样可以发送POST请求)
...
危害
- 对外网、服务器所在内网、本地进行端口扫描
- 向内部任意主机的任意端口发送payload来攻击内网服务
- DOS攻击(请求大文件,始终保持连接Keep-Alive Always)
- 攻击内网的web应用,如直接SQL注入、XSS攻击等
- 利用file、gopher、dict协议读取本地文件、执行命令等
- 可以无视网站CDN
漏洞发现
1) 分享功能:通过URL地址分享文章等,例如如下地址:
http://share.xxx.com/index.php?url=http://www.xxx.com
通过url参数的获取来实现点击链接的时候跳到指定的分享文章。如果在此功能中没有对目标地址的范围做过滤与限制则就存在着SSRF漏洞。
(2)图片加载/下载:通过URL地址加载或下载图片:
http://image.xxx.com/image.php?image=http://www.xxx.com
图片加载存在于很多的编辑器中,编辑器上传图片处加载设定好的远程服务器上的图片地址,如果没对加载的参数做限制可能造成SSRF。
(3)图片/文章收藏功能:
http://title.xxx.com/title?title=http://title.xxx.com/xxx
例如 title参数是文章的标题地址,代表了一个文章的地址链接,如果收藏功能采用了此种形式保存文章,则在没有限制参数的形式下可能存在SSRF。
(4)转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览。
(5)在线翻译:给网址翻译对应网页的内容。
(6)邮件系统:比如接收邮件服务器地址。
(7)利用参数中的关键字查找:
关键字:
share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain...
总的来说,需要从远程服务器请求资源的网站都有可能存在SSRF漏洞。
常用探测的协议
http
?url= get传参
主要用来发送http协议,获取超文本内容,包括文字、图片、视频、音频等常用互联网资源;
file
file:///文件路径
本地文件传输协议,File协议主要用于访问本地计算机中的文件,就如同在Windows资源管理器中打 开文件一样
dict
dict协议不支持换行符,没有办法进行换行,相当于一次只能执行一条命令,所以不能用来攻击那些需要交互的应用(比如需要认证的redis)。
Dict协议,字典服务器器协议,dict是基于查询响应的TCP协议,它的目标是超越Webster protocol,并允许客户端在使用过程中访问更多字典。Dict服务器和客户机使用TCP端口2628;主要用来探测内网端口协议;
ftp
是一种处于应用层的用于文件传输的协议。是基于TCP协议的应用层协议,用于在网络上传输文件。
Gopher
1、gopher协议会吃掉第一个字符,所以要先放一个没有用的字符
2、回车是\r\n,但如果直接对\r\n进行url编码结果是不对的,因为编码的是\ r \ n四个字符的结果,实际回车只是两个不可见的字符,url编码为%0d%0a
3、直接发%可以正常接收,但是发%0d%0a就会出现数据包发不出去的问题,还需要进行一次url编码成%250d%250a才能正常发送出去(直接用curl命令测试没这个问题,应该是web服务器会自动进行一次url解码导致的)
Gopher协议是互联网上使用的分布型的文件搜集获取网络协议。gopher协议是在HTTP协议出现之 前,在internet上常见重用的协议,但是现在已经用的很少了;
绕过姿势
(1)利用@,当网站限制只能访问 http://www.xxx.com
类型的域名时,可以采用http基本身份认证的方式绕过,如:http://www.xxx.com@www.xxc.com
在对@解析域名中,不同的处理函数存在处理差异,例如:
http://www.aaa.com@www.bbb.com@www.ccc.com
在PHP的parse_url中会识别 www.ccc.com,而libcurl则识别为 www.bbb.com。
2、绕过限制请求IP不为内网地址:
(1)采用短网址绕过
(2)利用特殊域名,xip.io可以指向任意域名(原理是DNS解析),即 127.0.0.1.xip.io,可以解析为127.0.0.1
(3)采用进制转换,127.0.0.1 八进制:0177.0.0.1
;十六进制:0x7f.0.0.1
;十进制:2130706433
(4)利用[::]
,http://[::]:80/
会解析为 http://127.0.0.1
(5)添加端口号,http://127.0.0.1:8080
(6)利用句号,127。0。0。1
会解析为 127.0.0.1
(7)采用302跳转
3、限制请求只为http协议:
(1)采用302跳转
(2)采用短地址
危险函数
根据后台使用的函数的不同,相应的影响和利用方法也不一样,PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()
file_get_contents()
这个函数的作用是将整个文件读入一个字符串中,并且此函数是用于把文件的内容读入到一个字符串中的首选方法。
比如:下面的代码执行结果是输出test.txt文件里面的字符串。
<?php echo file_get_contents(“test.txt”); ?>fsockopen()
使用fsockopen函数实现获取用户制定url的数据(文件或者html)。
curl_exec()
该函数可以执行给定的curl会话。
防护
1.禁止跳转
2.过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
3.禁用不需要的协议,仅仅允许http和https请求。可以防止类似于file://, gopher://, ftp:// 等引起的问题
4.设置URL白名单或者限制内网IP(使用gethostbyname()判断是否为内网IP)
5.限制请求的端口为http常用的端口,比如 80、443、8080、8090
的信息是否符合标准。
6.统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。