⚠️ 法律声明:本文仅用于网络安全学习与授权安全测试,严禁利用本文技术对未授权网站、数据库进行注入、拖库、篡改等非法操作,违者自行承担全部法律责任。

前言

MySQL是全球使用率最高的Web后端数据库,国内80%以上的PHP网站都搭配MySQL使用,而SQL注入是Web安全中危害最高、最经典的漏洞之一。不懂SQL语法,就只能做“工具小子”,永远看不懂注入漏洞的底层原理,也无法手工构造Payload。

本文基于网安专属MySQL基础笔记整理,从CRUD基础操作到注入专用函数,再到PHP交互漏洞源码,每个知识点都标注网安意义与渗透用途,零基础也能一步步吃透SQL注入的底层逻辑,所有代码可直接复制本地复现。

一、数据CRUD增删改查(DML数据操纵语言)

1.1 基础概念区分:DDL vs DML

数据库操作分为两大类,风险等级、使用场景完全不同,必须先明确区分:

类型 全称 核心作用 核心指令 风险等级 典型场景
DDL 数据定义语言 Data Definition Language 管控数据库、数据表的底层结构 CREATE、DROP、ALTER 高危(操作不可逆) 建库、建表、删库、删表
DML 数据操纵语言 Data Manipulation Language 管控表内的业务数据(用户、订单等) INSERT、SELECT、UPDATE、DELETE 中高风险(无WHERE则全表操作) 用户注册、登录校验、修改密码、注销账号

核心高危提示:四大CRUD操作中,仅INSERT新增语句无需搭配WHERE条件;SELECT查询、UPDATE更新、DELETE删除三类语句,生产环境必须携带WHERE限定范围。一旦省略WHERE,指令会作用于整张表全部数据,极易造成全站数据泄露、篡改、清空,是新手最高频的致命失误。

1.2 CRUD与业务场景的对应关系

网站的用户全生命周期,完全对应CRUD四条语句,也是SQL注入的四大利用场景:

  • C(Create 新增)INSERT语句 → 对应用户前台注册,将账号密码写入数据库

  • R(Read 查询)SELECT语句 → 对应用户登录、后台数据查看 →SQL注入使用率最高、利用方式最多的核心语句

  • U(Update 更新)UPDATE语句 → 对应用户修改密码、编辑个人资料

  • D(Delete 删除)DELETE语句 → 对应用户注销账号、管理员封禁违规账号

1.3 前置准备:创建测试库与用户表

所有实操均基于web_login业务库与users用户表,先执行以下初始化SQL完成环境搭建:

-- 创建业务数据库,指定通用utf8mb4编码
CREATE DATABASE web_login CHARACTER SET utf8mb4;

-- 切换到当前业务库
USE web_login;

-- 创建用户表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,      -- 主键ID,自增
    username VARCHAR(50) NOT NULL,          -- 用户名,非空
    password VARCHAR(255) NOT NULL,         -- 密码,非空
    email VARCHAR(100),                     -- 邮箱,可选
    created_at TIMESTAMP DEFAULT NOW()      -- 注册时间,默认当前时间
);

执行成功后,Navicat/命令行会返回Query OK提示,代表库表创建完成。

1.4 INSERT 新增语句(对应注册业务)

1.4.1 语法规则

  1. 字符串、文本、邮箱等字符型值,必须用英文单引号包裹;双引号会被数据库识别为字段名,裸写字符会直接语法报错。

  2. 自增主键id、带默认值的created_at字段,无需手动赋值,MySQL会自动填充。

  3. 括号内的字段顺序、值的顺序、数据类型必须一一匹配,数量不一致会直接报错。

1.4.2 实操示例

INSERT INTO users(username,password,email) VALUES('testuser','123456','test@qq.com');
  • 成功回执:Query OK, 1 row affected,代表单条数据插入成功

  • 验证方式:执行SELECT查询语句,可看到id、注册时间已自动生成

1.5 SELECT 查询语句(登录与注入核心)

1.5.1 基础查询语法

