CTF新手入门从HUBUCTF签到题解密PHP弱类型比较的陷阱在CTF竞赛的Web题目中PHP的弱类型比较漏洞堪称经典永流传。去年HUBUCTF新生赛的一道签到题就让不少新手选手第一次见识到这个看似简单却暗藏玄机的特性。本文将带您深入剖析这道checkin题背后的技术原理并通过实战演示如何利用弱类型比较漏洞获取flag。1. 初识PHP弱类型比较PHP作为一门弱类型语言其变量不需要声明具体类型这为开发带来便利的同时也埋下了安全隐患。其中最典型的莫过于松散比较与严格比较的区别。松散比较的核心规则如果比较的两个值类型不同PHP会尝试进行类型转换后再比较布尔值true与任何非空字符串比较结果为true数字0与字符串0比较结果为true空字符串与数字0比较结果为truevar_dump(true hello); // bool(true) var_dump(0 0); // bool(true) var_dump( 0); // bool(true)严格比较的规则不仅比较值还比较类型只有类型和值都相同时才返回truevar_dump(true hello); // bool(false) var_dump(0 0); // bool(false)2. HUBUCTF checkin题目深度解析让我们回到HUBUCTF 2022新生赛的这道签到题。题目给出了以下关键代码片段include(flag.php); $data_unserialize unserialize($_GET[info]); if ($data_unserialize[username]$username $data_unserialize[password]$password) { echo $flag; }2.1 题目漏洞点分析反序列化用户输入直接使用unserialize()处理GET参数存在反序列化漏洞风险弱类型比较使用而非进行身份验证变量覆盖flag.php中可能修改了$username和$password的值2.2 解题思路构建正常思路是获取$username和$password的实际值但由于它们被flag.php修改我们无法直接知道。这时就要利用弱类型比较的特性构造一个数组使username和password字段在松散比较下等于任意值选择布尔值true作为字段值因为true与大多数非空值比较都会返回true序列化这个数组作为payload3. 漏洞利用实战演示3.1 构造恶意序列化数据创建包含布尔值的数组并序列化$payload array( username true, password true ); echo serialize($payload);输出结果a:2:{s:8:username;b:1;s:8:password;b:1;}3.2 发送Payload获取flag将序列化后的字符串作为info参数传递?infoa:2:{s:8:username;b:1;s:8:password;b:1;}3.3 为什么这样能成功无论$username和$password被修改为什么值只要不是空字符串或0true $username和true $password都会返回true从而满足if条件输出flag4. 防御方案与最佳实践4.1 代码层面的防御使用严格比较if ($data_unserialize[username] $username $data_unserialize[password] $password)限制反序列化// 使用json_decode代替unserialize $data json_decode($_GET[info], true);类型检查if (is_string($data[username]) is_string($data[password]))4.2 CTF中的其他弱类型比较陷阱MD5碰撞if ($_GET[a] ! $_GET[b] md5($_GET[a]) md5($_GET[b]))可以利用0e开头的哈希值如240610708strcmp漏洞if (strcmp($password, $_POST[password]) 0)传递数组可使strcmp返回NULLNULL0为truein_array松散比较if (in_array($_GET[role], [admin, user]))传递0可能匹配到admin如果admin在转换后等于05. 举一反三CTF中的类型把戏除了PHP弱类型比较CTF中还有许多与类型相关的考点JavaScript类型混淆if (1 prompt(Input) 1) console.log(flag)输入空数组[]可实现1[]11Python的与is区别if user_input is admin: # 错误用法应该使用而不是is进行值比较SQL注入中的类型转换SELECT * FROM users WHERE id 1abc字符串1abc可能被转换为数字1在CTF比赛中理解这些类型系统的特性往往能发现出人意料的漏洞。建议新手在解题时多思考这里使用了哪种比较方式如果类型不同会发生什么