相对于前面的黑名单绕过,白名单更加难以绕过,使用白名单验证相对比较安全,但如果存在可控参数目录,也存在被绕过的风险
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
}
else{
$msg = '上传失败!';
}
}
else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
deny_arr变成ext_arr,白名单,下面判断后缀名是否在白名单中,代码相较于黑名单也简单不少
但是这里使用了$_GET['save_path']获取客户端的值,这个值可以被客户端修改,从而遗留安全隐患
%00截断需要gpc关闭 php版本要小于5.3.4版本
我这里版本是5.4.45先选择一个低版本
关闭gpc
这种攻击手法其实与sql注入中的注释差不多,%00的意思是忽略后面的内容进行上传,如果我们上传test.png再给服务器传递的save_path改为/upload/test.php%00那么最终上传到服务器的内容为test.php,操作一下,看起来就直观了
看到这里save_path其实就是本地的upload文件夹的路径,在后端中与检测后的文件名拼接,将文件上传,我们通过截断,忽略检测后的内容,直接上传到我们写入的文件中
因为已知是get型,所以直接写%00就ok,get型需要进行编码
放包
上传成功
只是将GET改成POST了
一样的套路,上传test.php抓包
直接在抓包里进行解码再放包就ok了
有的文件上传,上传时会检测文件头,不同的文件,文件头也不一样,常见的文件上传图片头检测 它检测图片两个字节长度,如果不是图片格式,会禁止上传文件
PNG:89504E47
JPEG:FFD8FF
GIF:47494638
....
对隐写术有些了解的同学应该对这个很熟悉啦
nction getReailFileType($filename){
$file = fopen($filename, "rb");
$bin = fread($file, 2); //只读2字节
fclose($file);
$strInfo = @unpack("C2chars", $bin);
$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
$fileType = '';
switch($typeCode){
case 255216:
$fileType = 'jpg';
break;
case 13780:
$fileType = 'png';
break;
case 7173:
$fileType = 'gif';
break;
default:
$fileType = 'unknown';
}
return $fileType;
}
这时提取文件头的函数
对文件进行解包
转成整型,然后白名单判断
下面就是获取上传文件,调用这个函数,返回如果不是unknown就上传,代码就不展示了
为了绕过上述的检测,我们可以制作图片马,即将图片信息与木马组合到一起上传
准备一张正常的图片,与恶意脚本php,放到一个目录下
目录下运行CMD,执行
copy 1.png/b+test.php test.png
生成了一个新的png,我们直接给它上传到服务器
右键图片打开链接(获取图片地址),复制url
upload/3520221023175627.png
这里需要利用文件包含漏洞,才能执行我们的图片马
我看大佬们这一关直接有个提示,有个链接,就是存在文件包含漏洞网页,但我这个靶场可能抽风了,我找了半天也没找到,所以我就自己写了一个,如果你们也没有可以直接再upload-labs文件夹下新建一个include.php
复制保存就ok了
下面进入文件包含漏洞页面
将图片地址给传进去
看到一堆乱码,这就是前面图片的内容,往下翻,就可以看到phpinfo()的结果啦
上传成功!
getimagesize是获取图片的大小,如果头文件不是图片会报错,直接可以利用图片马
一样的上传我们做好的图片马,通过包含漏洞,进行执行