目录
文件上传
1、文件上传完整代码
PHP代码
<?php
header("Content-Type:text/html; charset=utf-8");
require_once('pclzip.lib.php');
// echo "<pre>";
// var_dump($_POST['username']);exit;
// // var_dump(file_get_contents("php://input"));exit;
// // var_dump($GLOBALS['HTTP_RAW_POST_DATA']);exit;
// if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
// exit('环境不支持');
// }
// // 创建图片存储文件夹
// $dir = 'upload/';
// if (!file_exists($dir)) {
// mkdir($dir);
// }
function check_dir($dir){
$handle = opendir($dir);
while(($f = readdir($handle)) !== false){
if(!in_array($f, array('.', '..'))){
if(is_dir($dir.$f)){
check_dir($dir.$f.'/');
}else{
$ext = strtolower(substr(strrchr($f, '.'), 1));
if(!in_array($ext, array('jpg', 'gif', 'png'))){
unlink($dir.$f);
}
}
}
}
}
// // 创建图片存储的临时文件夹
// $temp = $dir.'member/1/';
// if (!file_exists($temp)) {
// mkdir($temp);
// }
// $filename = $temp.'avatar.zip'; // 存储flashpost图片
// file_put_contents($filename, $GLOBALS['HTTP_RAW_POST_DATA']);
// //第三次绕过
// // $zip=new ZipArchive;//新建一个ZipArchive的对象
// // if(!$zip->open($filename)){
// // //check_dir($dir);
// // exit("fail to open zip file");
// // }
// // if(!$zip->extractTo($temp)) {
// // exit("fail to extract zip file");
// // }
// $archive = new PclZip($filename);
// if ($archive->extract(PCLZIP_OPT_PATH, $temp, PCLZIP_OPT_REPLACE_NEWER) == 0) {
// check_dir($dir);
// exit("解压失败");
// }
// check_dir($dir);
// exit('success');
$file = $_FILES['file'];
if (!$file) {
exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'upload/';
$ext = strtolower(substr(strrchr($name, '.'), 1));
//递归删除 zip 1 web.php
// function check_dir($dir)
// {
// $handle = opendir($dir);
// while (($f = readdir($handle)) !== false) {
// if (!in_array($f, array('.', '..'))) {
// $ext = strtolower(substr(strrchr($f, '.'), 1));
// if (!in_array($ext, array('jpg', 'gif', 'png'))) {
// unlink($dir . $f);
// }
// }
// }
// }
// mkdir($dir);
if (!is_dir($dir)) {
mkdir($dir);
}
/**
* 1.未进行递归删除,导致文件夹内的webshell得以保留
* 修复方法(递归删除,又造成了新的问题)
* 2.由于先解压,再删除,导致暴力getshell
* (时间竞争拿下webshell)
* 3.将上传目录改为随机数,不能访问,自然不能getshell
* (可以创造一个加压出错的zip包,虽然解压出错,但其他webshell,以及被解压出来
* 同时,出错直接exit结束程序,不会执行后续递归删除操作
* )
* 4.解压即便失败,依然使用递归删除,然后退出,这样一来,可以将解压出的文件删除
* (制造一个特殊名称的webshell,../../../../web.php,当解压时,直接解压到根目录
* 随后,无论如何删除,也不能影响我们getshell
* )
* 可以将压缩解压缩操作放在非web目录下执行,将需要的文件移动到web目录下,这样可以从
* 根本解决以上问题
*
* 找到问题的关键,才可以解决,不然无异于盲人摸象。
*/
$temp_dir = $dir.md5(time(). rand(1000,9999)).'/';
// $temp_dir = $dir . 'member/1/';
if (!is_dir($temp_dir)) {
mkdir($temp_dir);
}
if (in_array($ext, array('zip', 'jpg', 'gif', 'png'))) {
if ($ext == 'zip') {
// $zip = new ZipArchive;
// if(!$zip->open($file['tmp_name'])) {
// echo "fail";
// return false;
// }