File upload vulnerability -- replay of upload labs shooting range (off 8-17)

Download range link

Related principles
① $DATA bypass:

php under windows system, if the file name + ":: $DATA"

The DATA after:: $DATA will be treated as a file stream, the suffix will not be detected, and the file name before:: $DATA will be retained
In this way, the purpose of bypassing suffix detection can be achieved
Level 9
Source code and tips

$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",".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 = 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.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            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!';
    }
}


Upload php file

Grab bag

Modify suffix and add:: $DATA


Upload successful
If you visit, you can visit directly php file

② . Space Bypass and use the imperfection of the validation rules to pass the file name In windows system, if there is a suffix at the end of the file Or spaces will be automatically removed
Chapter 10 source code and prompt

$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",".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); //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!';
    }
}


Analyze the source code, we upload the shell php file, first delete the point at the end, and then get the suffix php, then turn it to lowercase, then remove:: $DATA, then remove the space at the beginning and end, and then judge whether it is in the blacklist

Packet capture modification suffix

After analysis, the uploaded file name is shell php. .
First, delete the dot at the end of the file name to get the shell php. , Then get the first one And its suffix, i.e php. , Then convert to lowercase, then remove the string:: $DATA, and then empty the beginning and end php., The last upload is shell php., Due to the last suffix of file name in windows system Will be automatically removed to achieve the purpose of uploading PHP files



③ Double write bypass, some WAFS will replace illegal suffixes with empty ones, such as a.php, which is detected to have PHP is then replaced and the file name is changed to a
At this point, you can try a.pphphp. After PHP is deleted, the remaining one becomes a.php
Chapter 11 source code and tips

$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","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $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 = UPLOAD_PATH . 'Folder does not exist,Please create it manually!';
    }
}


Analyze the source code and use str_ The ireplace function replaces the suffix appearing in the blacklist with an empty one
Packet capture and double write bypass


④ % 00 truncation, utilization condition: php version < = 5.3.4, php Magic in INI file_ quotes_ gpc=off
Usage principle: the following content is truncated by manually adding string identifier, and the latter content can just help bypass the detection

Chapter 12 source code and tips

$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 error!';
        }
    } else{
        $msg = "Upload only.jpg|.png|.gif Type file!";
    }
}


Analyze the source code: set the whitelist, only allow JPG, PNG and GIF suffix files to upload, then intercept the file suffix for whitelist verification, and then generate the file path. The default is save_ The path is / upload. We can change it to / upload / shell4 PHP% 00. If there is no shell4.0 in this directory PHP, will automatically generate a shell4 PHP file, and then the code generated with random number and date will be truncated and the uploaded file will be written to shell4 PHP file. Note that the suffix of the uploaded file should also be modified when capturing the package

Packet capture modification


At this time, shell4 The statement after PHP will be truncated

Chapter 13 source code and prompt

$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!";
    }
}


The difference from the previous level is that the path here is submitted in post mode. At this time, it should be noted that in the post mode,% 00 will be treated as a character and will not be parsed. What needs to be modified at this time is the binary file
Direct modification:

fail

Modify binary


Upload successful

⑤ Picture horse
Level 14

function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //Read only 2 bytes
    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_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "Upload error!";
        }
    }
}

The file contains the source code of the vulnerability:


Make picture horse
Use the picture file a.png, Trojan file shell PHP to generate the picture horse b.png



Open it with notepad, and you can see a sentence at the end of the file

Direct upload

Upload successful

Access on file containing vulnerability page

An error is reported, indicating that the php file is parsed
You can try connecting with a kitchen knife

Level 15 can also use the picture horse made by level 14

⑥ Secondary rendering bypass
Second rendering refers to that the server extracts the content information of the uploaded pictures and then recombines them
We can get the newly generated image, and then compare it with our image horse to see the difference between the newly generated image and the original image, and then construct the image horse again
Chapter 17 source code and tips

$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_PATH.'/'.basename($filename);

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

    //Judge the file suffix and type, and upload only when 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!";
                @unlink($target_path);
            }else{
                //Assign a file name to the new picture
                srand(time());
                $newfilename = strval(rand()).".jpg";
                //Display the image after secondary rendering (new image generated by the image uploaded by the user)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "Upload error!";
        }

    }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!";
                @unlink($target_path);
            }else{
                 //Assign a file name to the new picture
                srand(time());
                $newfilename = strval(rand()).".png";
                //Display the image after secondary rendering (new image generated by the image uploaded by the user)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagepng($im,$img_path);

                @unlink($target_path);
                $is_upload = true;               
            }
        } else {
            $msg = "Upload error!";
        }

    }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!";
                @unlink($target_path);
            }else{
                //Assign a file name to the new picture
                srand(time());
                $newfilename = strval(rand()).".gif";
                //Display the image after secondary rendering (new image generated by the image uploaded by the user)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagegif($im,$img_path);

                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "Upload error!";
        }
    }else{
        $msg = "Only upload with suffix.jpg|.png|.gif My picture file!";
    }
}




Direct upload

Save as picture 22982 gif
Save the current picture and compare it with an open picture, and use winhex


You can see that the Trojan horse is gone
At this time, compare the unchanged places in front

It can be seen that many places in front are still the same. At this time, it can be seen in 22982 Gif front and BB Modify GIF in the same place and upload it

Upload the modified 22982 gif

Generate 24804 gif
Exploit File Inclusion Vulnerability for access

Code executed

Keywords: PHP security Web Security

Added by sasito on Fri, 18 Feb 2022 13:02:20 +0200