Introduction to the most complete upload labs clearance in the whole network (recommended Collection)

Upload labs is a shooting range to help you summarize all types of upload vulnerabilities, learn the principle of upload vulnerabilities, and reproduce the necessary shooting range environment for uploading vulnerabilities. Let's play! Project address: https://github.com/c0ny1/upload-labs

Environmental requirements

If you want to build your own environment, please configure the environment as follows before each Pass can run normally.

Configuration item

to configure

describe

operating system

Window or Linux

It is recommended to use Windows. Except that Pass-19 must be under linux, all other passes can run on Windows

PHP version

Recommendation 5.2.17

Other versions may cause some passes to fail to break through

PHP components

php_gd2,php_exif

Part of Pass depends on these two components

middleware

Setting up Apache

Connect in moudel mode

First pass

Thought discovery

  1. Upload php Trojan horse at will. It is found that the front-end reports an error, the response speed is very fast, and the data packet does not reach the server. Guess the front-end js verification

Source code interpretation

function checkFile() {
    var file = document.getElementsByName('upload_file')[0].value;
    if (file == null || file == "") {
        alert("Please select a file to upload!");
        return false;
    }
    //Define the file types allowed to upload
    var allow_ext = ".jpg|.png|.gif";
    //Extract the type of uploaded file
    var ext_name = file.substring(file.lastIndexOf("."));
    //Judge whether the uploaded file type is allowed to be uploaded
    if (allow_ext.indexOf(ext_name + "|") == -1) {
        var errMsg = "This file is not allowed to be uploaded, please upload" + allow_ext + "Type of file,The current file type is:" + ext_name;
        alert(errMsg);
        return false;
    }
}
  • The logic is to identify the suffix of the uploaded file and check whether it is one of jpg, png and gif. Otherwise, uploading is not allowed

bypass

1. Modify the front end not to use the checkfile function

  1. Directly upload php file successfully

Second pass

Thought discovery

  1. The uploaded php display file type is incorrect
  1. View the file type field by capturing the package, and guess the content type field

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = 'Upload error!';
            }
        } else {
            $msg = 'The file type is incorrect, please upload again!';
        }
    } else {
        $msg = UPLOAD_PATH.'Folder does not exist,Please create it manually!';
    }
}
  • The logic is to roughly identify the type of uploaded file and check whether it is one of image/jpge, image/png and image/gif. Otherwise, uploading is not allowed
  • $_ FILES global variable

$_FILES'myFile'

Original name of uploaded file

$_FILES'myFile'

MIME type of file

$_FILES'myFile'

The size of the uploaded file, in bytes

$_FILES'myFile'

The temporary file name stored on the server after the file is uploaded is generally the system default. You can upload in php.ini_ tmp_ Dir assignment

$_FILES'myFile'

Error code associated with the file upload

bypass

Directly capture the package and change the content type to image/png. The upload is successful

Third pass

Thought discovery

  1. Directly upload php script display prompt: it is not allowed to upload. asp,.aspx,.php,.jsp suffix files!
  1. Guess the suffix blacklist is set

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//Delete the point at the end of the file name
        $file_ext = strrchr($file_name, '.'); // Intercept the suffix after '.'
        $file_ext = strtolower($file_ext); //Convert to lowercase
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//Remove string: $DATA
        $file_ext = trim($file_ext); //Ending empty

        if(!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;// Random naming
            if (move_uploaded_file($temp_file,$img_path)) {
                 $is_upload = true;
            } else {
                $msg = 'Upload error!';
            }
        } else {
            $msg = 'Upload not allowed.asp,.aspx,.php,.jsp Suffix file!';
        }
    } else {
        $msg = UPLOAD_PATH . 'Folder does not exist,Please create it manually!';
    }
}
  • The logic is to roughly identify the type of uploaded file and check whether it is one of '. ASP', 'ASPX', 'PHP', 'JSP'. Otherwise, uploading is not allowed

bypass

  1. Try to use suffixes with the same parsing effect as php, such as php3, php4, php5, phtml, etc
  1. Uploaded successfully and parsed successfully

The fourth level

