In this post, we’ll be solving the PortSwigger lab: “Web shell upload via path traversal”.

To solve the lab, we need to upload a PHP file that reads and displays the contents of the /home/carlos/secret file. Since to demonstrate that we’ve completed the lab, we must submit the contents of this file.
Additionally, the server is configured to prevent the execution of user-supplied files, so we’ll need to bypass this defense.
In this case, the lab itself provides us with an account to log in, so let’s do that:


Once we’ve logged in, we’re presented with the account profile:

As we can see, we have an option to upload a file, specifically it appears to be for updating the profile avatar. Let’s try to take advantage of this option to upload the following PHP file:

First, let’s prepare Burp Suite to intercept the request:


Once we have Burp Suite ready along with the proxy, we select the file and click “Upload”:



Here Burp Suite will intercept the file upload request:

With this request, let’s go to the “Decoder” tab in Burp Suite and URL encode the following:

../readSecret
We URL encode this because it’s the name we’re going to give to the file we’re uploading, we’ll change the name in the request itself. It’s encoded so that the dot and slash symbols aren’t removed or misinterpreted by the server.
By uploading a file with this name, depending on how the server handles it, we might be able to store it one directory back from where it should be, and thus bypass the restriction that indicates the server won’t execute user-supplied files. This technique of using dots and slashes is called Path Traversal.
That said, let’s pass the request to the repeater with Ctrl R, change the name, and send the request:

According to the response, the file has been successfully uploaded with the name ../readSecret.php. Let’s view this response in the browser. To do this, right-click on the response, click on the “Show response in browser” option, and copy the generated link:


Once we get here, we can now disable Burp Suite, as we won’t be using it anymore.

With this, we return to our profile.

Now, if we look at the profile, we can see that the avatar has changed and is now showing an error that the image isn’t loading properly:

By right-clicking on it, we can go directly to the image path to see if it’s our PHP file:


And indeed, the PHP file we uploaded has been stored as the avatar file, that’s why it wasn’t loading on the profile, it was trying to load an image when it wasn’t one. By visiting the PHP file, the code we placed has been interpreted, and we successfully read the secret file. In fact, we could also access the file at the following path:

It was uploaded one directory back from where it should be, which is why it’s interpreted and isn’t affected by the server restriction.
Having read this file, we simply submit the answer:


And this way, we complete the lab:

