1、 什么是SSRF:
SSRF(Server-Side Request Forgery:服务器端请求伪造) 一种由攻击者构造形成由服务端发起请求的一个安全漏洞。 一般情况下,SSRF是要目标网站的内部系统。(因为他是从内部系统访问的,所以可以通过它攻击外网无法访问的内部系统,也就是把目标网站当中间人)
2、 形成的原因:
大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制。
3、 寻找漏洞的方法:
- 能够对外发起网络请求的地方,就可能存在SSRF漏洞。
- 从远程服务器请求资源(Upload from URL,Import & Export RSS feed)
- 数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)
- Webmail收取其他邮箱邮件(POP3/IMAP/SMTP)
- 文件处理,编码处理,属性信息处理(ffpmg,ImageMaic,DOCX,PDF,XML处理)
4、 SSRF的攻击方式:
- 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息;
- 攻击运行在内网或本地的应用程序(比如溢出);
- 对内网web应用进行指纹识别,通过访问默认文件实现;
- 攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2,sqli等);
- 利用file协议读取本地文件等。
5、 漏洞修复:
- 使用地址白名单
- 对返回内容进行识别
- 需要使用互联网资源(比如贴吧使用网络图片)而无法使用白名单的情况: 首先禁用CURLOPT_FOLLOWLOCATION;然后通过域名获取目标ip,并过滤内部ip;最后识别返回的内容是否与假定内容一致
产生ssrf漏洞的PHP函数:
file_get_contents()
<?php if(isset($_POST['url'])) { $content=file_get_contents($_POST['url']); $filename='./images/'.rand().'.img';\ file_put_contents($filename,$content); echo $_POST['url']; $img="";
}
echo $img;
?>
在PHP中,file_get_contents() 函数是一个用于读取文件内容的内置函数。它可以从指定的文件路径或URL地址获取数据并将其以字符串的格式返回。
函数格式如下
file_get_contents(string $filename, bool $use_include_path = false, resource $context = null, int $offset = 0, int $maxlen = null): string|false
- $filename:要读取的文件路径或URL地址。
- $use_include_path(可选):如果设置为 true,则会在 include_path 中搜索文件。默认为 false。
- $context(可选):上下文资源,可以用于更高级的操作,例如设置HTTP请求标头。
- $offset(可选):读取内容的起始位置。
- $maxlen(可选):要读取的最大字节数。
函数会先读取该文件内容(漏洞原因),读取成功则将文件内容转化为字符串返回,否则返回false。
fsockopen
<?php $host=$_GET['url']; $fp = fsockopen("$host", 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)
\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); } ?>
fsockopen() 函数 是 PHP 中用于打开一个网络连接的一种方法。它允许我们通过 TCP/IP 协议与远程服务器通信,发送请求并获取响应。
fsockopen(string $hostname,int port);
- $hostname:要连接的目标主机地址,可以是IP地址或域名。
- $port(可选):指定端口号。
成功时,返回一个包含连接信息的资源句柄,供其他函数使用。失败,则返回false。
可用于DDoS攻击。
curl
function curl($url){ $ch = curl_init(); // 初始化curl连接句柄 curl_setopt($ch, CURLOPT_URL, $url); //设置连接URL curl_setopt($ch, CURLOPT_HEADER, 0); // 不输出头文件的信息 curl_exec($ch); // 执行获取结果 curl_close($ch); // 关闭curl连接句柄 }
$url =
G
E
T
[
′
u
r
l
′
]
;
c
u
r
l
(
_GET['url']; curl(
GET[′url′];curl(url);
利用方式很多最常见的是通过file、dict、gopher这三个协议来进行渗透.
可供利用的协议
url伪协议
- file:/// -- 本地文件传输协议,主要用于访问本地计算机中的文件.
- dict:// -- 字典服务器协议,dict是基于查询相应的TCP协议,服务器监听端口2628.
- sftp:// -- SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol).
- ldap:// -- 轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议.
- tftp:// -- 基于lockstep机制的文件传输协议,允许客户端从远程主机获取文件或将文件上传至远程主机.
- gopher:// -- 互联网上使用的分布型的文件搜集获取网络协议,出现在http协议之前.