这是我学习 SQL 注入时整理的入门笔记,只覆盖原理和手工检测思路,供同样在学习的同学参考。 所有测试仅限自己的靶场或获得授权的环境。
为什么会存在注入
本质是用户输入被拼进了 SQL 语句。比如后端把用户名直接拼进查询:
-- 后端想执行的查询(username 是用户输入)
SELECT * FROM users WHERE username = '输入值' AND password = '...';
-- 如果输入值是 ' OR '1'='1
-- 语句就变成了:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '...';
输入不再只是"数据",而变成了"语句的一部分",这就是注入的根本原因。
手工检测的判断思路
- 在参数后加单引号
',观察是否报错或页面异常; - 用逻辑符探测:
' AND '1'='1与' AND '1'='2对比,前者正常后者异常,说明语句被带入执行; - 数字型注入不加引号,直接
AND 1=1 / AND 1=2对比; - 有回显时可用
UNION SELECT探测列数:ORDER BY n逐步试出列数。
提示:手工检测的价值在于理解原理。工具(如 sqlmap)能自动化,但你要能看懂它每一步在做什么、为什么这么做。
常见类型速记
| 类型 | 特征 | 常用思路 |
|---|---|---|
| 联合查询 | 页面有回显位 | UNION SELECT 拼接查询 |
| 报错注入 | 报错信息回显 | updatexml / extractvalue |
| 布尔盲注 | 只返回真假两种页面 | 逐位猜解 + 脚本自动化 |
| 时间盲注 | 无任何回显 | sleep() 观察响应时间 |
防御方向(开发者视角)
- 参数化查询(预编译),从根本上分离语句与数据;
- 最小权限原则:应用数据库账号不给 root,不给写文件权限;
- 对报错信息做统一处理,不把 SQL 错误直接返回给前端。
参考与练习
推荐在合法靶场里练习:sqli-labs、Pikachu、DVWA 等,自己用 Docker 十分钟就能搭起来。下一篇笔记我计划整理"布尔盲注的 Python 自动化脚本怎么写"。