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

【Web安全】转义字符注入?转义也会失效的SQL注入

文章目录

    • 一、明明转义了,为啥还能注入?
    • 二、用代码还原漏洞过程
      • 1. 有漏洞的代码示例
      • 2. 漏洞一步步爆发
        • 第一步:黑客的输入
        • 第二步:PHP的转义操作
        • 第三步:MySQL的"错读"
        • 第四步:SQL被注入
    • 三、这个漏洞的风险有多大?
    • 四、怎么防御?
      • 1. 用`set_charset`同步字符集(最关键)
      • 2. 用预处理语句(彻底杜绝注入)
      • 3. 别用废弃的扩展
    • 五、总结

⚠️本博文所涉安全渗透测试技术、方法及案例,仅用于网络安全技术研究与合规性交流,旨在提升读者的安全防护意识与技术能力。任何个人或组织在使用相关内容前,必须获得目标网络 / 系统所有者的明确且书面授权,严禁用于未经授权的网络探测、漏洞利用、数据获取等非法行为。

一、明明转义了,为啥还能注入?

先看个场景:程序员为了防SQL注入,老老实实用了PHP官方推荐的转义函数,结果还是被黑客注入了。问题就出在"字符集"这个容易被忽略的细节上——PHP和MySQL用了不同的"翻译手册",转义的保护作用被悄悄抵消了。

二、用代码还原漏洞过程

咱们用一段具体代码,看看黑客是怎么得手的。

1. 有漏洞的代码示例

<?php
// 连接数据库(PHP默认用GBK字符集处理)
$conn = mysqli_connect('localhost', 'user', 'pass', 'testdb');
if (!$conn) {die('连接失败: ' . mysqli_error($conn));
}// 程序员只告诉MySQL用UTF-8,却没告诉PHP(关键错误!)
mysqli_query($conn, "set names utf8"); // 获取用户输入(假设黑客输入:testuser%81' or sleep(3)-- -)
$name = $_GET['name']; // 用转义函数处理(PHP以为还在用GBK,按GBK规则转义)
$safe_name = mysqli_real_escape_string($conn, $name); // 拼接SQL语句
$sql = "select * from users where name='$safe_name'";
echo "执行的SQL: " . $sql; // 方便查看最终SQL// 执行查询(这里会触发注入)
$result = mysqli_query($conn, $sql);
mysqli_close($conn);
?>

2. 漏洞一步步爆发

第一步:黑客的输入

黑客在URL里输入:info?name=testuser%81' or sleep(3)-- -

这里的%81是关键,它对应计算机里的字节0x81(十六进制)。在GBK字符集里,0x81属于"双字节字符的前半部分"(可以理解为"半个字")——GBK规定,双字节字符的前半部分范围是0x81-0xFE(就像字典里的"偏旁部首",需要和后面的"笔画"组成完整的字)。

类似的"半个字"还有0xDF(也就是%df)、0x90%90)等,只要在0x81-0xFE范围内,作用都一样,黑客随便选一个就行。

第二步:PHP的转义操作

PHP的mysqli_real_escape_string按默认的GBK规则转义:

  • 输入里的单引号'(对应字节0x27)是特殊字符,转义函数会在它前面加一个反斜杠\(对应字节0x5C),把'变成\'(实际存储的字节是0x5C 0x27)。

这里有个容易误解的点:转义后我们看到的%81\\'里有两个反斜杠\\,但这只是"显示效果"。实际存储的只有一个反斜杠字节0x5C,之所以显示成\\,是因为反斜杠\本身在字符串里是"特殊符号",需要用\\才能正确显示。

简单说:%81'转义后,实际字节是0x81 0x5C 0x27(对应%81\'),但显示时会变成%81\\',方便我们看清"这里有一个反斜杠"。

第三步:MySQL的"错读"

因为程序员用了set names utf8,MySQL会用UTF-8规则解读收到的数据。这时候问题来了:

  • UTF-8对"双字节字符"有自己的规定:前半部分必须在0xC0-0xDF范围内,且后半部分必须≥0x80(比如0xC2 0xA1是有效的UTF-8字符)。
  • 而我们的0x81(前半部分)不在UTF-8的范围内,后面的0x5C(反斜杠,字节值92)也小于0x80,所以0x81 0x5C在UTF-8里是"无效的字符组合"。

MySQL遇到无效组合时,会把它们拆成单个字节:0x81被当成一个无效字符(可能显示成?),0x5C(反斜杠)被单独拎出来——这时候反斜杠原本的"保护作用"(保护单引号不闭合)就没了。

