PHP-MySQL 数据请求与 SQL 注入多样性(小迪 43 课笔记整理)

文章目录

本节课核心:
SQL 注入是否能成功,根本不取决于"有没有漏洞",而取决于"你是否拼对了原 SQL 语句"

而黑盒测试中,原 SQL 语句是未知的 ,只能通过分析数据请求的类型、方法、格式去逼近真实语句。


一、PHP-MySQL 数据请求类型(决定"怎么拼 SQL")

数据请求类型 ≈ 原 SQL 中变量所在的位置与上下文

不同类型 → 需要不同的闭合方式与注入语法

1️⃣ 数字型(无符号干扰)

原 SQL 示例

复制代码
select * from news where id=$id;

特点

  • $id 未被引号包裹
  • 直接参与数值运算或条件判断
  • 不需要闭合引号

注入特征

  • 可直接拼接逻辑

    ?id=1 and 1=1
    ?id=1 union select ...

失败常见原因

  • 实际是字符型,但误以为是数字型
  • 后端做了强制类型转换(intval)

2️⃣ 字符型(有引号干扰)

原 SQL 示例

复制代码
select * from news where id='$id';

特点

  • $id单引号或双引号包裹
  • 注入前必须闭合引号

注入特征

复制代码
?id=1' and '1'='1
?id=1' union select ...

关键点

  • 判断是 ' 还是 "
  • 判断是否存在转义或过滤

3️⃣ 搜索型(多符号干扰)

原 SQL 示例

复制代码
select * from news where id like '%$id%'

特点

  • 前后存在 %
  • 实际上下文更复杂
  • 注入点被夹在字符串中间

注入思路

  • 先逃逸 % + '

  • 再重构逻辑

    ?id=%' and 1=1 and '%'='

实战难点

  • 很多 payload 拼接失败并非无注入,而是上下文没对齐

4️⃣ 框架型(括号 / 多层符号)

原 SQL 示例

复制代码
select * from news where id=('$id');
select * from news where (id='$id');

特点

  • 框架或 ORM 自动加括号
  • 实际 SQL 结构不直观
  • 常见于 ThinkPHP / Laravel / 自封装框架

注入难点

  • 需要额外考虑:
    • ( )
    • 引号
    • 函数包裹

结论

框架型 ≠ 无注入

而是 拼接容错率更低


二、PHP-MySQL 数据请求方法(决定"注入点在哪")

凡是能进入数据库的地方,都是潜在注入点

1️⃣ 常见 PHP 数据来源(全局变量)

来源 PHP 变量
GET $_GET
POST $_POST
Cookie $_COOKIE
Header $_SERVER
文件 $_FILES

2️⃣ HTTP Header 注入点(重点)

(1)User-Agent

用途

  • 记录用户系统 / 浏览器
  • 常被写入数据库用于统计

风险

复制代码
insert into log(user_agent) values('$ua');

INSERT 型 SQL 注入


(2)Cookie

用途

  • Session 跟踪
  • 用户识别

特点

  • 用户完全可控
  • 经常被忽略过滤

(3)X-Forwarded-For(XFF)

用途

  • 获取"真实 IP"

  • 常见代码:

    $_SERVER['HTTP_X_FORWARDED_FOR'];

典型注入场景

  1. 登录时记录 IP
  2. IP 白名单校验
  3. 防注入日志记录 IP

三种风险点

  • 逻辑绕过:伪造固定 IP
  • SELECT 注入:IP 参与白名单查询
  • INSERT 注入:IP 写入数据库

(4)Referer / Host

特点

  • 极少做过滤
  • 在统计、日志、反爬中常入库

3️⃣ 文件上传名 → INSERT 注入

场景

复制代码
$filename = $_FILES['file']['name'];
insert into upload(name) values('$filename');

风险

  • 文件名可控
  • 易被忽略
  • 可配合报错 / 延时注入

三、PHP-MySQL 数据请求格式(决定"怎么传数据")

1️⃣ JSON 格式传输

特点

  • 前端统一 JSON

  • 后端解析后入库

    {
    "id": "1' and 1=1 -- "
    }

风险

  • 开发者误以为"不是表单就安全"
  • 实际解析后仍是字符串拼接 SQL

2️⃣ 编码 / 加密传输(Base64 等)

流程

复制代码
前端 → 编码/加密 → 后端解码 → SQL

关键点

  • 注入 payload 是在"解码后"生效
  • 需要先编码再测试

结论

编码 ≠ 防注入

只是增加了一层处理


四、本节课的统一核心结论

SQL 注入的本质不是"有没有过滤"
而是"你是否拼对了真实 SQL 语句"

黑盒失败 ≠ 无漏洞

很可能是:

  • 数据类型判断错
  • 符号上下文没闭合
  • 注入点不是你测试的那个参数

五、与之前一致的「三步法」扩充总结(实战版)

你之前一直用的那套,这里只做"本课内容映射",不换框架

第一步:数据输入是否可控?

  • GET / POST 参数
  • Cookie
  • Header(XFF / UA / Referer / Host)
  • 文件名
  • JSON 字段
  • 编码前的原始数据

👉 可控 ≠ 可注入,但不可控一定无注入


第二步:数据输入后用到了哪里?

重点关注是否进入:

  • select
  • insert
  • update
  • delete
  • 日志 / IP 记录 / 统计表

👉 只要进了 SQL,就进入注入可能性分析阶段


第三步:能否改变逻辑或执行东西?

结合本课内容具体判断:

  • 是数字型 / 字符型 / 搜索型 / 框架型?
  • 是否需要闭合 ' " ) %
  • 能否:
    • 改 WHERE 条件
    • UNION 查询
    • 报错
    • 延时
    • 写入数据

一句话总结本课实战思想

不要问"有没有 SQL 注入"
而要问"这条 SQL 原本长什么样"

用"被动输入"去期待"主动判断能力"的出现

相关推荐
BingoGo8 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack8 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
于眠牧北1 天前
MySQL的锁类型,表锁,行锁,MVCC中所使用的临键锁
mysql
BingoGo1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
Turnip12023 天前
深度解析:为什么简单的数据库"写操作"会在 MySQL 中卡住?
后端·mysql
JaguarJack3 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php