前言、
今天跟大家分享的是ssrf的一些知识,不喜勿喷,感谢大家的观看。
真正的壮举,其实从来人间处处可见,人性善心之灯火,俯拾即是,就看我们愿不愿意去睁眼看人间了。--《剑来》
SSRF服务端请求伪造
漏洞描述
SSRF(Server-side Request Forgery),服务端请求伪造。是一种由攻击者构造请求,由服务端发起请 求的安全漏洞,一般情况况下SSRF攻击的目标是从外网无法访问到的内部系统(正因为它是由服务端发起的,所以它能够请求到与自身相连而与外网隔离的内部系统)。
漏洞原理
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对服务器目标地址做过滤与限制,且用户对目标地址可控。比如从用户提供的指定URL地址获取网页文本内容,加载指定地址的图片,下载等。
例如:网易翻译、百度翻译
http://webtrans.yodao.com/webTransPc/index.html#/?
url=http://www.baidu.com&from=auto&to=auto&type=1
漏洞分类
显示对攻击者的响应(Basic)
它显示对攻击者的响应,因此在服务器获取攻击者要求请求的URL后,他将会把响应发送回攻击者。返回结果到客户端。会返回这个网址的界面或对应的HTML代码。
不显示响应(Blind)
和上面正好相反,不会返回结果到客户端。当您从未从初次请求中获取有关目标服务的任何信息时,就会发生这种ssrf。通常,攻击者将提供url,但是该url中的数据将永远不会返回给攻击者。要在这种情况下确认漏洞,攻击者必须使用Burp,DNSLOG等类似工具。这些工具可以通过强制服务器向攻击者控制的服务器发出DNS或HTTP请求来确认服务器是易受攻击的。这种ssrf通常易于验证,但难以利用;
漏洞函数
SSRF漏洞可能会产生在任何语言编写的应用中,这里介绍PHP中可能会存在SSRF漏洞的函数: file_get_contents()、fsockopen()、curl_exec()
file_get_contents():将整个文件或一个URL指向的文件,以字符串的性质展示给用户。
fsockopen():使用该函数实现获取用户制定url的数据(文件或者html);该函数会使用socket跟服务器 建立TCP连接,进行传输原始数据
curl_exec():对远程的URL发起请求访问,并将请求的结果返回至前端页面
攻击方式
主要攻击方式如下所示:
1. 对外网服务器所在的内网本机进行主机扫描、端口扫描、服务探测。
2. 攻击运行在内网活本地的应用程序。
3. 对内网Web应用进行指纹识别,识别企业内部的资产信息。
4. 攻击内外网的Web应用,主要是使用HTTP GRT请求就可以实现的攻击(struts2、thinkphp、SQL等)
5. 利用File协议读取服务器文件。
6. 利用http/gopher协议发送攻击数据包的功能。
验证漏洞
有回显类型:输入指定地址,如果将指定URL内容获取到了那么也存在SSRF
无回显类型:输入dnslog地址,如果dnslog地址有解析记录及代码存在SSRF
SSRF漏洞攻击
SSRF支持很多协议所以漏洞利用的方式也有挺多的
http:// -- 通过http协议访问内网主机web服务,或发送Get数据包
file:// -- 本地文件传输协议,主要用于访问本地计算机中的文件
dict:// -- 字典服务器协议,dict是基于查询相应的TCP协议
gopher:// -- 互联网上使用的分布型的文件搜集获取网络协议,出现在http协议之前
sftp:// -- SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol)
ldap:// -- 轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议
tftp:// -- 基于lockstep机制的文件传输协议,允许客户端从远程主机获取文件或将文件上传至远程主机
HTTP协议
能进行内网端口探测-可通过返回的时间和长度判断端口是否开放/与Web站点访问。
FILE协议
伪协议,读取敏感的文件信息
file:///var/logs/apache/access.log
file:///etc/passwd Linux用户基本配置信息
file:///c:/windows/win.ini windows系统基本配置信息
file:///etc/shadow Linux用户密码等敏感信息(一般需要root用户才能查看 web服务用户一般没有权限查看)
dict协议
内网服务探测(dict伪协议)
dict协议是一个字典服务器协议,通常用于让客户端使用过程中能够访问更多的字典源,但是在SSRF中如果可以使用dict协议那么就可以获取目标服务器端口上运行的服务版本等信息。ps: 通过响应时间判断端口开放
dict://127.0.0.1:3306 (探测MySQL服务)
dict://127.0.0.1:22 (探测SSH服务)
dict://127.0.0.1:6379 (探测redis服务)
dict://127.0.0.1:1433 (探测SQL server服务)
Gopher协议
Gopher协议是比HTTP协议更早出现的协议,现在已经不常使用了,但是在SSRF漏洞中可以利用gopher协议发送各种格式的请求包,这样便可以解决漏洞点不在GET参数的问题。所有WEB服务器都支持gopher协议。
Gopher协议格式:gopher://<host>:<port>/<gopher-path>_<TCP数据流>
【注意】
由于Gopher协议的特殊格式,在SSRF利用Gopher攻击目标时,需要对数据包进行两次URL编码。1. 第一次URL将URL中的特殊字符进行转义,以便于传输和解析。
2. 第二次编码是为了让Gopher协议能够正常解析,因为Gopher协议使用的ASCII编码。需要将URL中的所有字符都转换为ASCII码的可打印字符,才能被Gopher协议正确解析。
发送Gopher协议时,我们需要注意,(空格、换行符)URL编码,第二次编码前,我们需要将第一次编码后的换行符%0a替换成%0d%0a,在代码最后也需要添加个%0d%0a (因为http协议中换行符是%0d%0a,编码器会编码成%0a) 。
%20 = 空格
%0d%0a = 换行
% = ‘
关于二次转码
先是原码 第一次编码 (看最后是不是以%0a结尾,不是的话加上)然后进行二次编码