-- 查询全表所有字段(*为全局通配符,仅运维临时查表用,业务代码不推荐,易泄露敏感字段)
SELECT * FROM users;

-- 查询指定字段(业务标准写法,按需调取,过滤密码等敏感数据)
SELECT username,email FROM users;

1.5.2 系统库information_schema(注入必考)

information_schema是MySQL内置的全局信息字典库,服务启动自动加载,只读不可修改,永久存储本机所有数据库、数据表、字段的元数据信息,是SQL注入中爆库、爆表、爆字段的核心依托。

以下4条为注入专属查表命令,可直接复制使用:

-- 1. 查询本机所有数据库名(注入第一步:枚举所有库)
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA;

-- 2. 查询本机所有库+对应所有表名(注入第二步:枚举所有表)
SELECT TABLE_SCHEMA,TABLE_NAME FROM information_schema.TABLES;

-- 3. 精准查询指定库的所有表(例如查询web_login库)
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='web_login';

-- 4. 精准查询指定库、指定表的所有字段(注入第三步:枚举字段名)
SELECT COLUMN_NAME FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA='web_login' AND TABLE_NAME='users';

网安意义:手工注入的标准流程就是「爆库→爆表→爆字段→拖数据」,全程依托information_schema系统库完成,无需知道任何业务信息。

1.5.3 条件查询WHERE(登录校验核心)

-- 精准查询指定用户名的整条数据
SELECT * FROM users WHERE username='testuser';

安全关联:网站前台登录的校验逻辑,完全依赖WHERE条件匹配账号密码。攻击者只需在输入框中用单引号闭合原生SQL引号,搭配OR 1=1等永真逻辑,就能篡改判断规则,构造万能密码绕过登录,这就是SQL注入最基础的运行原理。

1.6 UPDATE 更新语句(对应改密业务)

1.6.1 标准语法

UPDATE 表名 SET 字段=新值 WHERE 限定条件;

1.6.2 实操示例

-- 将testuser用户的密码修改为654321
UPDATE users SET password='654321' WHERE username='testuser';

1.6.3 高危禁忌

绝对禁止省略WHERE条件。无限制的UPDATE指令会批量覆盖全表所有用户的密码/资料,数据覆盖后无原生日志回滚渠道,会造成全站用户数据不可逆损毁。

1.7 DELETE 删除语句(对应注销业务)

1.7.1 标准语法

DELETE FROM 表名 WHERE 限定条件;

1.7.2 实操示例

-- 删除testuser这条用户记录
DELETE FROM users WHERE username='testuser';

1.7.3 高危禁忌

同UPDATE一致,禁止省略WHERE。无限制DELETE会清空整张表的全部数据,仅保留表结构,数据无法恢复。

1.8 CRUD完整业务闭环与风险总结

  1. INSERT(增):新增单/多条数据,表结构不变,写入binlog可回溯恢复

  2. SELECT(查):只读数据,不修改结构,不产生变更日志,零操作风险

  3. UPDATE(改):修改指定字段值,必须带WHERE,操作前务必备份数据

  4. DELETE(删):物理删除数据,必须带WHERE,操作前务必备份数据

  5. DROP(毁):彻底销毁整张表(结构+数据+索引+约束),无简易恢复途径,数据库最高危指令

二、SQL注入核心语法:多表查询与条件筛选

2.1 MySQL内置探针函数(注入信息搜集第一步)

无需指定业务数据表,单行执行即可调取数据库底层环境参数,是SQL注入信息搜集阶段的第一步,渗透测试人员优先执行这几个函数,快速摸排目标环境。

函数语句 核心作用 网安意义
SELECT database(); 获取当前后端正在使用的业务数据库名 锁定目标数据所在的核心库
SELECT user(); 获取当前MySQL登录连接的账号 判断是否为root高权限账号,决定能否读取系统库敏感数据
SELECT version(); 获取本机MySQL完整版本号 不同版本语法、权限漏洞不同,针对性适配注入Payload
SELECT @@version_compile_os; 获取服务器操作系统类型 为后续提权、命令执行操作做准备