Thought discovery

  1. Direct upload php script display prompt: this file is not allowed to upload!
  2. Parameters to be verified by packet capture

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//Delete the point at the end of the file name
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //Convert to lowercase
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//Remove string: $DATA
        $file_ext = trim($file_ext); //Ending empty

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = 'Upload error!';
            }
        } else {
            $msg = 'This file is not allowed to be uploaded!';
        }
    } else {
        $msg = UPLOAD_PATH . 'Folder does not exist,Please create it manually!';
    }
}
  • The logic is roughly similar to the previous level, except that the blacklist quantity is increased. Identify the type of uploaded file and check whether it is one of the blacklist quantities. Otherwise, it is not allowed to upload. It can be seen that both case and upper case are included, and some common suffixes are also included. By viewing the data, it is found that the. htaccess suffix file is not in the blacklist and can be used.

bypass

  1. Upload a. htaccess file
  2. The content is as follows, which means that all files are parsed in php
AddType application/x-httpd-php .png
 perhaps
<FilesMatch "file name">
SetHandler application/x-httpd-php
</FilesMatch>
  1. Upload a picture horse hacker.png
  2. Direct access to the picture address is successful!

Fifth pass

Thought discovery

  1. Similar to the previous level

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//Delete the point at the end of the file name
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //Convert to lowercase
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//Remove string: $DATA
        $file_ext = trim($file_ext); //Empty head and tail
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = 'Upload error!';
            }
        } else {
            $msg = 'This file type cannot be uploaded!';
        }
    } else {
        $msg = UPLOAD_PATH . 'Folder does not exist,Please create it manually!';
    }
}
  • The logic is roughly similar to the previous level, except that the amount of. htaccess blacklist is added to identify the type of uploaded file and check whether it is one of the blacklist amount. Otherwise, uploading is not allowed. If you look closely, the case filtering is not complete, and you can use mixed case.

bypass

  1. Upload shell.PhP successfully

Sixth pass

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//Delete the point at the end of the file name
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //Convert to lowercase
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//Remove string: $DATA
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = 'This file is not allowed to be uploaded';
        }
    } else {
        $msg = $UPLOAD_ADDR . 'Folder does not exist,Please create it manually!';
    }
}
  • PHP _FILES is a predefined array used to obtain information about FILES uploaded through the POST method. If you upload a single file, FILES is a two-dimensional array; If multiple FILES are uploaded, then
Array
(
    [userfile] => Array
    (
        [name] => Screen Shot 2016-05-12 at 18.13.24.png
        [type] => image/png
        [tmp_name] => /private/var/tmp/phplVHp3W
        [error] => 0
        [size] => 344925
    )
)
  • Is the suffix blacklist, without this code file_ext = trim(file_ext); // Empty head and tail

bypass

You can bypass the space, directly capture the package, modify the file name, and then add a space at the end of the file name to upload successfully

  1. Directly upload php file successfully

The seventh pass

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //Convert to lowercase
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//Remove string: $DATA
        $file_ext = trim($file_ext); //Empty head and tail
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = 'This file is not allowed to be uploaded';
        }
    } else {
        $msg = $UPLOAD_ADDR . 'Folder does not exist,Please create it manually!';
    }
}
  • The suffix name is not processed with "." instead, strrchr(file_name, '.') just intercepts the suffix name after. Using the windows feature, the last "." in the suffix will be automatically removed, which can be bypassed by adding "." in the suffix. Missing code file_name = deldot(

bypass

Check the source code or blacklist, and there is no operation on the suffix. Using Windows features will automatically remove the last suffix. You can add. Bypass in the suffix

Eighth pass

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//Delete the point at the end of the file name
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //Convert to lowercase
        $file_ext = trim($file_ext); //Empty head and tail
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = 'This file is not allowed to be uploaded';
        }
    } else {
        $msg = $UPLOAD_ADDR . 'Folder does not exist,Please create it manually!';
    }
}
  • The logic is to roughly identify the type of uploaded file and check whether it is one of '. ASP', 'ASPX', 'PHP', 'JSP'. Otherwise, uploading is not allowed. The code file_ext = str_ireplace('::DATA', '', file_ext); / / remove the string:: DATA

bypass

  • The NTFS file system includes support for alternate DATA streams, mainly including providing compatibility with files in the Macintosh file system. Alternate DATA streams allow files to contain multiple DATA streams. Each file has at least one DATA stream. In windows, this default DATA stream is called: DATA. Upload. php::DATA. (Windows only)

The ninth pass

Source code interpretation

 $is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//Delete the point at the end of the file name
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //Convert to lowercase
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//Remove string: $DATA
        $file_ext = trim($file_ext); //Empty head and tail
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = 'This file is not allowed to be uploaded';
        }
    } else {
        $msg = $UPLOAD_ADDR . 'Folder does not exist,Please create it manually!';
    }
}
  • Check the source code. It is filtered only once, so you can directly construct. php. To bypass it

