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. 代码审计要点
- 定位传参点:查找所有
$_GET、$_POST、$_REQUEST等接收用户输入的代码 - 分析SQL拼接:检查SQL语句是否直接拼接用户输入
- 过滤机制检查:
- 是否使用预处理语句
- 过滤函数如
addslashes()、mysql_real_escape_string()的使用情况
- 字符编码检查:特别注意GBK等宽字节编码设置
- 错误处理:检查是否直接输出数据库错误信息
- 业务逻辑分析:
- 数据流追踪:从输入到最终SQL执行的完整路径
- 重点关注增删改查操作
5. 防御措施
- 使用预处理语句(PDO或MySQLi预处理)
- 对输入进行严格过滤和类型检查
- 设置合适的数据库错误处理级别
- 使用最小权限原则配置数据库账户
- 避免直接拼接用户输入到SQL语句中
通过全面理解这些SQL注入类型和审计方法,可以有效识别和修复PHP应用中的SQL注入漏洞。