第42天:WEB攻防-PHP应用&MYSQL架构&SQL注入&跨库查询&文件读写_笔记
一、知识点00:08
- 课程定位: WEB安全攻防系列课程中的PHP应用安全专题,重点讲解SQL注入漏洞
- 语言特性差异: 不同编程语言(JS/ASP/PHP/NET/JAVA/Python)的漏洞原理相似但存在实现差异
- 学习路径: 通过PHP语言掌握漏洞原理后,其他语言的学习会更快
二、课程要点01:54
- SQL注入专题: 将用3-4次直播全面讲解,包括常规查询、跨库查询和文件读写
- 实战价值: 虽然SQL注入漏洞出现频率降低,但仍是WEB安全基础知识点
- 架构重点: PHP应用通常与MySQL数据库组合使用,需理解其架构特点
三、PHP-MYSQL-WEB组成架构02:37
1. PHP-MYSQL-Web组成架构介绍02:41

- 基本组成: 服务器安装MySQL数据库,可搭建单个或多个站点,数据库集中存储在MySQL中
- 管理方式:
- 统一使用root用户管理所有数据库
- 为每个网站创建独立用户管理对应数据库(推荐)
2. 服务器安装与多站点搭建02:50

- 环境搭建: 使用phpStudy等集成环境可快速搭建多个站点
- 站点配置:
- 每个站点可绑定不同域名或端口(如81/82端口)
- 指向独立的网站目录(如Z-Blog和demo01)
- 数据库连接: 网站源码中包含数据库配置文件,指定连接用户和数据库名
3. 不同管理方式的差异与选择08:26

- 统一管理(root用户):
- 所有网站数据库都由MySQL的root用户管理
- 优点:管理简单
- 缺点:安全性较低,一旦泄露影响所有数据库
- 独立用户管理:
- 为每个网站创建专属数据库用户(如zblog用户管理zblog数据库)
- 优点:权限隔离,安全性高
- 缺点:管理稍复杂
4. 架构模型总结与实战应用09:40

- 模型对比:
- 模型1:MySQL → root用户 → 网站A(testA库)/网站B(testB库)
- 模型2:MySQL → testA用户 → testA库 / testB用户 → testB库
- 实战意义:
- 影响SQL注入攻击的思路和方法
- 统一管理模式下可通过root用户进行跨库查询
- 独立用户模式下攻击面受限于单个数据库权限
四、PHP注入13:10
1. 代码结构分析

- 文件包含:代码开头包含config.php文件,这是数据库配置文件
- 模板加载:使用file_get_contents()函数加载new.html模板文件
- ID参数处理:通过$_GET['id']获取URL参数,未传值时默认设为'1'
- SQL拼接:直接将ID参数拼接到SQL语句中,存在注入漏洞
- 查询执行:使用mysqli_query()执行SQL语句并输出结果
2. 关键函数解析

- 函数作用:将整个文件读入一个字符串的首选方法
- 参数说明:
- $filename:要读取的文件名
- $use_include_path:是否在include路径中查找文件
- $context:资源上下文
- $offset:开始读取的位置
- $maxlen:最大读取长度
- 性能优化:操作系统支持时会使用内存映射技术增强性能
- 注意事项:URL包含特殊字符(如空格)时需要先进行URL编码
3. 注入原理分析

- 默认值处理:当不传ID参数时,默认设为'1'执行查询
- SQL拼接方式:直接拼接$_GET['id']到SQL语句中,未做任何过滤
- 查询执行:通过mysqli_query()执行拼接后的SQL语句
- 结果输出:使用mysqli_fetch_row()遍历查询结果并输出到模板
4. 实际运行演示

- 默认查询:访问不带ID参数的URL时,自动执行select * from news where id=1
- SQL输出:代码中通过echo$sql显示实际执行的SQL语句
- 结果渲染:查询结果被填充到模板对应位置后输出完整页面
5. 数据库连接验证

- 数据库环境:使用MySQL 5.7.26版本
- 连接信息:通过localhost的3306端口连接
- 表结构:news表包含id、page_title、heading、subheading、content、item等字段
- 权限说明:演示中使用root用户连接,实际开发中应避免使用高权限账户
五、SQL注入原理15:04
1. 例题1:SQL注入实例演示

