SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者利用漏洞服务器发送恶意请求的攻击方式。SSRF漏洞通常出现在服务器端的web应用中,应用允许用户提供的输入被服务器用来发起请求,而没有对输入进行充分的验证或限制。这使得攻击者可以构造恶意请求,访问内部资源或服务,甚至在某些情况下,控制服务器。
SSRF的常见利用方式
①访问内部服务:攻击者可以通过SSRF漏洞访问原本只有在内部网络中才能访问的服务,例如数据库、内部API、文件服务器等。 ②获取敏感信息:攻击者可以利用SSRF获取一些本应只有服务器端才能访问的敏感信息,例如云服务提供商的元数据服务。 ③端口扫描:攻击者可以通过SSRF漏洞对服务器所在网络的内部系统进行端口扫描,以识别网络中的其他活跃服务。 ④执行代码:在某些情况下,攻击者甚至可以通过SSRF漏洞在目标服务器上执行恶意代码,达到远程代码执行的效果。
SSRF漏洞常见的出现场景
1. URL 读取功能
许多应用程序允许用户输入一个URL,然后服务器从该URL获取数据。例如,社交媒体平台允许用户提供一个图片URL,然后服务器从该URL下载并显示图片;如果对输入的URL没有进行严格的验证,攻击者可以输入指向内部服务的URL。
2. Webhooks
Webhooks允许外部服务通过HTTP请求触发某些事件。攻击者可以利用SSRF漏洞指定内部网络中的URL,导致服务器发送请求到内部服务。
3.服务器端的URL转发功能
一些应用程序提供URL转发或代理服务,允许用户通过服务器访问外部资源;如果没有对用户输入的URL进行严格的验证,攻击者可以利用这个功能访问内部网络资源。
示例:
在此处我们也是使用pikachu
靶场来进行演示,打开靶场中SSRF漏洞相关页面,可以发现此处有一个链接:
点击链接后页面出现了一首诗;但是我们需要关注的重点并不是诗,而是当前页面的url;可以看到url中出现了另外一个url;
url=http://127.0.0.1/pikachu/vul/ssrf/ssrf_info/info1.php
这个url的作用又是什么呢,我们可以通过查看靶场源码来进行理解:
1.首先我们来看一下后面这个url中的容是什么,只需要根据路径找到info1.php这个文件即可
可以发现这个php文件的主要作用实际上就是打印刚才显示在页面中的那首诗。
那么到这边的话我们基本上可以初步判断原先的SSRF漏洞页面的链接实际上就触发了一个事件:在当前页面中显示另外一个页面的内容,这个时候要验证我们的想法很简单,我可以将后面的另外一个URL的值改为www.baidu.com
百度的网址,看百度的页面内容是否会显示到当前页面中即可;此时访问到的URL就是:
http://127.0.0.1/pikachu/vul/ssrf/ssrf_curl.php?url=https://www.baidu.com
访问后可以发现页面中出现了百度网页内容,这个想法就基本没错了;
当然除了这个方法之外还可以直接通过剖析源码来验证我们的想法;相关代码以及代码解析如下:
if(isset($_GET['url']) && $_GET['url'] != null){
// 检查是否通过URL参数提供了名为 'url' 的参数,并且该参数不为空
$URL = $_GET['url'];
// 将用户提供的URL赋值给变量 $URL
$CH = curl_init($URL);
// 初始化一个cURL会话,并设置会话的URL为用户提供的URL
curl_setopt($CH, CURLOPT_HEADER, FALSE);
// 设置cURL选项,不输出HTTP头部信息
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
// 设置cURL选项,不验证对等证书的真实性(关闭SSL验证)
$RES = curl_exec($CH);
// 执行cURL会话,发送请求并获取响应
curl_close($CH) ;
// 关闭cURL会话,释放资源
echo $RES;
// 输出响应内容
}
从代码中就可以看出来,后端程序会接收来自前端的url参数中的数据,接着对该数据进行访问并显示在当前页面中,这段代码就存在明显的安全问题,主要是由于没有对用户输入的URL进行充分的验证;攻击者可以利用该漏洞,构造恶意URL,导致服务器发送请求到内部网络中的其他服务或资源,从而访问敏感信息或进行其他恶意操作。
漏洞利用:
SSRF的利用姿势还是非常多的,但因为本文主要是针对SSRF漏洞的形成原理进行描述,所以漏洞利用方式我们就稍微举两个例子即可:
1.存活主机探测与开放端口扫描
通过SSRF可以扫描当前内网中的存活主机(服务器可访问的)以及对应主机的开放端口;此时我在物理机中开启一个虚拟机,那么这个时候我们就可通过这个页面去对探测虚拟机是否存活以及对其进行端口扫描。
当前虚拟机的IP地址为192.168.8.140,且虚拟机中开启了mysql数据库服务,为了节约时间我们直接测试这个IP的3306,这个时候的访问的url:
http://127.0.0.1/pikachu/vul/ssrf/ssrf_curl.php?url=http://192.168.8.140:3306
查看结果:
可以看到我们获得了虚拟机(内网中另外一台存活主机)的端口;当然这边需要测试的范围非常大,我们可以通过写一个脚本,或者使用burpsuite的爆破模块进行批量检测。
2.利用file协议查看服务器中的文件
此处以Windows为例子(在渗透前肯定是要先判断当前网站的部署环境的);我在服务器(其实就是我的物理机)的D盘中创建一个文件:
文件内容为:
这个时候我们就可以通过file协议对这个文件的内容进行读取,将其显示在页面中;此时地址栏中访问的url为:
http://127.0.0.1/pikachu/vul/ssrf/ssrf_curl.php?url=file:///D:/mysql.ini
查看访问结果:
可以看到文件内容就显示在页面中了,打开思路,若是网站部署在Linux服务器中,那么通过这个SSRF漏洞我们是不是就可以读取Linux中的一些敏感文件,如/etc/passwd等获取系统的用户结构,为后续攻击做准备。
Windows中也有一些比较有用的的文件,如hosts文件、win.ini文件等:
防御SSRF攻击的措施
-
输入验证和过滤:严格验证和过滤用户输入的URL,只允许访问白名单中的地址或域名。
-
网络隔离:将内部服务和外部可访问的服务进行网络隔离,防止外部请求直接访问内部服务。
-
使用防火墙:配置防火墙规则,限制服务器只能对特定的外部地址或端口发起请求。
-
减少权限:运行服务器进程的账户应具有最小权限,以减少在被攻击时的损害。
-
监控和日志记录:对服务器的请求活动进行监控和日志记录,及时发现和响应异常请求行为。