代码审计
<?php
if(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命令,或点符号