Summary of file upload vulnerability comprehensive penetration posture

Summary of file upload vulnerability comprehensive penetration posture

Oriental Health Network https://www.9559.org/cn/

0x00 file upload scene

(This document is only for technical exchanges, do not conduct illegal or criminal operations, please be a good person and do not cause trouble to others)

File upload scenes can be seen everywhere, without precautions, it is easy to cause loopholes, information leakage, and even more serious disasters.

For example, in the comment editing module of a blog site, there is a function to upload pictures in the upper right corner. After submitting pictures with malicious strings, they can be directly displayed in the comments, as shown in the figure:

 

Once again: Everyone should test in the environment built by themselves, and don't cause trouble to others.

File upload vulnerability is a common and easy to exploit vulnerability for infiltration. Using it to directly upload webshell and connect is a relatively common attack method. A comprehensive posture summary is made for file upload scene detection and bypass.

0x01 Comprehensive analysis of penetration posture

For a file upload scenario, first determine whether it is client-side JS verification or server verification. The judgment basis: uploading an illegal file, is the return result fast?

1. Client-side JavaScript detection

If an illegal file is uploaded and the result is returned quickly, or F12 opens the developer mode and uploads an illegal file, and it is found that there is no network request, but it is intercepted, it is very likely that the client has performed a JS verification test. This front end uses JS to limit the upload type and size:

<script type="text/javascript">
     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 allowed file type 
        var allow_ext = ".jpg|.png|.gif" ;
         // Extract the uploaded file type 
        var ext_name = file.substring( file.lastIndexOf("." ));
         // Determine whether the upload file type is allowed to upload 
        if (allow_ext.indexOf(ext_name) == -1) {
             var errMsg = "The file is not allowed to be uploaded, please upload a file of type "+ allow_ext + ", the current file type is:" + ext_name; 
            alert(errMsg); 
            return  false ; 
        } 
    }
 </script>

Very tasteless, bypass the idea: 1. Directly disable JS locally, not let it do the detection 2. Capture the package, modify the file suffix type, and bypass the detection limit

2. Server back-end detection

There are many methods for server back-end detection, which are generally divided into file type detection, file header type, file extension list detection, file content detection, and then a brief analysis.

a. File type detection

This type of detection and protection is mainly from the content-type to check whether the content-type in the request meets the acceptable upload type (such as "image/gif", "image/png", "image/jpeg") 

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;     

Bypass the idea: change the content-type of the package to the acceptable image format, and then it can be bypassed

b. File header type detection 

The last file type is to detect the content-type, which is better for forgery, this is to use the getimagesize() function to get the MIME type of the file, and to judge the file type through the file header

 if(file_exists($filename)){
        $info = getimagesize($filename);

The file header is a file-specific mark, such as 4D5A for binary PE files, 424D for bmp files, and 504B0304 for zip files. You can find and understand the file header types of various common files. Common picture file headers are as follows:

gif: GIF89a

jpg,jpeg: FF D8 FF

png: 89 50 4E 47 0D 0A

Bypassing the idea: For this, when uploading a Trojan horse malicious file, first use an editing tool to add the header of the image at the top of the data to forge it, then you can bypass it

c. File extension detection

This type is based on blacklist detection and whitelist detection. Usually based on a blacklist is very insecure. The blacklist mechanism: only intercept the extension suffixes that appear in the list, and let the rest of them by default. This depends on the scope of the extended suffix coverage in the list. It is difficult to consider all of them, and it is easy to cause loopholes.

Blacklist bypass ideas: analysis can be performed from the parsing characteristics of the server, such as special parsable suffixes such as php3, php7, phtml, jspx, etc., such as special parsing methods, unfamiliar suffix names, newline suffix names, double suffix names, etc. Loopholes. You can also start from the confusion aspect, suffix name case, dot bypass, space bypass, and upload .htaccess configuration to control file permissions and the use of ::$DATA data stream

Based on the whitelist is much safer than the blacklist, it is required that only files with a specific extension can be uploaded.

Whitelist bypass ideas: MIME bypass, modify the file type to a whitelist acceptable type, and %00, 0x00 truncation bypass, this scenario is controllable for save_path.

The 00 truncation principle is actually very clever. The use scenario is that the file save path is controllable, so that the file we upload meets the whitelist. The real place to do it is in the file save path. You can put your own webshell file, and then put it in the webshell file. Add %00, or 0x00 at the end, and then add some characters. In this way, the system will be truncated when it encounters 00 in parsing, and the following characters will not work. Only the previous webshell file name is left, which can be accessed in the url. Up. The difference between %00 and 0x00 is that when submitting a get request, it is %00, which will automatically decode the URL, and then enter the verification function. 0x00 is the post request to enter the verification function directly.

d. File content detection

The more powerful protection detection is to check the content. This protection ability is relatively strong, but it is not impossible to bypass. From beginning to end, offense and defense have evolved spirally in confrontation.

This detection and protection are basically representative sensitive characters from webshell? or dangerous sensitive functions.

Bypass the idea: start the Fuzz test with special sensitive characters, and detect how many necessary characters in the webshell are replaced, if they constitute the characters executed by the webshell

Many are replaced, and the remaining unfiltered characters are difficult to support webshell execution. You can use the system from another angle to call the script language, such as <script language='php'>system('ls');<script>.

There is also a stronger content-based detection mechanism that performs secondary rendering on uploaded pictures. The reference code is as follows

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

            if ($im == false ){ 
                $msg = " The file is not a picture in jpg format! " ; 
                @unlink($target_path); 
            } else {
                 // Specify the file name for the new picture 
                srand(time()); 
                $newfilename= strval(rand()). " .jpg " ;
                 // Display the picture after the second rendering (using the new picture generated by the user uploaded picture) 
                $img_path = UPLOAD_PATH. ' / ' .$newfilename; 
                imagejpeg($im,$ img_path); 
                @unlink($target_path); 
                $is_upload = true ; 
            } 
        } else { 
            $msg = " Error uploading! " ; 
        }

The main reason is that the backend calls the GD library of php, uses the imagecreatefromjpeg() function to extract the image data in the file, and then re-renders it, so that the malicious code inserted in the image will be filtered out. After testing, it is found that whether it is directly Modifying the file header to make a picture horse, or using the copy command to make a picture horse, can’t prevent one sentence from being filtered out.

Bypassing the idea: Drawing on the idea of ​​hooks in binary, in fact, I want to find a "place" in the uploaded image to store the webshell. This "place" must not be filtered out after the back-end processing. Then upload a normal file, then download it, diff it to see which locations have not been changed, and then add a webshell to try.

0x02 Safety Thoughts

The above protection and bypass postures are basically summarized from business actual combat and CTF competitions. More often, various information is required for comprehensive utilization. Attacks and defenses in security are always achieved in confrontation. Revere the prior knowledge of the predecessors and show the exploration spirit of the younger generations.

Guess you like

Origin blog.csdn.net/nidongla/article/details/115213219