- 基本流程:通过修改URL中的id参数值,可以查询不同新闻内容。例如id=1查询"小迪安全博客"内容,id=2查询"萧瑟迪安全博客"内容。
- 数据库操作:实际执行的是SELECT * FROM news WHERE id=id语句,id直接从URL参数获取未经过滤。
- 注入验证:当id=3时页面无内容,说明数据库中没有id=3的记录,这为后续注入创造了条件。

- 数据修改:通过数据库工具直接插入id=3的记录后,页面可以正常显示新增内容"小瑟迪安全博客"。
- 关键发现:页面内容完全由数据库查询结果决定,且参数值直接拼接到SQL语句中。
2. 例题2:SQL注入获取管理员账号密码18:56

- 攻击方法:使用联合查询UNION SELECT获取其他表数据,如id=3 union select 1,2,username,password,5,6 from admin。
- 结果展示:成功获取admin表中的用户名和密码(admin/123456和xiaodi/xiaodisec)。
- 原理验证:通过Navicat执行相同SQL语句,确认返回结果与网页显示一致。

- 参数构造:需要将空格编码为%20等特殊字符,如id=3%20union%20select...。
- 字段匹配:必须确保UNION前后查询的字段数量相同,通过数字占位确定显示位置。
- 限制绕过:添加limit 0,1可以控制返回的记录数量。
3. SQL注入的架构23:56

- 核心原理:接受的参数值未进行过滤直接带入SQL查询,如id=id=id=_GET['id']直接拼接到SQL语句。
- 攻击本质:利用SQL语句执行任意查询,SQL语句能实现的功能就是注入能实现的攻击范围。
- 数据库差异:不同数据库(MySQL/Oracle等)的SQL语法差异导致注入技术不同,功能支持决定攻击危害。

- 最小权限原则:为每个网站创建单独数据库用户,如zblog用户只能访问zblog数据库。
- 参数过滤:应对所有输入参数进行严格过滤和转义。
- 预处理语句:使用参数化查询避免SQL拼接,这是最有效的防御方式。
六、实战案例24:22
1. 案例展示

- 环境搭建:演示通过phpstudy搭建的网站环境,访问端口为81和82,分别对应Z-Blog和demo01两个站点
- 数据库连接:使用Navicat连接MySQL数据库,展示demo01数据库中的admin表结构,包含username、password等字段
2. 数据库架构与用户管理26:51

- 管理方式:
- 统一管理:所有网站数据库由root用户统一管理
- 一对一管理:推荐方式,每个网站创建独立用户管理对应数据库
- 版本问题:演示中出现的语法错误是由于PHP版本兼容性问题导致,更换版本后解决
3. SQL注入与数据库信息获取31:11

- 数据层级:
- 数据库名:如demo01、zblog等
- 表名:如admin、news等
- 列名/字段:如username、password等
- 数据:表中存储的具体记录
- 与Access区别:
- Access:单层结构,直接通过字典猜测表名和字段名
- MySQL:多层结构,可通过information_schema系统数据库获取信息
4. information_schema数据库介绍31:47

- 作用:MySQL 5.0以上版本自带的元数据库,存储所有数据库名、表名和列名信息
- 版本限制:仅MySQL 5.7及以下版本完整支持information_schema查询
5. SCHEMATA表介绍32:11

- 功能:记录MySQL服务器中所有数据库的名称信息
- 关键字段:SCHEMA_NAME字段存储所有数据库名称
- 查询示例:SELECT * FROM information_schema.SCHEMATA
6. 数据库查询操作33:50

- 点表示法:使用"数据库名.表名"格式进行跨数据库查询
- 示例:SELECT * FROM zblog.zbp_member
- 当前数据库:未指定数据库名时默认在当前数据库查询
7. TABLES表介绍35:17

- 功能:记录所有数据库中的表信息
- 关键字段:
- TABLE_SCHEMA:表所属的数据库名
- TABLE_NAME:表名本身
- 应用:通过查询此表可获取指定数据库中的所有表名
七、SQL注入基础35:58
1. 信息架构

- information_schema: MySQL 5.0+自带的核心数据库,存储所有数据库元数据
- schemata表: 记录所有数据库名称信息
- tables表: 记录所有表名信息
- columns表: 记录所有列名信息
2. 关键查询技术

