初探SSRF漏洞
原理剖析:
能够对外发送网络请求的点都有可能存在ssrf漏洞
SSRF(Server-Side Request Forgery: 服务器端请求伪造)是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
![image-20210325130158963](https://i-blog.csdnimg.cn/blog_migrate/c6157dd5f2eb86e8b0e0541449f08ac2.png)
危害:
- 对目标服务器所在的内网进行IP存活性扫描和端口扫描。
- 利用扫描的指纹信息判断开放的服务,从而对内网的主机进行攻击。
- 识别内网WEB应用指纹,判断应用类型进行攻击。
- 使用特定协议攻击应用(gopher、dict、file、FTP/SFTP等)
业务场景:
- 分享:通过URL地址分享网页内容。
- 转码服务(手机适配)。
- 在线翻译(百度翻译搜索检索IP的网址:
http://www.ip.cn
)(已修复)。 - 图片加载与下载:通过URL地址加载或下载图片。
- 图片、文章收藏功能。
- 未公开的api实现以及其他调用URL的功能。
- 从URL关键字中寻找(share、wap、url、link、src、source、target、sourceURI、imageURL、domain)
总之,一切需要服务器去请求资源的场景都有可能存在SSRF漏洞。
涉及函数:
-
file_get_contents()
条件:allow_url_fopen=ON
-
fsockopen()
-
curl_exec()
条件:
1、PHP版本>=5.3;
2、开启extension=php_curl.dll;
3、–wite-curlwrappers(编译PHP时用)
实例:
实验环境:
kali:192.168.1.115 开放端口:redis 6379,mysql 3306,ssh 22。
window10:192.168.1.120
1、curl_exec()函数
后端代码:
#curl_exec.php
<?php
$url = $_GET['url'];
$curlobj = curl_init($url); //初始化一个新的会话,返回一个cURL句柄(句柄就是用来标识一个对象),供curl_setopt(), curl_exec()和curl_close() 函数使用。
echo curl_exec($curlobj); //执行 cURL 会话,返回执行结果
?>
探测内网kali的22端口是否开放:
如图所示,返回了ssh版本信息,说明kali的22端口开放。
探测内网存活的主机:
输入一个不存在的主机IP
延迟了大概有17秒左右,排除网络拥塞的情况,大概率可以判断该主机不存在。
输入一个存活主机的IP:
延迟了大概三秒左右,与上例差异较大,可以初步判断该主机是存活状态。
利用dict协议探测:
![image-20210326150522410](https://i-blog.csdnimg.cn/blog_migrate/3b57c513ce28fc01a66ccb92a95233bc.png)
![image-20210326150630171](https://i-blog.csdnimg.cn/blog_migrate/d66da2be127a009b9cb7d742245cbf74.png)
说明ssh和redis服务均开启。
2、file_get_contents()函数
后端源码:
#file_get_contents.php
<?php
if(isset($_POST['url']))
{
$content=file_get_contents($_POST['url']); //将整个文件读入一个字符串
$filename='./images/'.rand().'.img';
file_put_contents($filename,$content); //将一个字符串写入文件
echo $_POST['url'];
$img="<img src=\"".$filename."\"/>";
}
echo $img;
?>
探测kali的22端口:
探测kali的6379端口:
![image-20210326152714956](https://i-blog.csdnimg.cn/blog_migrate/915e644c3cf8fcd1cfa0c5e811e7d476.png)
由图可知均成功开启!
探测kali的8889端口:
如图所示,高延迟且回显错误,可以初步判断8889端口没有开启。
3、fsockopen()函数
后端源码:
#fsockopen.php
<?php
$host=$_GET['url'];
$port=$_GET['port'];
# fsockopen(主机名称,端口号码,错误号的接受变量,错误提示的接受变量,超时时间)
$fp = fsockopen($host, intval($port), $errno, $errstr, 30); //打开一个网络连接或者一个Unix套接字连接
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
# fwrite() 函数将内容写入一个打开的文件中。
fwrite($fp, $out);
# 函数检测是否已到达文件末尾 ,文件末尾(EOF)
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
探测kali的22端口:
如图所示,kali的22端口开启。
小结:
可以利用SSRF漏洞进行内网探测,根据回显信息可以大致判断内网中某主机的存活性,或者某主机的一个端口是否开放,不过值得注意的是:回显报错和高延迟并不一定代表主机不存在,实际中情况比较复杂应灵活对待。