SQL注入基础:从原理到实战
什么是SQL注入?
SQL注入(SQL Injection)是一种代码注入攻击技术,攻击者通过在Web应用的输入参数中注入恶意SQL语句,从而突破应用程序的安全边界,获取数据库中的敏感数据甚至完全控制服务器。
SQL注入的原理
Web应用通常使用SQL语句与数据库进行交互。如果应用程序没有对用户输入进行充分的过滤和验证,攻击者就可以构造特殊的输入数据,使其与原始SQL语句拼接后产生意外的行为。
经典例子
假设一个登录验证的SQL查询是这样的:
SELECT * FROM users WHERE username = '$username' AND password = '$password'
正常输入:username = admin,password = 123456
生成的SQL:
SELECT * FROM users WHERE username = 'admin' AND password = '123456'
恶意输入:username = admin' --
生成的SQL:
SELECT * FROM users WHERE username = 'admin' --' AND password = ''
注意:-- 是SQL的注释符,后面的内容被注释掉了,密码验证被绕过了!
如何发现SQL注入漏洞?
1. 异常测试法
在输入框中尝试输入特殊字符,观察应用的异常反应:
- 单引号
' - 双引号
" - 注释符
--或/* - 逻辑测试:
' OR '1'='1
如果页面返回数据库错误(如"MySQL syntax error"),说明可能存在SQL注入。
2. 布尔盲注
如果页面没有明显的错误信息,但页面内容会随输入变化(如登录成功/失败的提示不同),可以用布尔盲注来逐步推断数据。
CTF题目解析:简单的SQL注入入门
题目:Basic SQL Injection
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
echo "Login successful! Flag: " . $flag;
} else {
echo "Login failed!";
}
?>
解题思路
这是一个典型的存在SQL注入漏洞的登录页面。我们可以利用注释符绕过密码验证:
Payload:
- 用户名:
admin' -- - 密码:任意值(如
123)
原理:
-- 实际执行的SQL
SELECT * FROM users WHERE username='admin' --' AND password='123'
-- 等价于(注释掉了密码验证部分)
SELECT * FROM users WHERE username='admin'
这样就直接绕过了密码验证,以admin用户身份登录成功,获取到Flag。
防御方法
-
使用预处理语句(Prepared Statements)
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); $stmt->bind_param("ss", $username, $password); $stmt->execute(); -
输入过滤与验证
- 严格检查输入数据类型
- 使用白名单验证
- 转义特殊字符
-
最小权限原则
- 数据库账户应遵循最小权限
- 避免使用root等高权限账户
知识点关联
SQL注入是Web安全中最基础也是最重要的漏洞之一。它与以下知识点密切相关:
- 布尔盲注:当页面无回显时,通过页面响应差异推断数据
- 联合查询注入(UNION注入):利用UNION语句获取其他表的数据
- 报错注入:通过数据库错误信息提取数据
- 时间盲注:利用数据库延时函数(如SLEEP())推断信息
浙公网安备 33010602011771号