bypass

Direct construction point plus space plus dot. php. Bypass

Can pass https://localhost/upload-labs/upload/shell1.php Access mm

The tenth level

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $file_name)) {
            $img_path = $UPLOAD_ADDR . '/' .$file_name;
            $is_upload = true;
        }
    } else {
        $msg = $UPLOAD_ADDR . 'Folder does not exist,Please create it manually!';
    }
}
  • file_name = str_ireplace(deny_ext,"",

bypass

1. Double write bypass

The eleventh pass

Source code interpretation

$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 = 'Upload failed!';
        }
    }
    else{
        $msg = "Upload only.jpg|.png|.gif Type file!";
    }
}
  • The strrpos() function looks for the last occurrence of a string in another string
  • Is the white list of suffix names. Intercept the suffix names and name them randomly

bypass

$_ GET['save_path '] has controllable incoming parameters and can be truncated with% 00

The twelfth pass

Source code interpretation

$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 = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = "Upload failed";
        }
    }
    else{
        $msg = "Upload only.jpg|.png|.gif Type file!";
    }
}
  • Similar to the previous level, it only becomes POST submission

bypass

%00 cut for splicing

13th pass

Source code interpretation

function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //Read only 2-byte read file header
    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;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "Unknown file, upload failed!";
    }else{
        $img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = "Upload failed";
        }
    }
}
  • The file header and file type will be read, and the picture mm has been prompted

bypass

Make picture mm upload

Parsing in combination with File Inclusion

The fourteenth pass

Source code interpretation

 function isImage($filename){
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
        $info = getimagesize($filename);
        $ext = image_type_to_extension($info[2]);
        if(stripos($types,$ext)){
            return $ext;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
        $msg = "Unknown file, upload failed!";
    }else{
        $img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = "Upload failed";
        }
    }
}

Here, use getimagesize to get the file type

bypass

Or can we use the picture directly to bypass the horse

The 15th pass

Source code interpretation

function isImage($filename){
    //PHP needs to be turned on_ EXIF module
    $image_type = exif_imagetype($filename);
    switch ($image_type) {
        case IMAGETYPE_GIF:
            return "gif";
            break;
        case IMAGETYPE_JPEG:
            return "jpg";
            break;
        case IMAGETYPE_PNG:
            return "png";
            break;    
        default:
            return false;
            break;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
        $msg = "Unknown file, upload failed!";
    }else{
        $img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").".".$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = "Upload failed";
        }
    }
}

PHP is used here_ EXIF module to determine the file type

bypass

Or can we use the picture directly to bypass the horse

The sixteenth pass

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    // Get the basic information of the uploaded file, file name, type, size and temporary file path
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=$UPLOAD_ADDR.basename($filename);

    // Gets the extension of the uploaded file
    $fileext= substr(strrchr($filename,"."),1);

    //Judge the file suffix and type, and upload only if it is legal
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //Use the uploaded image to generate a new image
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
                $msg = "The file is not jpg Format picture!";
            }else{
                //Assign a file name to the new picture
                srand(time());
                $newfilename = strval(rand()).".jpg";
                $newimagepath = $UPLOAD_ADDR.$newfilename;
                imagejpeg($im,$newimagepath);
                //Display the image after secondary rendering (new image generated using the image uploaded by the user)
                $img_path = $UPLOAD_ADDR.$newfilename;
                unlink($target_path);
                $is_upload = true;
            }
        }
        else
        {
            $msg = "Upload failed!";
        }

    }else if(($fileext == "png") && ($filetype=="image/png")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //Use the uploaded image to generate a new image
            $im = imagecreatefrompng($target_path);

            if($im == false){
                $msg = "The file is not png Format picture!";
            }else{
                 //Assign a file name to the new picture
                srand(time());
                $newfilename = strval(rand()).".png";
                $newimagepath = $UPLOAD_ADDR.$newfilename;
                imagepng($im,$newimagepath);
                //Display the image after secondary rendering (new image generated using the image uploaded by the user)
                $img_path = $UPLOAD_ADDR.$newfilename;
                unlink($target_path);
                $is_upload = true;               
            }
        }
        else
        {
            $msg = "Upload failed!";
        }

    }else if(($fileext == "gif") && ($filetype=="image/gif")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //Use the uploaded image to generate a new image
            $im = imagecreatefromgif($target_path);
            if($im == false){
                $msg = "The file is not gif Format picture!";
            }else{
                //Assign a file name to the new picture
                srand(time());
                $newfilename = strval(rand()).".gif";
                $newimagepath = $UPLOAD_ADDR.$newfilename;
                imagegif($im,$newimagepath);
                //Display the image after secondary rendering (new image generated using the image uploaded by the user)
                $img_path = $UPLOAD_ADDR.$newfilename;
                unlink($target_path);
                $is_upload = true;
            }
        }
        else
        {
            $msg = "Upload failed!";
        }
    }else{
        $msg = "Only upload with suffix.jpg|.png|.gif My picture file!";
    }
}
  • This level comprehensively judges the suffix name, content type, and uses imagecreate fromgif to judge whether it is a gif image. Finally, it makes a secondary rendering

