This post will detail the steps I took to find a path traversal vulnerability, and how I paired the vulnerability with the logic of the application to achieve Remote Code Execution through a shell upload.
I found this while testing a mobile application that has a feature allowing users to upload and encrypt documents to a cloud server, then decrypt the files when the user wants to view their uploaded files. When uploading a file and intercepting the traffic in burpsuite, I saw that the server first checks if the file exists with a given image name.
Then after it verifies that the image does not already exist, the server then encrypts the file, and uploads it in the following request, changing the value of the “method” parameter to “writeFile”.
Then to read the file, the server just changes the method parameter to “readFile”, specifying the document’s name in the path parameter. The output is the content of the encrypted file.
Since I saw that I could read files using this request, I immediately tried to traverse the “path” parameter in order to read system files. This was the result of traversing for the etc/passwd file.
So now that I could read system files, I also noticed (but did not attempt) that I could also override these files just by changing the “method” parameter value to “writeFile”. I wanted to escalate this to remote code execution, so I tried uploading a php shell to the web root, in the /api/ directory with the following request:
As you can see, I’ve traversed the path to upload the shell “da.php” into the “/api/” directory, where the value of the “contents” parameter is the php shell code. Navigating the the url /api/da.php?cmd=id, you can see that the shell upload was successful, and outputs the results from executing the unix “id” command.
The mobile application is listed as in-scope for a private hackerone program, however after reporting this and waiting 3 weeks for a response, they told me that the mobile application itself is in-scope, but not the endpoints that the app communicates with, as it is hosted by the third party developer of the app. Even though it has an impact on all users that upload documents through their app, they still refused to take responsibility for it and changed the scope afterwards to reflect this. Overall a pretty disappointing experience, but still one I can learn from, and hopefully others can too.