web渗透测试之SSRF漏洞详解
1.介绍
SSRF(Server-Side Request Forgery)服务端请求为伪造,SSRF是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。
一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
SSRF漏洞形成的原因大多是因为服务端提供了从其他服务器应用获取数据的功能且没有对目标地址作过滤和限制。
2.ssrf的漏洞攻击和利用
1、可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 banner 信息;
2、攻击运行在内网或本地的应用程序(比如溢出);
3、对内网Web应用进行指纹识别,通过访问默认文件实现;
4、攻击内外网的web应用,主要是使用get参数就可以实现的攻击;
5、利用 file 协议读取本地文件等;
3.ssrf漏洞发现以及挖掘
能够对外发起网络请求的地方,就可能存在 SSRF 漏洞
从远程服务器请求资源(Upload from URL,Import & Export RSS Feed)
数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)
Webmail 收取其他邮箱邮件(POP3、IMAP、SMTP)
文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML)
1、分享:通过URL地址分享网页内容
2、转码服务
3、在线翻译
4、图片加载与下载:通过URL地址加载或下载图片
5、图片、文章收藏功能
6、未公开的Api实现以及其它调用URL的功能
7、从URL关键字中寻找
share
wap
url
link
src
source
target
u
3g
display
sourceURL
imageURl
domain
4.SSRF常用的后端实现
1、file_get_contents()
这段代码使用 file_get_contents 函数从用户指定的 URL 获取图片。然后把它用一个随机文件名保存在硬盘上,并展示给用户。
<?php
if (isset($_POST['url'])) {undefined
$content = file_get_contents($_POST['url']);
$filename ='./images/'.rand().';img1.jpg';
file_put_contents($filename, $content);
echo $_POST['url'];
$img = "<img src="".$filename.""/>";
}
echo $img;
?>
2、fsockopen()
这段代码使用 fsockopen 函数实现获取用户制定 URL 的数据(文件或者 HTML)。这个函数会使用 socket 跟服务器建立 TCP 连接,传输原始数据。
<?php
function GetFile($host,$port,$link) {undefined
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {undefined
echo "$errstr (error number $errno) n";
} else {undefined
$out = "GET $link HTTP/1.1rn";
$out .= "Host: $hostrn";
$out .= "Connection: Closernrn";
$out .= "rn";
fwrite($fp, $out);
$contents='';
while (!feof($fp)) {undefined
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>
3、curl_exec()
使用 curl 获取数据。
<?php
if (isset($_POST['url'])) {undefined
$link = $_POST['url'];
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($curlobj);
curl_close($curlobj);
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>
5.利用 SSRF 进行端口扫描
127.0.0.1:3306
根据服务器的返回信息进行判断,大部分应用不会判别端口,可通过返回的 banner 信息判断端口状态。
PHP后端代码:
<?php
if (isset($_POST['url'])) {undefined
$link = $_POST['url'];
$filename = './curled/'.rand().'txt';
$curlobj = curl_init($link);
$fp = fopen($filename,"w");
curl_setopt($curlobj, CURLOPT_FILE, $fp);
curl_setopt($curlobj, CURLOPT_HEADER, 0);
curl_exec($curlobj);
curl_close($curlobj);
fclose($fp);
$fp = fopen($filename,"r");
$result = fread($fp, filesize($filename));
fclose($fp);
echo $result;
}
?>
html前端代码:
<html>
<body>
<form name="px" method="post" action="http://127.0.0.1/ss.php">
<input type="text" name="url" value="">
<input type="submit" name="commit" value="submit">
</form>
<script></script>
</body>
</html>
请求非 HTTP 的端口可以返回 banner 信息。或可利用 302 跳转绕过 HTTP 协议的限制。
辅助脚本
<?php
$ip = $_GET['ip'];
$port = $_GET['port'];
$scheme = $_GET['s'];
$data = $_GET['data'];
header("Location: $scheme://$ip:$port/$data");
?>
6.SSRF绕过姿势
1、更改 IP 地址写法,例如:192.168.0.1
8 进制格式:0300.0250.0.1
16 进制格式:0xC0.0xA8.0.1
10 进制整数格式:3232235521
16 进制整数格式:0xC0A80001
还有一种特殊的省略模式,例如10.0.0.1这个 IP 可以写成10.1
2、利用 URL 解析问题 在某些情况下,后端程序可能会对访问的 URL 进行解析,对解析出来的 host 地址进行过滤。这时候可能会出现对 URL 参数解析不当,导致可以绕过过滤。 例如:
http://www.baidu.com@192.168.0.1/与http://192.168.0.1请求的都是192.168.0.1内容
可以指向任意 ip 的域名http://xip.io:http://127.0.0.1.xip.io/==>http://127.0.0.1/
短地址http://dwz.cn/11SMa==>http://127.0.0.1
利用句号。:127。0。0。1==>127.0.0.1
利用 Enclosed alphanumerics
7.SSRF防御
服务器开启 OpenSSL 无法进行交互利用
服务端需要鉴权(Cookies & User:Pass)不能完美利用
限制请求的端口为 http 常用的端口,比如,80,443,8080,8090。
禁用不需要的协议。仅仅允许 http 和 https 请求。可以防止类似于 file:///,gopher://,ftp:// 等引起的问题。
统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
8.SSRF漏洞应用攻击模拟演示
漏洞场景
A:本机 192.168.1.100 存 在ssrf漏洞 内网网站服务器
B:本机内网 192.1681.105 存在HFS服务 单独内网
C:外网 192.168.232.128 攻击主机 模拟外网
环境介绍
由于网络环境限制,C无法直接连接B,C利用A的ssrf漏洞探针到B的IP及存在HFS漏洞,攻击成功后可以利用反弹使C其能正常连接B,进而取得控制权!
1、利用ssr探针内网情况
2、探针到B存在HFS
3、利用HFS漏洞攻击(可参考其他漏洞篇专题课程)
4、攻击变异 反弹 shell 取得权限