bypass

17th pass

Source code interpretation

$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = $UPLOAD_ADDR . '/' . $file_name;

    if(move_uploaded_file($temp_file, $upload_file)){
        // Moving pictures first is a prerequisite for conditional competition
        if(in_array($file_ext,$ext_arr)){
             $img_path = $UPLOAD_ADDR . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             unlink($upload_file);
             $is_upload = true;
        }else{
            $msg = "Upload only.jpg|.png|.gif Type file!";
            unlink($upload_file);
        }
    }else{
        $msg = 'Upload failed!';
    }
}
  • Here, first upload the file to the server, then change the name through rename, and then delete the file through unlink. Therefore, you can access the webshell before unlink through conditional competition

bypass

First, send and upload web shell data packets in burp, and then access them in the browser. It is found that they can be accessed through competition.

18th pass

Source code interpretation

/index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    require_once("./myupload.php");
    $imgFileName =time();
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload($UPLOAD_ADDR);
    switch ($status_code) {
        case 1:
            $is_upload = true;
            $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
            break;
        case 2:
            $msg = 'The file has been uploaded but not renamed.';
            break; 
        case -1:
            $msg = 'This file cannot be uploaded to the temporary file storage directory of the server.';
            break; 
        case -2:
            $msg = 'Upload failed. The upload directory is not writable.';
            break; 
        case -3:
            $msg = 'Upload failed. This type of file cannot be uploaded.';
            break; 
        case -4:
            $msg = 'Upload failed. The uploaded file is too large.';
            break; 
        case -5:
            $msg = 'Upload failed. A file with the same name already exists on the server.';
            break; 
        case -6:
            $msg = 'The file cannot be uploaded and cannot be copied to the target directory.';
            break;      
        default:
            $msg = 'Unknown error!';
            break;
    }
}

//myupload.php
class MyUpload{
......
......
...... 
  var $cls_arr_ext_accepted = array(
      ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
      ".html", ".xml", ".tiff", ".jpeg", ".png" );

......
......
......  
  /** upload()
   **
   ** Method to upload the file.
   ** This is the only method to call outside the class.
   ** @para String name of directory we upload to
   ** @returns void
  **/
  function upload( $dir ){
    
    $ret = $this->isUploadedFile();
    
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->setDir( $dir );
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkExtension();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkSize();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }
    
    // if flag to check if the file exists is set to 1
    
    if( $this->cls_file_exists == 1 ){
      
      $ret = $this->checkFileExists();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }

    // if we are here, we are ready to move the file to destination

    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }

    // check if we need to rename the file

    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
    
    // if we are here, everything worked as planned :)

    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
...... 
};
  • Need to upload a picture mm
  • This pass makes a white list judgment on the file suffix, and then checks the file size, file existence, etc. step by step

bypass

After uploading the file and renaming the file, there is also a vulnerability of conditional competition. burp can be continuously used to send data packets for uploading pictures. Due to competition conditions, the program will have no time to rename, so the upload is successful:

19th pass

Source code interpretation

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");

        $file_name = $_POST['save_name'];
        $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);

        if(!in_array($file_ext,$deny_ext)) {
            $img_path = $UPLOAD_ADDR . '/' .$file_name;
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $img_path)) { 
                $is_upload = true;
            }else{
                $msg = 'Upload failed!';
            }
        }else{
            $msg = 'It is forbidden to save as this type of file!';
        }

    } else {
        $msg = $UPLOAD_ADDR . 'Folder does not exist,Please create it manually!';
    }
}
  • file_name = _POST['save_name']; Variable controllable found in move_ uploaded_ IMG in file() function_ Path is saved by the post parameter_ Name, so you can save_ Name used 00 truncation to bypass:

Posted on Fri, 26 Nov 2021 02:15:15 -0500 by xydra