- 数据库枚举: union select 1,2,3,group_concat(schema_name),6 from information_schema.schemata
- 表名枚举: union select 1,2,3,group_concat(table_name),6 from information_schema.tables where table_schema='zblog'
- 列名枚举: union select 1,2,3,group_concat(column_name),6 from information_schema.columns where table_name='zbp_member'
3. 文件读写操作

- 必要条件:
- 当前数据库用户有文件权限
- secure-file-priv设置允许
- 文件读取: union select 1,load_file('d:\1.txt'),3,4,5,6
- 文件写入: union select 1,'xiaodi',3,4,5,6 into outfile 'd:\2.txt'
4. 系统表结构
- 关键字段:
- schema_name: 记录数据库名
- table_schema: 关联数据库名
- table_name: 记录表名
- column_name: 记录列名
5. 注入技术对比

- MySQL优势: 可直接查询information_schema获取元数据
- Access劣势: 需要字典猜测表名和列名
- 数据类型: 需注意不同数据库的语法差异
6. 实战查询示例

- 用户信息查询: select * from news where id=3 union select 1,2,username,password,5,6 from admin
- 系统信息查询:
- union select 1,2,3,database(),user(),6
- union select 1,2,3,version(),@@version_compile_os,6
7. 防御措施

- 输入过滤: 对所有用户输入进行严格验证
- 权限控制: 数据库用户使用最小权限原则
- 安全配置: 禁用不必要的文件系统访问权限
八、火狐浏览器38:35

- 界面配置建议:使用黑色主题更易于理解,虽然未安装特定插件,但可以使用火狐自带的工具功能
- 文件搜索功能:支持使用系统通配符"?"和"*"进行本地文件快速查找,例如搜索"我的工作计划"文档
九、手工注入39:08
1. 手工注入的判断与理解39:14

- order by作用:用于判断数据库表中字段数量,通过不断调整数字直到页面显示异常,可以确定字段数
- 手工注入步骤:
- 先测试order by语句,如order by 7,通过页面是否报错判断字段数
- 确定字段数后(如6个),再构造完整查询语句
- 建议手工编写SQL语句而非使用插件,有助于深入理解注入原理

