PHP代码审计系列基础文章(一)之SQL注入漏洞篇
字数 1034 2025-08-11 23:26:41

PHP代码审计之SQL注入漏洞详解

1. SQL注入原理

SQL注入是攻击者通过将恶意SQL语句插入到Web表单输入页面中,使原有SQL语句发生改变,从而执行非预期的数据库操作。所有涉及数据库增删改查的系统功能点都可能存在SQL注入漏洞。

攻击原理示例

$name = $_GET['name']; // 未过滤的用户输入
$sql = "select * from user where name = '".$name."';"; // 直接拼接SQL语句

攻击者可构造输入如:1' union select 1,2,user(),database();#,改变原SQL语义。

2. PHP MySQLi基础函数

  • mysqli_connect(): 建立MySQL连接
  • mysqli_query(): 执行SQL查询
  • mysqli_fetch_array(): 获取结果集为数组
  • mysqli_close(): 关闭数据库连接

3. SQL注入分类及审计要点

3.1 报错注入

特征

  • 未过滤直接拼接用户输入
  • 使用mysqli_error()输出错误信息

示例代码

$id=$_GET['id']; // 未过滤的输入
$sql="SELECT * FROM user WHERE id='$id' LIMIT 0,1";
$result=mysqli_query($db,$sql);
if(!$row){
    echo mysqli_error($db); // 直接输出错误信息
}

测试Payload

1' and (select extractvalue("anything",concat('~',( user()))))%20--%20dsddsa

3.2 宽字节注入

特征

  • 设置MySQL字符编码为GBK
  • 使用addslashes()转义特殊字符

原理
GBK编码中,%df和转义符%5c组合成汉字"運",导致单引号逃逸。

示例代码

mysqli_query($db,"SET NAMES 'gbk'");
$id=addslashes($_GET['id']); // 转义特殊字符
$sql="SELECT * FROM user WHERE id='$id' LIMIT 0,1";

测试Payload

1%df%27 and extractvalue(1,concat(0x7e,(select user()),0x7e)) -- qwe

3.3 盲注

特征

  • 页面无直接错误回显
  • 需要通过布尔或时间延迟判断注入

示例代码

$id=$_GET['id'];
$sql="SELECT * FROM user WHERE id='$id' LIMIT 0,1";
$row = @mysqli_fetch_array($result);
if(!$row){ // 查询失败时返回默认数据
    $sql="SELECT * FROM user WHERE id='1' LIMIT 0,1";
}

时间盲注Payload

2312'%20or%20sleep(5)%20--%20qwe

3.4 二次注入

特征

  • 第一次操作时数据被转义存储
  • 第二次调用时转义被移除,导致注入

示例代码

// 第一次操作(存储)
$user=addslashes($_GET['user']);
$sql="update user set user='$user' where id=1";

// 第二次操作(使用)
$sql = "select * from user where user = '$row[2]'"; // 从数据库取出未转义的数据

测试Payload

' union select 1,2,database(),3 -- qwe

4. 代码审计要点

  1. 定位传参点:查找所有$_GET$_POST$_REQUEST等接收用户输入的代码
  2. 分析SQL拼接:检查SQL语句是否直接拼接用户输入
  3. 过滤机制检查
    • 是否使用预处理语句
    • 过滤函数如addslashes()mysql_real_escape_string()的使用情况
  4. 字符编码检查:特别注意GBK等宽字节编码设置
  5. 错误处理:检查是否直接输出数据库错误信息
  6. 业务逻辑分析
    • 数据流追踪:从输入到最终SQL执行的完整路径
    • 重点关注增删改查操作

5. 防御措施

  1. 使用预处理语句(PDO或MySQLi预处理)
  2. 对输入进行严格过滤和类型检查
  3. 设置合适的数据库错误处理级别
  4. 使用最小权限原则配置数据库账户
  5. 避免直接拼接用户输入到SQL语句中

通过全面理解这些SQL注入类型和审计方法,可以有效识别和修复PHP应用中的SQL注入漏洞。

PHP代码审计之SQL注入漏洞详解 1. SQL注入原理 SQL注入是攻击者通过将恶意SQL语句插入到Web表单输入页面中,使原有SQL语句发生改变,从而执行非预期的数据库操作。所有涉及数据库增删改查的系统功能点都可能存在SQL注入漏洞。 攻击原理示例 攻击者可构造输入如: 1' union select 1,2,user(),database();# ,改变原SQL语义。 2. PHP MySQLi基础函数 mysqli_connect() : 建立MySQL连接 mysqli_query() : 执行SQL查询 mysqli_fetch_array() : 获取结果集为数组 mysqli_close() : 关闭数据库连接 3. SQL注入分类及审计要点 3.1 报错注入 特征 : 未过滤直接拼接用户输入 使用 mysqli_error() 输出错误信息 示例代码 : 测试Payload : 3.2 宽字节注入 特征 : 设置MySQL字符编码为GBK 使用 addslashes() 转义特殊字符 原理 : GBK编码中, %df 和转义符 %5c 组合成汉字"運",导致单引号逃逸。 示例代码 : 测试Payload : 3.3 盲注 特征 : 页面无直接错误回显 需要通过布尔或时间延迟判断注入 示例代码 : 时间盲注Payload : 3.4 二次注入 特征 : 第一次操作时数据被转义存储 第二次调用时转义被移除,导致注入 示例代码 : 测试Payload : 4. 代码审计要点 定位传参点 :查找所有 $_GET 、 $_POST 、 $_REQUEST 等接收用户输入的代码 分析SQL拼接 :检查SQL语句是否直接拼接用户输入 过滤机制检查 : 是否使用预处理语句 过滤函数如 addslashes() 、 mysql_real_escape_string() 的使用情况 字符编码检查 :特别注意GBK等宽字节编码设置 错误处理 :检查是否直接输出数据库错误信息 业务逻辑分析 : 数据流追踪:从输入到最终SQL执行的完整路径 重点关注增删改查操作 5. 防御措施 使用预处理语句(PDO或MySQLi预处理) 对输入进行严格过滤和类型检查 设置合适的数据库错误处理级别 使用最小权限原则配置数据库账户 避免直接拼接用户输入到SQL语句中 通过全面理解这些SQL注入类型和审计方法,可以有效识别和修复PHP应用中的SQL注入漏洞。