uplaod-labs 21:
源码:
$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){
//检查MIME
$allow_type = array('image/jpeg','image/png','image/gif');
if(!in_array($_FILES['upload_file']['type'],$allow_type)){
$msg = "禁止上传该类型文件!";
}else{
//检查文件名
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
$ext = end($file);
$allow_suffix = array('jpg','png','gif');
if (!in_array($ext, $allow_suffix)) {
$msg = "禁止上传该后缀文件!";
}else{
$file_name = reset($file) . '.' . $file[count($file) - 1];
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' .$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$msg = "文件上传成功!";
$is_upload = true;
} else {
$msg = "文件上传失败!";
}
}
}
}else{
$msg = "请选择要上传的文件!";
}
代码分析:
本关为该系列靶场最后一关,当中使用了很多陌生的函数,让我们来一一认识它们。
在代码第5、6行设置了 Content-Type 白名单,检测请求头中 Content-Type 是否为 $allow_type 中的
三种类型。如果 Content-Type 为白名单中的类型的话,会在代码第10、11行判断传入的文件是否为
POST传入,如果POST没有传入文件名则使用 $_FILES 中获取到的文件名并且如果$file不是 $_FILE 传
入的话则使用 explode() 将内容以 . 进行分割并以数组的形式进行返回以便后续调用。
在代码第15行使用 end() 函数将获取$file数组进中最后一个数组元素,也就是获取后缀名,然后在代码
第17行与白名单中后缀进行比较,如果在白名单中则在代码第20行将 reset() 函数获取的文件名与
count() 函数获取的文件后缀进行拼接组成新的文件名,然后在23行进行移动。
explode()
定义和用法:
explode() 函数使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
语法:
explode(separator,string,limit)
separator 必需。规定在哪里分割字符串。
string 必需。要分割的字符串。
limit 可选。规定所返回的数组元素的数目。
可能的值:
大于 0 - 返回包含最多 limit 个元素的数组
小于 0 - 返回包含除了最后的 -limit 个元素以外的所有元素的数组
0 - 会被当做 1, 返回包含一个元素的数组
返回值:返回字符串数组。
end()
定义和用法:
end() 函数将内部指针指向数组中的最后一个元素,并输出。
语法:
end(array)
array 必需。规定要使用的数组。
返回值:
如果成功则返回数组中最后一个元素的值,如果数组为空则返回 FALSE。
reset()
该函数与上述 end() 类似,类似函数还有 current() 、 next() 、 prev() 、 each() 。
定义和用法:
reset() 函数将内部指针指向数组中的第一个元素,并输出。
语法:
reset(array)
返回值:
如果成功则返回数组中第一个元素的值,如果数组为空则返回 FALSE。
count()
定义和用法:
count() 函数返回数组中元素的数目。
语法:
count(array,mode);
array 必需。规定要计数的数组。
mode 可选。规定函数的模式。可能的值:
0 - 默认。不计算多维数组中的所有元素。
1 - 递归地计算数组中元素的数目(计算多维数组中的所有元素)
返回值:
返回数组中元素的数目。
绕过方法:
这里可以构造 save_name[0] = upload-20.php ,save_name[2] = png ,这样数组的长度为2,
save_name[1] = null ,所以最终 file_name=upload-20.php.