CTF Web 入门从[HCTF 2018]WarmUp看PHP白名单绕过的2种核心技巧在CTF Web安全竞赛中PHP代码审计是常见的挑战类型。本文将以经典题目[HCTF 2018]WarmUp为例深入剖析两种关键的PHP白名单绕过技巧帮助初学者建立系统化的解题思路。1. 题目背景与代码分析首先我们查看题目提供的核心代码片段class emmm { public static function checkFile($page) { $whitelist [sourcesource.php,hinthint.php]; if (!isset($page) || !is_string($page)) { echo you cant see it; return false; } if (in_array($page, $whitelist)) { return true; } $_page mb_substr($page, 0, mb_strpos($page.?, ?)); if (in_array($_page, $whitelist)) { return true; } $_page urldecode($page); $_page mb_substr($_page, 0, mb_strpos($_page.?, ?)); if (in_array($_page, $whitelist)) { return true; } echo you cant see it; return false; } }这段代码实现了一个白名单校验机制主要功能点包括定义白名单$whitelist仅允许访问source.php和hint.php通过in_array()检查输入是否在白名单中使用mb_substr()和mb_strpos()处理带参数的URL对输入进行URL解码后再次检查2. 关键PHP函数解析2.1 mb_substr与mb_strpos组合这两个函数在处理多字节字符时特别重要函数描述危险用法示例mb_substr()安全的多字节字符串截取mb_substr($input, 0, mb_strpos($input.?, ?))mb_strpos()返回字符串在另一字符串中首次出现的位置可能被用于构造特殊路径典型利用场景// 当输入为source.php?../../../../flag时 $_page mb_substr($page, 0, mb_strpos($page.?, ?)); // $_page source.php2.2 in_array函数特性in_array()函数用于检查值是否存在于数组中// 严格模式关闭时存在类型转换问题 in_array(1, [a, 1, b]); // 返回true2.3 urldecode的双重解析PHP会对GET参数自动进行一次URL解码手动调用urldecode()可能导致双重解码原始输入: source.php%253f../../flag 第一次解码: source.php%3f../../flag 第二次解码: source.php?../../flag3. 第一种绕过技巧字符串截断利用mb_substr和mb_strpos的组合特性我们可以构造特殊路径绕过检查构造原理在文件名后添加?字符利用截断获取白名单通过的前缀附加实际要访问的路径Payload示例/source.php?../../../../ffffllllaaaagggg操作步骤检查source.php?的前缀source.php在白名单中include实际加载的是source.php?../../../../ffffllllaaaagggg服务器解析时会忽略?后的路径参数注意这种技巧依赖于服务器对包含路径的特殊处理方式不同环境可能有差异。4. 第二种绕过技巧双重URL编码利用URL解码特性构造特殊输入构造原理对关键字符?进行双重编码(%253f)第一次自动解码为%3f第二次urldecode()解码为?Payload示例/source.php%253f../../../../ffffllllaaaagggg代码执行流程$_page urldecode(source.php%253f../../flag); // 变为source.php%3f../../flag $_page mb_substr($_page, 0, mb_strpos($_page.?, ?)); // 截取后变为source.php5. 防御方案对比针对这类白名单绕过开发者可以采取以下防护措施防护措施有效性实现复杂度使用realpath()解析路径★★★★★中等严格模式in_array(..., true)★★★☆☆简单禁用危险函数如include★★★★★高白名单完整路径校验★★★★☆中等6. 实战思维导图以下是面对类似白名单校验时的通用解题思路确定白名单内容查找in_array或白名单数组定义确认允许访问的基础文件分析校验逻辑检查字符串处理流程识别可能的截断点尝试绕过方法参数附加法添加?或#路径遍历../编码混淆双重URL编码验证包含结果测试文件包含是否成功检查错误信息获取线索7. 扩展训练建议为了巩固这些技巧建议尝试以下练习修改题目代码使两种绕过方法都失效在Docker环境中搭建类似题目研究其他CTF题目中的白名单绕过案例编写自动化检测脚本识别这类漏洞掌握这些核心技巧后面对大多数PHP白名单校验场景都能快速找到突破点。在实际CTF比赛中灵活组合多种技巧往往能解决更复杂的挑战。