0x01
进入题目
有一个上传页面
那看来就是要上传shell,然后来查看flag了。看一下页面给的代码
if($contents=file_get_contents($_FILES["file"]["tmp_name"])){
$data=substr($contents,5);
foreach ($black_char as $b) {
if (stripos($data, $b) !== false){
die("illegal char");
}
}
}
有文件包含功能,包含我们上传的文件,那如果我们写入shell,那么我们的shell文件将被包含,从而我们可以执行命令。但是,这里对文件内容做了一定的过滤,所以我们需要知道都过滤了什么,什么没有过滤,这里用python写个小字典fuzz一下,下面是我用bpfuzz的结果
可以看到,上面的字符都是没有被过滤的,那么我们就需要用到这些字符来进行shell的编写
0x02
这里就需要不用数字和字符串写一句话后门,那么核心思路就是将非字母,非数字的字符经过各种变换,最后构造出a-z中的任意字符,用这种方式写一句话后门
方法一
在php中,两个字符串执行异或操作后,得到的还是一个字符串。所以我们就需要找到两个非字母,非数字的字符串,让它们的异或结果是某个字母就行,你比如说:
('%13'^'`') //s 这个是php5版本的
('%13'^'`') //E 这个是php7版本的
不同版本的结果是不同的,这里我参考的是大佬的文章,里面只是介绍了php5版本的利用,所以这里我就暂时只用php5,php7版本的有机会补上
方法二
这里还可以运用取反的操作,具体原理就是利用UTF-8编码中的某个汉字,并将其中某个字符取出来结果如下
原理就是‘和’{2}的结果是“x8c”,然后再取反运算,从而得到字母s,利用这个特性可以构造payload
echo ~茉[$____]; //s
echo ~内[$____]; //y
echo ~茉[$____]; //s
echo ~苏[$____]; //t
echo ~的[$____]; //e
echo ~咩[$____]; //m
echo ~课[$____]; //P
echo ~尬[$____]; //O
echo ~笔[$____]; //S
echo ~端[$____]; //T
echo ~瞎[$____]; //a
这个是php7版本下的
直接上传一个php文件
这里说一下,因为这道题我是在buuctf上做的复现,但是它这个环境可能有点问题,flag不在这个文件,没有写进去,后来经过师傅指点,可以通过env命令来获取flag,结果如下
env命令:打印当前的环境变量
从这里可以看出,flag这个动态变量没有写进去文件,可能是环境布置有问题
总结
对于webshell的写法有了更多的认识,当过滤掉字母和数字的时候,还可以通过异或运算或者取反运算来获得自己想要的字母从而构成webshell,避免了规则的检测。
参考文章:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html