PortSwigger: Web shell upload via race condition (Easy Method)

Aaryan Golatkar
3 min readJun 30, 2023

--

Web shell upload via race condition

Hello, and welcome to this article on how to easily solve the Web shell upload via race condition lab!

What Makes This Method Different?

We’ll execute this attack using the Normal Burp Intruder rather than the Turbo Intruder. It is helpful for individuals who don’t know how to operate the Turbo Intruder. This will make it much simpler for them to comprehend the attack!

What is a Race Condition?

You’ll need some familiarity with Operating Systems in order to comprehend what a race condition is. I advise you to watch the video down below to clearly understand how this vulnerability manifests itself:

Race Condition Vulnerability Explanation

Now that you know what a Race Condition is, let’s get to the fun part!

Attack Explanation

Let’s look at the Hint. We can see that there is PHP code there. What is the vulnerability here?

<?php
$target_dir = "avatars/";
$target_file = $target_dir . $_FILES["avatar"]["name"];

// temporary move
move_uploaded_file($_FILES["avatar"]["tmp_name"], $target_file);

if (checkViruses($target_file) && checkFileType($target_file)) {
echo "The file ". htmlspecialchars( $target_file). " has been uploaded.";
} else {
unlink($target_file);
echo "Sorry, there was an error uploading your file.";
http_response_code(403);
}

function checkViruses($fileName) {
// checking for viruses
...
}

function checkFileType($fileName) {
$imageFileType = strtolower(pathinfo($fileName,PATHINFO_EXTENSION));
if($imageFileType != "jpg" && $imageFileType != "png") {
echo "Sorry, only JPG & PNG files are allowed\n";
return false;
} else {
return true;
}
}
?>

Instead of checking the file directly, it is temporarily moved to a directory before the FileType & Virus check is run. This shows that, before being examined, the file is only momentarily uploaded to the server. This gives us a window of time before the checks are made to execute the file.

Exploitation

Step 1: Create a PHP Web Shell that reads the “secret” file’s contents.

<?php echo file_get_contents('/home/carlos/secret'); ?>
// Filename: shell.php

Step 2: Intercept the POST File Upload Request and send it to the Intruder

POST Request (File Upload)

Step 3: Intercept the GET Request for the “shell.php” file

Assuming you’ve solved the previous labs of this Topic, you already know the location where the file is being stored on the server.

GET Request (shell.php)

Step 4: Make the following configurations in both Requests

Attack Type: Sniper

Payload Type: Null Payloads (We simply want to send the requests as-is without any modifications)

Payload Settings: Continue indefinitely

Payload Encoding: Uncheck 🔲 the box next to URL-encode these characters

Step 5: Start Both the Requests Simultaneously

Check the Response Tab by clicking on any Request in the GET Request attack. The “secret” file’s contents are available to you.

Response of GET Request

Submit this & Voilà!

Lab Completed!

--

--

Aaryan Golatkar

Cyber Security Enthusiast who has recently cracked the OSCP!