2.2 GROUP_CONCAT 聚合函数(注入拖库核心)

2.2.1 功能作用

MySQL专属聚合拼接函数,核心作用是将数据表多行独立的查询结果,合并为单行字符串(默认英文逗号分隔)。

绝大多数网站页面仅支持单行文本回显数据,该函数可以突破网页回显限制,一次性批量调取多条敏感数据,是外网渗透拖库的核心工具函数。

2.2.2 前置准备:批量插入测试数据

先执行以下SQL批量插入30+条测试数据,方便演示拖库效果:

INSERT INTO users(username,password,email) VALUES 
('test','test123','test@demo.com'), 
('zhangsan','123456','zhangsan@demo.com'), 
('lisi','666888','lisi@demo.com'), 
('wangwu','abc123','wangwu@demo.com'), 
('admin','admin123','admin@demo.com'), 
('student','stu456','student@demo.com'), 
('teacher','tea789','teacher@demo.com'), 
('root','root666','root@demo.com'), 
('guest','guest000','guest@demo.com'), 
('demo','demo999','demo@demo.com'),
('亚索','yasuo123','yasuo@lol.test.com'), 
('盖伦','gailun666','gailun@lol.test.com'), 
('阿狸','fox999','ali@lol.test.com'), 
('薇恩','vn0000','vn@lol.test.com'), 
('劫','shadow777','jie@lol.test.com');

2.2.3 实操语法

-- 合并单字段:一次性取出所有用户名
SELECT GROUP_CONCAT(username) FROM users;

-- 合并关联字段:一次性取出所有「用户名:密码」,冒号分隔
SELECT GROUP_CONCAT(username,':',password) FROM users;

安全价值:SQL注入拖库的刚需函数,无需分页多次查询,一键批量盗取全站用户名、密码、手机号、邮箱等核心敏感数据。

2.3 逻辑运算符与模糊查询

2.3.1 AND / OR 逻辑(万能密码核心)

  • AND(并且逻辑):所有条件同时成立,查询结果才为真,是登录校验的原生逻辑
-- 必须同时匹配账号和密码,才会返回数据
SELECT * FROM users WHERE username='admin' AND password='admin123';
  • OR(或者逻辑):任意一个条件成立,查询结果就为真,是万能密码的核心原理
-- 账号是admin 或者 账号是root,满足其一就返回数据
SELECT * FROM users WHERE username='admin' OR username='root';

注入原理:经典万能密码Payload' OR 1=1 -- ,就是利用OR逻辑拼接1=1永真式,让WHERE条件整体恒成立,直接绕过账号密码校验,返回全表所有用户数据。

2.3.2 LIKE模糊查询 + %通配符

%是模糊匹配通配符,可匹配0个、1个、多个任意字符。攻击者在未知完整表名、管理员账号时,依托LIKE+%组合猜解后台敏感信息。

-- 猜解所有首字母为a的用户名(常用于枚举管理员账号)
SELECT * FROM users WHERE username LIKE 'a%';

2.4 注入三大核心工具语法

2.4.1 ORDER BY 字段数探测

  • 原理:用数字代表列号进行排序,语句不报错 = 数据表至少有N个字段;报错 = 字段数小于N。

  • 渗透用途:联合查询注入的前置必做操作,探测目标表的总字段数,保证UNION前后两段查询的列数一致。

-- 按第3列排序,正常返回 → 表至少有3个字段
SELECT * FROM users ORDER BY 3;

-- 按第5列排序,正常返回 → 表至少有5个字段
SELECT * FROM users ORDER BY 5;

-- 按第6列排序,报错 → 表字段数小于6
SELECT * FROM users ORDER BY 6;

通过逐步递增测试,最终可测出users表共有5个字段。

2.4.2 LIMIT 精准取数

  • 语法LIMIT 起始下标, 读取条数,数据库下标固定从0开始计数

  • 渗透用途:分页取数,注入时精准调取单行敏感数据(比如管理员账号密码),避免批量数据冗余回显。

-- 取第1条数据(下标0,取1条)
SELECT username,password FROM users LIMIT 0,1;