第四步:SQL被注入

最终拼接的SQL变成:
select * from users where name='testuser%81\\' or sleep(3)-- -'

但MySQL用UTF-8解读后,实际效果是:
select * from users where name='testuser?\' or sleep(3)-- -'

这里的单引号'因为失去了反斜杠的保护,直接"打断"了前面的字符串,导致or sleep(3)-- -变成有效的SQL命令(-- -会注释掉后面多余的单引号)。于是MySQL执行sleep(3),页面卡顿3秒,黑客就知道注入成功了。

三、这个漏洞的风险有多大?

  1. 数据泄露:黑客可以通过注入获取数据库里的账号、密码、个人信息等;
  2. 数据篡改:修改、删除数据库中的数据(比如删订单、改余额);
  3. 服务器控制:如果数据库权限高,可能通过注入执行系统命令,控制整个服务器。

更危险的是,它利用了"官方推荐的转义函数",容易让程序员放松警惕,以为代码是安全的。

四、怎么防御?

核心原则:让PHP和MySQL用同一套"翻译手册"(字符集),并从根源上避免拼接SQL。

1. 用set_charset同步字符集(最关键)

不要用mysqli_query("set names utf8"),改用mysqli_set_charset,它会同时告诉PHP和MySQL用相同的字符集:

// 正确做法:同步字符集
$conn = mysqli_connect('localhost', 'user', 'pass', 'testdb');
mysqli_set_charset($conn, 'utf8'); // 同时更新PHP和MySQL的字符集

这样转义函数和MySQL的解读规则一致,反斜杠不会失效。

2. 用预处理语句(彻底杜绝注入)

最安全的方式是用"预处理语句",把SQL结构和用户数据分开,让黑客的输入永远当不了命令:

// 预处理示例(推荐!)
$conn = mysqli_connect('localhost', 'user', 'pass', 'testdb');
mysqli_set_charset($conn, 'utf8');$name = $_GET['name'];
// 准备带占位符的SQL
$stmt = mysqli_prepare($conn, "select * from users where name=?");
// 绑定参数(s表示字符串类型)
mysqli_stmt_bind_param($stmt, 's', $name);
// 执行查询
mysqli_stmt_execute($stmt);

预处理语句里,?会被严格当作数据处理,不管输入什么特殊字符,都不会变成SQL命令。

3. 别用废弃的扩展

mysql_real_escape_string(属于早已废弃的mysql扩展)完全不能用,必须用mysqliPDO扩展。

五、总结

转义函数不是万能的,它的安全依赖于PHP和MySQL的字符集一致。如果两边"翻译错了",哪怕是0x810xDF这样的"半个字",都能让反斜杠的保护失效,导致注入。

同步字符集是基础,预处理语句是王道——这两个做到了,绝大多数SQL注入都能防住。

http://www.dtcms.com/a/449560.html

相关文章:

  • 虚拟机中建设iis网站网站推广洛阳
  • python+vue高校新生报到管理系统设计(源码+文档+调试+基础修改+答疑)
  • 中秋连连看小游戏开发完整教程
  • 产品图案设计网站一起做网店网站入驻收费
  • traffic-filter inbound acl 概念及题目
  • Python3 XML 解析
  • 驾驭涌现的艺术:自组织系统——解锁复杂世界的创新与适应力
  • 青岛做外贸网站建设西安网站建设培训中心
  • 【MES架构师与C#高级工程师(设备控制方向)两大职业路径的技术】
  • MySQL 8.0.26崩溃恢复全解析
  • 北京哪个网站最好湖南网络营销
  • 【Linux】MobaXterm 工具介绍
  • 2025-10-6学习笔记
  • 【面板数据】各国数字服务贸易进出口额数据集(2005-2023年)
  • dede怎么做商城网站个人网站免费制作平台
  • Oracle OCP认证考试题目详解082系列第57题
  • 嵌入式开发学习日志36——stm32之USART串口通信前述
  • Linux中capability权能管理的实现
  • Python 语法与注释详解
  • joomla 网站建设教程合肥网站推广公司
  • 介绍一个做美食的网站网店网站技术方案
  • 电源——BUCK电路设计实战
  • wordpress点击页面跳转通辽做网站通过seo来赚钱
  • Git 分支完整操作指南
  • 英伟达:人类反馈与可验证奖励相结合
  • claude code + GLM模型 入门
  • linux-1
  • Docker 三剑客:镜像、容器、仓库
  • 有哪些做二手的网站排名好的网站关键词优化企业
  • FPGA驱动LTC1856 ADC芯片