当前位置: 首页 > news >正文

043-WEB攻防-PHP应用SQL注入符号拼接请求方法HTTP头JSON编码类

043-WEB攻防-PHP应用&SQL注入&符号拼接&请求方法&HTTP头&JSON&编码类

引言

一、SQL 注入基础:为什么会成功?

在 PHP 开发中,若直接将用户输入(如 URL 参数、表单值)拼接到 SQL 语句中,且未做任何过滤,就可能引发注入。例如:

// 危险写法:直接拼接用户输入$id
$id = $_GET['id'];
$sql = "SELECT * FROM news WHERE id='$id'"; // 若$id是恶意值,SQL逻辑会被篡改

核心矛盾:用户输入可控 + SQL 语句直接拼接,这是所有注入的前提。

二、PHP-MYSQL 数据请求类型(注入的 “入门关卡”)

不同请求类型的核心差异是原 SQL 语句中对用户输入的 “符号包裹方式” 不同(如是否有单引号、百分号),需针对性闭合符号才能注入成功。

1. 数字型注入(无符号干扰,最简单)

原 SQL 格式

select * from news where id=$id; // $id直接作为数字,无引号包裹

注入原理

无需处理符号,直接用and/or篡改逻辑,或用union联合查询。

实战步骤

测试是否为数字型:在 URL 后加?id=1 and 1=1(页面正常)、?id=1 and 1=2(页面异常),说明存在数字型注入;

猜列数:?id=1 order by 4(若正常,说明至少 4 列;若报错,减少列数直到正常);

联合查询:?id=-1 union select 1,2,database(),4(-1让原查询无结果,只显示联合查询结果,database()可查当前数据库名)。

2. 字符型注入(单引号干扰,最常见)

原 SQL 格式

select * from news where id='$id'; // $id被单引号包裹,注入需先闭合单引号

注入原理

用户输入的$id会被单引号包裹,若直接输入1 union select...,SQL 会变成select * from news where id='1 union select...'(被当作字符串,无效)。

需用'闭合左侧单引号,再用--+(注释符)忽略右侧多余内容。

实战步骤

测试是否为字符型:?id=1'(页面报错,提示 “单引号未闭合”,说明是字符型);

闭合符号 + 注释:?id=1' --+(页面恢复正常,说明符号闭合成功);

联合查询:?id=1' union select 1,2,database(),4 --+(获取数据库名、版本等信息)。

image-20250915171227645

