前言
- 前几天曾经教过的学员给我甩来了这么一道题。虽然想出了用通配符做,但是没有实际做出来,总的来说就是对无字母的webshell学习不够仔细,限于做出一道CTF题目为止的,蜻蜓点水的状态。
题目解决流程
题目源码
<?php
if(isset($_GET['evil'])){
if(strlen($_GET['evil'])>25||preg_match("/[\w$=()<>'\"]/", $_GET['evil'])){
die("danger!!");
}
@eval($_GET['evil']);
}
highlight_file(__FILE__);
?>
单个字符的Fuzz
- 题目主要是过滤了单个字符,这种Fuzz能够快速得知我们还有哪些字符能够用。编写一个脚本:
<?php
for ($ascii = 0; $ascii < 256; $ascii++) {
if (!preg_match("/[\w$=()<>'\"]/", chr($ascii))) {
echo (chr($ascii));
}
}
?>
//运行结果
// !#%&*+,-./:;?@[\]^`{|}~��������������������������������������������������������������������������������������������������������������������������������[Finished in 0.3s]
- 可以快速地看到,我们呢广告用 的只有(!#%&*+,-./:;?@[]^`{|}~),这里$,()都已经被过滤,不论是取反、异或、或运算、位运算都是通过动态拼接函数来实现执行任意代码的。这里还不能使用可见的字符,使用require来包含flag也是不可能实现的。这里还能用的就是反引号了。我们知道反引号能执行shell,它本质就是调用shell_exec,这个函数执行的shell是不会有回显的,就算catflag也不会显示出来。做到这里基本就没有思路了。
有趣的Linux shell
- 回看P神的
《无字母数字webshell之提高篇》
,可以 知道这么两个有趣的shell知识点:
1.shell下可以利用
.
来执行任意脚本2.Linux文件名支持用glob通配符代替
- 但是我们用通配符来执行这个SB脚本的时候却会报错:
- 这说明我们能够匹配上
??
的文件或者目录很多,我们直接列出来看看
- 这说明两个字符的文件还是有很多的,我们必须匹配上我们唯一的文件才有可能直线我们想要直接的代码。
有趣的glob通配符
- 我们都认识
*?
这两个通配符,其实在glob语法里面还支持类似于正则表达式的语法。例如[^S]
就是排除掉S字母,我们可以排除掉S字母然后再列目录看看,就会发现SB这个文件被排除在外。
- 但是这里我们的要求是不能有字母数字,我们刚才说了glob是支持类似正则表达式的用法,如
[0-9]
,是支持的,那么我们在aiisc表中找出两个包含大写字母之间的字符就行了这样我们就能够成功获取到SB文件。
- 从AIISC表中我们可以知道,
@-[
是在大写字母之间的,那么我构造[@-[]?
是不是能够匹配到SB了呢?答案是肯定的。
- 其实我们PHP在接受上传表单的文件流后会将文件保存到
/tmp
文件夹中,不论后端是否有编写上传的代码。而这个文件类似于这样的命名方式:/tmp/phpXXXXXX
.
- 和上面讨论的一样,这样匹配出来的回匹配到很多文件,我哦们可以看到后面两位或者一位可能是大写这样我们就可以用
.+/???/????????[@-[]
来匹配执行文件。
- 直接getflag