ctf show web 入门95
2026/5/17 3:58:53 网站建设 项目流程

这是一道典型的 PHP 弱类型与内置函数特性绕过的 CTF(Capture The Flag)题目。我们的目标是绕过层层 if 过滤,最终让代码执行到 echo $flag;。
下面为你梳理出这道题的核心解题思路和绕过技巧:
核心代码分析与绕过策略
我们需要分析每一个限制条件,并找到一个能够同时满足所有条件的 num 参数。

  1. 第一关:不能直接等于 4476
if($num==4476){die("no no no!");}

分析:这里使用了 PHP 的弱类型比较 ==。如果传入 4476,直接被拦截。
绕过思路:我们需要传入一个字符串,它在后续的 intval() 中能变成 4476,但在这一步不直接等于 4476。例如,利用空格、加号、进制转换或科学计数法。
2. 第二关:正则过滤

if(preg_match("/[a-z]|\./i",$num)){die("no no no!!");}```分析:/[a-z]|\./i 表示过滤了所有英文字母(不分大小写)和小数点 .。 受限点:这意味着我们不能使用十六进制(如 0x... 包含 x)、科学计数法(包含 e)以及浮点数形式(包含 .)来绕过。 3. 第三关:必须包含字符 "0"(核心难点) ```phpif(!strpos($num,"0")){die("no no no!!!");}```分析:strpos($num, "0") 用于查找字符 "0" 在字符串 $num 中首次出现的位置。 如果没找到,返回 false,取反后变为 true,触发 die。 大坑:如果 "0" 放在字符串的第一位(索引为 0),strpos 会返回 0。在 PHP 中,!0 也是 true,同样会触发 die! 绕过思路:字符串 $num 中必须包含数字 0,且绝对不能放在第一位。 4. 第四关:终点线 ```phpif(intval($num,0)===4476){echo$flag;}

分析:这里使用了强类型比较 ===。intval(num,0)的结果必须严格等于整数4476。函数特性:intval(num, 0) 的结果必须严格等于整数 4476。 函数特性:intval(num,0)的结果必须严格等于整数4476。函数特性:intval(num, $base) 当第二个参数 $base 为 0 时,PHP 会根据字符串的前缀来自动检测进制:
如果以 0x 开头,认为是十六进制(已被正则拦截,排除)。
如果以 0 开头,认为是八进制。
否则,认为是十进制。
构造 Payload 的逻辑推理
尝试八进制绕过:
十进制的 4476 转换为八进制是 010574。
满足第四关:intval(“010574”, 0) 会将其当作八进制解析,结果正是 4476。
满足第一关:“010574” == 4476 在弱类型比较时,字符串 “010574” 会转换为十进制数字 10574,不等于 4476。
满足第二关:全是数字,没有字母和小数点。
卡在第三关:“010574” 的第一个字符就是 “0”,导致 strpos(“010574”, “0”) 返回 0,被 !strpos 拦截。
解决第三关(如何让 0 不在第一位,同时不影响 intval):
intval() 函数在解析字符串时,会自动忽略字符串开头的空格或空白字符(如空格、\t、\n、\r 等)。
如果我们构造:[空格]010574
strpos(" 010574", “0”) 的返回值将是 1(因为前面有一个空格)。!1 为 false,成功绕过第三关!
同时,intval(" 010574", 0) 忽略空格,识别到 0 开头,继续按八进制解析为 4476,成功通关!
最终解题 Payload
在 URL 中,空格可以直接敲空格,或者使用 URL 编码 %20。
payload为:?num= 010574

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

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

立即咨询