- 报错技巧:若页面不报错,可在参数前加减号强制报错,如-id=1
- 关键信息查询:通常需要查询以下四项:
- 数据库版本(判断是否大于5.0,影响information_schema可用性)
- 数据库用户(权限判断)
- 操作系统(影响路径大小写敏感性,Linux区分大小写而Windows不区分)
- 当前数据库名(后续查询的基础)
- information_schema:MySQL系统数据库,存储表结构等元数据,但仅适用于5.0以上版本
十、查询数据库版本42:21
- 查询语法:通过内置语句可同时查询数据库版本、数据库名和操作系统信息
- 显示结果:
- 数据库版本:5.7.26
- 数据库名:dom01
- 操作系统:WINDOWS 64位
- 注意:这是MySQL内置的固定查询语法,不需要理解为什么这样写
十一、查询表名43:28
1. 基础查询语法
- 核心语句:SELECT * FROM information_schema.tables WHERE table_schema='数据库名'
- 组成部分:
- information_schema.tables:系统内置的表信息存储表
- table_schema:条件字段,用于指定要查询的数据库
- 执行原理:不添加条件会返回所有表信息,通过WHERE限定只显示指定数据库的表
2. 查询结果处理
- 默认显示:直接查询会返回60条记录(包含系统表)
- 优化方法:使用GROUP_CONCAT()函数合并显示结果
- 典型结果:对dom01数据库查询会显示三个关键表名(admin、gbox、64)
- 筛选技巧:根据表名字段含义选择关键表(如admin最可能是管理员表)
3. 字段查询延伸
- 后续步骤:确定关键表后需要查询其字段结构(如username/password字段)
- 查询逻辑:必须先知道表名才能查询具体字段,这是层级递进关系
- 重要性:admin表的用户名字段是获取登录凭证的关键信息源
十二、查询年龄的信息47:52
1. 查询列名信息
- 查询语句修改:将查询表名信息改为查询列名信息,需要将查询字段改为column_name
- 数据来源:列名信息存储在系统表的column_name字段中
2. 查询条件设置
- 双条件查询:需要设置两个查询条件
- 条件一:table_schema='dom01'(指定数据库名)
- 条件二:table_name='admin'(指定表名)
- 完整查询语句:SELECT column_name FROM information_schema.columns WHERE table_schema='dom01' AND table_name='admin'
3. 查询结果应用
- 结果验证:执行查询后可以获取到admin表的列名信息
- 一步到位查询:获取列名后可以直接使用SELECT * FROM admin进行完整查询
- 数据限制技巧:
- LIMIT 0,1:查询第一条数据
- LIMIT 1,1:查询第二条数据
- 当查询超出数据范围时会报错
4. 条件查询方法
- 精确查询:可以通过WHERE id=1等条件查询特定记录
- 数据验证:当查询不存在的记录(如id=3)时会报错
5. MySQL版本说明
- 版本兼容性:当前讲解的注入方法适用于MySQL 5.0及以上版本
- 版本现状:MySQL 5.0以下的版本(十年前的产品)目前已很少见
十三、跨库查询52:25
1. 概念与原理
- 定义:跨库查询是指通过一个数据库用户权限访问其他数据库的数据
- 核心条件:需要具备root级别的高权限用户才能执行
- 架构关系:与数据库用户管理架构直接相关,root用户可管理所有库,普通用户只能管理指定库
2. 用户权限对比实验
- root用户特性:
- 可查看和操作所有数据库(如demo0521、information_schema等)
- 连接时使用root@localhost:3306
- 普通用户特性:
- 示例用户demo0521/123456只能看到自己的数据库
- 无法查看其他数据库内容
- 权限比喻:root相当于总管,普通用户相当于部门主管
3. 跨库注入攻击演示
- 攻击流程:
- 查询information_schema.schemata获取所有数据库名
- 识别目标数据库(如zblog)
- 查询zblog的表明(如zbp_member)
- 获取关键字段(member_name, member_pass)
- 关键SQL语句:
- 注意事项:跨库查询时必须指定数据库前缀(如zblog.)
4. 安全防护方案
- 风险根源:使用root用户作为网站数据库连接用户
- 解决方案:
- 为每个网站创建独立数据库用户
- 采用一对一用户管理架构
- 用户权限最小化原则
- 防护效果:即使一个网站被注入,也不会影响其他网站数据
十四、文件读写注入
1. 文件读取操作
- 关键函数:LOAD_FILE()
- 示例:
- 限制条件:
- 需要root权限
- 受secure_file_priv参数限制
- 需要知道文件绝对路径
2. 文件写入操作
- 关键语法:
- 路径获取方法:
- 通过报错信息泄露
- 查看phpinfo页面
- 常见中间件默认路径尝试
3. 防护机制
- MySQL配置:
- 设置secure_file_priv限制目录
- 高版本MySQL默认禁用文件读写
- 防御建议:
- 使用普通数据库用户
- 定期检查数据库配置
十五、课后总结01:37:23
1. 注入攻击思路
- root用户场景:
- 先测试文件读写
- 失败后再尝试跨库查询
- 普通用户场景:直接尝试获取当前数据库数据
2. 编码技巧
- 16进制编码:可替代单引号绕过过滤
- 应用场景:表名、数据库名、路径等均可编码
3. 实战要点
- 信息收集:通过user()判断当前权限
- 配置文件:数据库连接用户决定注入权限
- 版本影响:高版本MySQL防护更强,需结合其他漏洞
十六、知识小结
| 知识点 | 核心内容 | 技术要点 | 难度系数 |
| SQL注入原理 | 未过滤参数直接带入数据库查询 | 参数拼接导致恶意SQL执行 | ⭐⭐ |
| 数据库架构模型 | Root统一管理 vs 独立用户管理 | 权限差异导致安全风险不同 | ⭐⭐⭐ |
| 信息收集技术 | 查询information_schema获取元数据 | 获取数据库/表/列结构信息 | ⭐⭐ |
| 跨库注入攻击 | 利用高权限账户跨数据库查询 | Root用户可访问所有数据库 | ⭐⭐⭐⭐ |
| 文件读写操作 | load_file()读取 / into outfile写入 | 需root权限和目录权限配置 | ⭐⭐⭐⭐ |
| 路径获取方法 | 报错信息/配置文件/默认路径探测 | 关键配置文件路径猜测 | ⭐⭐⭐ |
| 编码绕过技术 | 十六进制编码替代单引号 | 绕过WAF过滤规则 | ⭐⭐⭐ |
| 防御措施 | secure_file_priv权限限制 | 数据库配置加固方案 | ⭐⭐ |