这看起来是一道经典的 PHP 代码审计类型的 CTF 题目。这类题目的核心在于绕过正则表达式(WAF)的限制,最终实现 RCE(远程命令执行)。
这段代码非常简洁,逻辑如下:
接收参数:通过 GET 请求接收参数 c。
过滤检查:使用 preg_match 函数对参数 c 进行正则匹配过滤。
/;|cat|flag| /i:这表示如果你的输入中包含 分号 (😉、关键词 cat、关键词 flag 或 空格,正则匹配就会成功(返回 true)。
前面的 ! 表示取反,即:如果你不包含这些字符,才会执行 system() 函数。
执行命令:system($c." >/dev/null 2>&1");
注意:这里有一个重定向 >/dev/null 2>&1,这意味着你的命令执行结果会被丢弃,页面上不会直接显示回显内容。
我们需要解决三个主要障碍:空格过滤、关键词过滤、以及结果无回显。
A. 绕过空格过滤
在 Linux 命令中,有多种方式可以替代空格:
${IFS}
$IFS9<(输入重定向,例如cat<flag.php)B.绕过关键词过滤(cat和flag)不能直接用cat和flag,我们可以尝试:替代命令:使用more,less,head,tail,tac(反向显示),nl(添加行号显示),od−c等。利用通配符:f∗匹配flag,或者f?ag。变量拼接:例如a=c;b=at;9 < (输入重定向,例如 cat<flag.php) %09 (Tab 键的 URL 编码 B. 绕过关键词过滤 (cat 和 flag) 不能直接用 cat 和 flag,我们可以尝试: 替代命令:使用 more, less, head, tail, tac (反向显示), nl (添加行号显示), od -c 等。 利用通配符:f* 匹配 flag,或者 f?ag。 变量拼接:例如 a=c;b=at;9<(输入重定向,例如cat<flag.php)B.绕过关键词过滤(cat和flag)不能直接用cat和flag,我们可以尝试:替代命令:使用more,less,head,tail,tac(反向显示),nl(添加行号显示),od−c等。利用通配符:f∗匹配flag,或者f?ag。变量拼接:例如a=c;b=at;a$b (但这里有分号限制,较难使用)。
内联执行:例如ls。
C. 解决无回显问题 (>/dev/null)
这是本题最关键的一步。由于命令后面接了重定向,我们需要截断掉后面的内容,或者让命令在后台执行。
使用 ||:如果前一个命令成功,则不执行后面。
使用 %0a (换行):在 URL 编码中代表换行符,可以开启新的一行命令,从而让后面的重定向失效。
使用 & (后台执行):在 URL 中需编码为 %26。
所以我们构造以下payload: ?c=ls%0A
首先来查看当前目录下的文件
再尝试构造一个payload来查看flag.php文件中的内容
payload为:?c=tac${IFS}f*%0a
或者是:?c=tac%09f*%0a