php代码审计片段 02 绕过过滤的空白字符
源码点这:bowu678/php_bugs: PHP代码审计分段讲解 (github.com)

要彻底吃透这道题,你得先备好这几样“家伙事儿”:扎实的PHP基础知识、对特定函数行为的深刻理解,以及对URL编码和ASCII码的灵活运用。当然,如果你还能用Python写个简单的脚本(比如会用Requests库发个请求),那效率就更高了。
甜点部分:前置处理逻辑
先来看看代码入口处的“开胃菜”:
ini_set(“display_error”, false); #关闭错误报告
error_reporting(0); //关闭所有PHP错误报告
foreach([$_GET, $_POST] as $global_var) {
foreach($global_var as $key => $value) {
$value = trim($value);//trim — 去除字符串首尾处的空白字符(或者其他字符)
is_string($value) && $req[$key] = addslashes($value); // is_string — 检测变量是否是字符串,addslashes — 使用反斜线引用字符串
}
}
这段代码干了件什么事呢?它把通过GET和POST方式传进来的所有参数,都“清洗”了一遍。具体来说,先用trim函数把值首尾的空白字符去掉,然后,如果这个值是个字符串,就用addslashes给它加上反斜线转义,以防SQL注入。处理完的结果,都存进了$req这个数组里。
举个例子,如果请求的URL是xxx.php?a=2,那么$_GET[“a”]是2,经过这一套流程后,$req[“a”]也等于2(只不过数字2不会被addslashes处理)。这个$req数组,就是后面正餐部分要用的“食材”。
正餐部分:核心校验函数
接下来是硬核的主菜。首先登场的是一个自定义函数:is_palindrome_number($number)。顾名思义,它用来判断一个数是不是回文数。它的实现方式很经典:先把数字转成字符串,然后从字符串的两端向中间逐个字符比较。
通读整个代码逻辑,你会发现,要想成功拿到Flag,必须同时满足以下四个条件:
条件①:is_numeric($_REQUEST[‘number’]) == 0
这意味着,超全局变量$_REQUEST中的number参数,经过is_numeric函数判断后,结果必须为“假”(即不是数字或数字字符串)。
条件②:$req[‘number’] == strval(intval($req[‘number’]))
$req数组里的number值,先被intval转换成整数,再被strval转回字符串,这一通操作之后,得到的结果必须和原始值严格相等。
条件③:$value1 == $value2
其中:
$value1 = intval($req[“number”])
$value2 = intval(strrev($req[“number”]))
这个条件要求,$req[“number”]直接转成整数的值,必须等于其字符串反转后再转成整数的值。
条件④:is_palindrome_number( $req[“number”] ) == 0
最后,把$req[“number”]丢进回文数判断函数,结果必须返回0,也就是说,函数必须判定它不是回文数。
看到这里,矛盾点就出来了:你需要构造一个number,它既要能通过函数判断“不是回文数”(条件④),又要满足其本身和反转后的整数值相等(条件③),这听起来几乎像个“不可能任务”。
直接传number=11这样的回文数肯定不行,第一个条件就过不去,is_numeric(“11”)会返回true。
突破口在于变量来源的差异。仔细看,只有条件①的number是从$_REQUEST里取的,而条件②、③、④的number都来自那个被处理过的$req数组。这就是关键所在!
我们可以利用空字符%00来制造差异。传入number=%0011,对于条件①:$_REQUEST[“number”]接收到的字符串是“%0011”,is_numeric(“%0011”)结果为false,条件满足。而$req数组在处理时,trim函数会去掉首尾的空白字符,但%00(空字符)并不在trim的默认去除列表里吗?这里需要注意,trim默认去除的是空白字符(如空格、制表符等),空字符\0通常不被认为是“空白字符”,但有些环境或配置下可能被处理。更常见的绕过思路是,$_REQUEST在接收参数时会自动对URL解码,%00被解码为空字符,而空字符在字符串比较中有时会被忽略或产生截断效果,导致is_numeric看到的是“11”,从而判断为真?不,这里需要精确测试。实际上,is_numeric(“%0011”)在PHP中会对字符串进行判断,开头的%00(空字符)会导致其判断为非数字字符串,从而满足条件①。同时,这个空字符在后续$req的处理中可能被保留或产生其他影响。
但仅用%00还不够,因为11依然是回文数,无法满足条件④。
所以,我们需要在%00和11之间,再插入一个“神奇”的字符。这个字符需要能“欺骗”intval、strrev、strval这些函数(用于条件②③),让它们忽略它,但同时又能让自定义的回文判断函数is_palindrome_number(条件④)认为字符串不对称。
经过测试,有两个字符可以胜任这个角色:%0c(换页符)或者%2B(加号+)。
因此,最终的有效载荷可以是:number=%00%0c11 或者 number=%00%2B11。
%2B(加号)这个选择可以从逻辑上推导出来。因为intval()函数对加号的处理很特别:intval(“+123”)结果是123,intval(“123+”)结果也是123,intval(“1+23”)则得到1。也就是说,intval在转换时,遇到非数字字符(包括加号在非开头位置)就会停止。把加号放在数字前面,就能让intval(“+11”)和intval(strrev(“+11”))(即intval(“11+”))都得到11,从而满足条件③。同时,字符串“+11”不是回文(“+11”反转是“11+”),满足了条件④。
模糊测试(Fuzzing)思路
除了逻辑推导,我们还可以用“暴力美学”——模糊测试来寻找所有可能的解。我们的目标是找出所有能放在%00和11之间,并满足所有条件的ASCII字符。
基本ASCII码有128个,扩展ASCII码还有128个,总共256个字符,对应十六进制从%00到%FF。
下面这段Python脚本展示了如何自动化这个过程。理解这段代码的关键在于Python的“字符串切片”和“格式化输出”:
import requests
for i in range(256):
i = str(hex(i))
if len(i) == 3: # 例如0x1,需要去掉‘x’
i = i[0:1:] + i[2::]
else: # 例如0x10,需要去掉‘0x’
i = i[2::]
i = “%” + i
# print(i)
number = f“%00{i}11”
re = requests.get(f“https://127.0.0.1/php_bugs/02%20%E7%BB%95%E8%BF%87%E8%BF%87%E6%BB%A4%E7%9A%84%E7%A9%BA%E7%99%BD%E5%AD%97%E7%AC%A6.php?number={number}”)
# print(re.text)
if “x” in re.text: # 假设成功时页面包含‘x’(或Flag标识)
print(i)
这个脚本会遍历所有可能的单字节字符,构造形如%00{XX}11的payload进行测试,并根据返回页面内容判断是否成功,从而找出所有可用的特殊字符。
相关攻略
Webman2 0深度集成Swoole,全面支持原生协程,使HTTP请求、数据库及Redis操作自动异步化。单进程可承载超十万轻量级协程,性能显著提升,QPS增长4 8倍,平均响应时间降至23毫秒。框架解决了全局变量隔离与日志追踪等难题,并为1 x项目提供平滑升级路径,同时保持代码同步风格,降低开发门槛。
2026年PHP框架生态呈现五雄鼎立格局,各具特色。Laravel生态完善,统治复杂业务;ThinkPHP中文生态友好,适合中小企业快速开发;Hyperf专注微服务与高性能;Yii以企业级特性和安全见长;webman凭借常驻内存架构,在高并发场景性能领先。选型需综合性能、微服务支持、开发效率及团队规模,回归业务本质进行决策。
Hyperf3 0正式发布,全面拥抱PHP原生注解,显著提升执行效率与代码灵活性。框架新增对分布式事务的完整支持,提供DTM与Seata两大解决方案。内置SDB协程调试器,实现生产环境零损耗调试。同时在微服务治理、数据库等核心组件上进行了深度优化,致力于构建高性能、易维护的微服务架构。
Workermanv5正式发布,核心更新包括采用revolt event-loop事件驱动库及实现兼容多种实现的协程功能。此次升级使开发者能灵活选用多种驱动协程方案,旨在减少生态分化并提升性能。目前PHP协程生态仍面临组件阻塞化问题,期待更多开发者参与建设以拓宽其应用范围。
在ThinkPHP框架中动态调整数据库连接等配置参数,是许多开发者实现多环境部署的核心需求。然而,你是否曾遇到这样的困境:在入口文件中修改了配置值,刷新页面后却发现更改并未生效?这通常源于对框架配置加载机制的理解偏差。 本文将深入解析ThinkPHP配置生效的唯一正确路径,帮助你彻底规避“本地测试通
热门专题
热门推荐
2026年5月29日,青岛将举办新一代信息技术及人工智能产业对接大会,主题为“向新·向智·向未来”。大会汇聚院士及产业领军者,聚焦技术与商业化融合,通过发布场景需求、推动签约合作,以“场景换技术、资本引项目”模式,助力青岛人工智能产业突破千亿规模,驱动城市智能化升级。
高效运用AI数据平台需遵循清晰路径。首先创建符合格式要求的数据集作为基础。随后进行数据清洗,处理重复、错误与缺失值以保证分析准确性。接着选择合适模型进行数据分析以挖掘规律。最后将结果通过图表可视化,实现直观呈现与有效沟通。
正在寻找《大唐2》一折服的官方网站入口?许多新玩家初次接触时确实会遇到这个困惑。无需担心,本指南将为您提供最清晰的路径,直接呈现官方入口与游戏核心信息,助您快速启程。 大唐2一折服正式首页入口 最权威、最稳定的官方访问地址如下,建议您妥善收藏,方便随时访问: 正式入口:https: dt yhyx
核心应用场景: 在当今信息爆炸的时代,数据规模持续增长,分析需求日益精细化。无论是企业决策者还是项目团队,都面临一个核心痛点:如何在确保报告专业深度与质量的同时,显著缩短撰写时间、提升产出效率?AI智能写作工具的出现,为这一难题提供了系统性解决方案。熟练掌握其应用方法,您便能高效、稳定地产出具备专业
带团队,是每个管理者必须跨过去的坎。一个人执行力再强,终究独木难支;不懂如何凝聚众人之力,结果往往是管理者自己累到崩溃,团队却一盘散沙。说到底,管理的核心不是“管”,而是“理”——理顺目标,理顺人心,理顺协作的节奏。今天,我们就来聊聊一种化繁为简的管理方法:“3个一分钟”。它就像一套管理上的“组合拳