关键说明

  • --+的作用:--是 SQL 注释符,+在 URL 中会被解析为空格,确保注释生效(也可用#,但 URL 中需转义为%23)。

3. 搜索型注入(百分号干扰,多符号处理)

原 SQL 格式

select * from news where title like '%$keyword%'; // $keyword被%和''双重包裹

注入原理

%是 SQL 的 “模糊匹配符”,需先闭合%和单引号,再注释右侧内容。

实战步骤

构造注入语句:?keyword=1%' union select 1,2,database(),4 --+ and '%'=';

解析:1%' 闭合左侧的%'(原 SQL 变成like '%1%'),--+注释右侧,and '%'='确保右侧的%被匹配(避免语法错误)。

image-20250915171459751

4. 框架型注入(括号 + 符号干扰,复杂场景)

原 SQL 格式

select * from news where (id='$id'); // $id被()和''双重包裹
-- 或带limit:select * from news where id='$id' limit 0,1;

注入原理

需先闭合括号和单引号,再注释后续内容。

实战步骤

闭合符号:?id=1') --+(1') 闭合('$id,变成(id='1'));

联合查询:?id=1') union select 1,2,database(),4 --+(若有 limit,可在末尾加limit 1,1调整结果显示)。

image-20250915171428629

总结:不同请求类型的核心差异

请求类型 原 SQL 符号包裹 注入关键操作 示例语句
数字型 无符号 直接加 and/union 1 union select 1,2,3
字符型 单引号 闭合单引号 + 注释 1' union select 1,2,3 --+
搜索型 单引号 + 百分号 闭合 % 和单引号 + 注释 1%' union select 1,2,3 --+ and '%'='
框架型 单引号 + 括号 闭合括号和单引号 + 注释 1') union select 1,2,3 --+

三、PHP-MYSQL 数据请求方法(注入的 “攻击路径”)

PHP 通过$_GET、$_POST、$_COOKIE等全局变量获取用户输入,甚至通过$_SERVER获取 HTTP 头信息。只要这些数据被拼接到 SQL 中,就可能引发注入。

1. 核心请求方法:GET/POST/Cookie(直接输入注入)

(1)GET 注入(最直观,参数在 URL 中)

  • 原理:通过 URL 参数(如?id=1)传入恶意值,对应 PHP 代码$id = $_GET['id'];

  • 实战:参考 “数据请求类型” 中的示例(如字符型注入?id=1' union select... --+)。

image-20250915171652972

(2)POST 注入(参数在请求体中,需抓包)

  • 场景:登录表单(用户名 / 密码)、提交表单等,对应 PHP 代码$username = $_POST['username'];

  • 实战步骤(以登录表单为例):

  1. 用 Burp 抓包:拦截登录请求(方法为 POST,参数在Form Data中,如username=admin&password=123);

  2. 发送到 Repeater:修改username为恶意值,测试注入;

  3. 猜列数:username=admin' order by 4 --+&password=任意值(通过Content-Length判断:正常时长度不变,报错时长度变化);

  4. 查数据库:username=admin' union select 1,database(),version(),4 --+&password=任意值(页面可能回显数据库名、版本)。

  5. image-20250915171710537

  • 原理:若 PHP 从 Cookie 获取值并拼接 SQL(如$c = $_COOKIE['user']),可修改 Cookie 注入;

  • 实战:用 Burp 抓包,在Cookie字段后加; user=1' union select 1,database(),3 --+,发送请求。

image-20250915171823684

关键说明:$_REQUEST的风险

$_REQUEST会同时获取 GET、POST、Cookie 中的参数,若用$r = $_REQUEST['r']拼接 SQL,意味着GET/POST/Cookie 都可能成为注入入口,风险更高。

2. HTTP 头注入(间接注入,易被忽略)

部分网站会将 HTTP 头信息(如用户浏览器、IP)存入数据库(如统计用户设备、记录访问 IP),若直接拼接 SQL,会引发注入。常见可注入的 HTTP 头如下:

HTTP 头 作用 PHP 获取方式 注入场景
User-Agent 告诉服务器客户端的浏览器 / 系统版本 $_SERVER['HTTP_USER_AGENT'] 网站记录用户设备信息到数据库
X-Forwarded-For(XFF) 记录客户端真实 IP(代理场景) $_SERVER['HTTP_X_FORWARDED_FOR'] 网站用 IP 做白名单验证(如仅允许特定 IP 登录)
Referer 记录请求来源页面 $_SERVER['HTTP_REFERER'] 网站验证请求是否来自指定页面(如防止跨站提交)
Host 记录客户端要访问的域名 / IP $_SERVER['HTTP_HOST'] 网站多域名部署时,用 Host 判断访问的站点

实战案例:XFF 头注入(IP 白名单绕过)

场景

网站用 IP 白名单验证:仅数据库中存在的 IP 才能登录,PHP 代码如下:

// 获取客户端IP(优先取XFF头)
function getip() {if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) {$ip = getenv("HTTP_X_FORWARDED_FOR"); // 可被篡改} else {$ip = getenv("REMOTE_ADDR");}return $ip;
}// 用IP查询数据库,判断是否允许登录
$ip = getip();
$sql = "SELECT * FROM admin WHERE ip='$ip'"; // 直接拼接$ip,存在注入
注入步骤

抓包:拦截登录请求,查看是否有X-Forwarded-For头(若无则手动添加);

构造恶意 XFF 头:X-Forwarded-For: 127.0.0.1' union select 1,database(),user(),4 --+;

发送请求:若页面回显database()的结果(如testdb),说明注入成功;

绕过白名单:若仅需登录,可直接改 XFF 头为白名单 IP(如X-Forwarded-For: 192.168.1.100)。

四、PHP-MYSQL 数据请求格式(编码 / 格式的 “破解”)

部分网站会对用户输入做 “格式封装”(如 JSON)或 “编码处理”(如 Base64),需先还原为原始数据,再构造注入语句。

1. JSON 格式注入(需按 JSON 语法构造恶意值)

场景

前端用 JSON 格式提交数据,PHP 解码后拼接 SQL,代码如下:

// 接收JSON数据(如前端POST的{"username":"admin","password":"123"})
$jsonData = file_get_contents("php://input");
$data = json_decode($jsonData, true); // 解码为数组// 直接拼接,存在注入
$username = $data['username'];
$password = $data['password'];
$sql = "SELECT * FROM admin WHERE username='$username' AND password='$password'";

注入步骤

  1. 抓包:拦截 POST 请求,查看请求体是否为 JSON 格式(如{"username":"admin","password":"123"});

  2. 构造恶意 JSON:按字符型注入规则,修改username为admin' union select 1,database(),version(),4 #,注意 JSON 语法需正确(引号用双引号,内部单引号无需转义);

  3. 发送请求:请求体改为{"username":"admin' union select 1,database(),version(),4 #","password":"任意值"},若回显数据库信息,注入成功。

2. Base64 编码注入(需先编码恶意语句)

场景

前端将参数 Base64 编码后提交,PHP 解码后拼接 SQL,代码如下:

// 获取GET参数id(Base64编码)
$id = $_GET['id'] ?? 'MQ=='; // 默认为MQ==(Base64解码后是1)
$bid = base64_decode($id); // 解码为原始值// 直接拼接,存在注入
$sql = "SELECT * FROM news WHERE id='$bid'";

注入步骤

确定编码方式:若?id=MQ对应页面显示id=1的内容,说明MQ是1的 Base64 编码;

构造恶意语句:按字符型注入规则,生成原始注入语句:1' union select 1,database(),3,4 --+;

Base64 编码:将原始语句编码为MSd1bmlvbiBzZWxlY3QgMSxkYXRhYmFzZSgpLDMsNCAtLT4=;

发送请求:?id=MSd1bmlvbiBzZWxlY3QgMSxkYXRhYmFzZSgpLDMsNCAtLT4=,页面会回显数据库信息。

关键工具

Base64 编码 / 解码:可用在线工具(如Base64.cn)或 Burp 的 “Decoder” 模块。

五、常见问题与解决方案(注入失败怎么办?)

常见问题 原因 解决方案
注入语句报错:mysqli_num_rows() expects parameter 1 to be mysqli_result SQL 语法错误(如多了单引号、括号不匹配) 检查注入语句的符号闭合:1. 确认原 SQL 的符号包裹方式(如是否有括号);2. 简化语句(先测试1' --+是否正常,再逐步加 union)
联合查询无结果 1. 原查询有结果(覆盖了联合查询结果);2. 列数不匹配 1. 用-1或999让原查询无结果(如?id=-1' union...);2. 重新用order by确认列数
HTTP 头注入无回显 1. 网站未将 HTTP 头信息存入数据库;2. 注入语句未闭合符号 1. 先测试 HTTP 头是否生效(如改 User-Agent 为test,看页面是否回显test);2. 按字符型 / 框架型规则闭合符号
http://www.wxhsa.cn/company.asp?id=4835

相关文章:

  • 离散数学课堂习题及课后习题 - PPX
  • 玻璃2601
  • 二十、DevOps落地:Jenkins基础入门(一)
  • ubuntu 22.04安装mysql5.7
  • Docker如何获取镜像
  • 2025 ICPC 网络赛2 E
  • 偏移寻址
  • 金融业-数字化转型大赛-网络安全赛道部分wp
  • Mysql查找含字符串表字段
  • MySQL注意事项与规范 - 实践
  • 真正的元推理,不需要人类的认可,恰恰是人类追求元推理,只有元推理才能彻底解放人类
  • 西电微机原理-第三章 Intel处理器指令系统及汇编语言(5)
  • 西电微机原理-第五章 存储技术
  • 西电微机原理-第七章 常用接口器件
  • CF1264D1 Beautiful Bracket Sequence (easy version)
  • 西电微机原理-第六章 输入输出技术
  • 【FAQ】应用A如何使用应用B内的文件?
  • OpenStack Cinder 创建卷
  • 西电微机原理-第二章 Intel单核处理器
  • 二叉树的迭代遍历(非递归)
  • 记录---用好了 defineProps 才叫会用 Vue3,90% 的写法都错了
  • 今日流水账-2025年9月15日
  • c#给原文件重命名
  • tcpdump常用随笔
  • 2025年HR经理必备:10款高效人力资源管理软件推荐
  • GAS中GA变量数据的同步
  • 提升员工绩效的5大人才管理软件评测与分析
  • 【触想智能】工业显示屏与普通显示屏的八大区别以及应用领域分析
  • LLaVA- Improved Baselines with Visual Instruction Tuning - jack
  • 042-WEB 攻防:PHP 应用 MYSQL 架构 SQL 注入 跨库查询 文件读写 权限操作