-- 一次性取前10条数据
SELECT * FROM users LIMIT 0,10;

2.4.3 UNION ALL 联合查询(注入拖库核心)

  • 原理:拼接两条SELECT查询语句,前后两段的字段数量必须完全一致,同时返回两段查询结果。

  • 渗透用途:在正常业务查询中拼接恶意查询语句,悄无声息窃取系统库、敏感业务表的数据。

  • 前置条件:必须先用ORDER BY测出准确的字段数量。

基础示例:

-- 联合查询,同时返回正常数据 + 数据库版本+库名
SELECT id,username,password FROM users 
UNION ALL 
SELECT 1,version(),database();

三、PHP与MySQL交互:SQL注入漏洞根源

3.1 PHP数据库交互五步法(固定流程)

所有PHP网站与MySQL的交互,都遵循固定的5步流程,SQL注入漏洞就诞生在第2-3步之间:

  1. PHP代码建立与MySQL的数据库连接

  2. PHP内部编写SQL语句

  3. PHP调用函数执行SQL语句

  4. PHP处理数据库返回的结果

  5. PHP关闭数据库连接

3.2 完整业务源码演示(含注入漏洞)

3.2.1 前端登录页 login.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
    <h2>用户登录</h2>
    <form action="login.php" method="post">
        <p>用户名:<input name="username" type="text"></p>
        <p>密码:<input name="password" type="password"></p>
        <button type="submit">登录</button>
    </form>
</body>
</html>

3.2.2 后端登录逻辑 login.php(原生高危代码)

连接四要素说明:

  • 主机地址:127.0.0.1 本地回环地址,外网无法直连数据库

  • 管理员账号:root,MySQL本地最高权限账号

  • 默认密码:root,PhpStudy预装MySQL的初始密码

  • 业务数据库:web_login

<?php
header("Content-Type:text/html;charset=utf-8");
// 1. 数据库连接四要素,建立连接
$host = "127.0.0.1";
$user = "root";
$pwd = "root";
$dbname = "web_login";
$conn = mysqli_connect($host, $user, $pwd, $dbname);
if (!$conn) die("连接失败:" . mysqli_connect_error());

// 2. 直接接收前端表单参数,无任何过滤
$username = $_POST['username'];
$password = $_POST['password'];

// 3. 高危漏洞点:直接将用户输入拼接到SQL语句中
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";

// 4. 执行SQL并校验登录结果
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
    echo "✅ 登录成功";
} else {
    echo "❌ 账号密码错误";
}

// 5. 关闭数据库连接
mysqli_close($conn);
?>

3.3 漏洞核心成因

SQL注入产生的唯一根源:后端PHP代码无过滤、无转义、无黑名单拦截,完全信任前端用户输入,直接将用户可控的字符拼接进SQL执行语句。

攻击者只需输入英文单引号闭合原生SQL的引号,搭配OR、AND等恶意逻辑,即可篡改原有查询判断逻辑,实现免密登录、全站数据拖取、后台权限接管等危害。

3.4 核心交互函数总结

  1. mysqli_connect():携带四要素建立PHP与MySQL的长连接,校验连通状态

  2. $_GET / $_POST:全局接收变量,无过滤获取前端用户输入,是注入的参数入口

  3. 字符串直接拼接:SQL注入漏洞产生的唯一根源

  4. mysqli_query():执行组装好的SQL语句,接收数据库返回结果

  5. mysqli_close():业务执行完毕后断开连接,释放数据库连接资源

写在最后

MySQL基础语法是学习SQL注入的根基,只有吃透原生SQL的逻辑、函数、执行流程,才能真正理解注入漏洞的本质,而不是只会用工具盲目跑Payload。本文覆盖了Web安全场景下必备的全部MySQL基础知识点,从CRUD操作到注入专用函数,再到漏洞源码成因,完整覆盖入门全流程。

再次郑重提醒:所有技术仅用于合法授权的安全测试与学习研究,请勿用于任何非法场景。

 posted on 2026-06-30 11:26  2525256  阅读(9)  评论(0)    收藏  举报