We covered a basic example of bypassing file upload filters by changing the extension. We used Burp Suite to intercept the POST request and changed the extension to the desired one. The vulnerability was caused by the lack of input filters after the file has been uploaded. This was part of OverTheWire Natas Level 12 challenge.
Source Code Analysis
I analyzed the PHP code and found several functions: get random string
, make random path
, and make random path from file name
. The upload process was controlled by a form that accepted user input via a POST request. There was a hidden field for the maximum file size (1KB), and another hidden field controlled the filename, using the get random string
function to generate a 10-character random name for the uploaded file. The make random path
function constructed the file path, and the uploaded file was stored in the “upload” directory.
The key finding was that while there was a check for file size, there were no checks on the file extension after the initial form validation. The form initially expected a .gpg
extension.
Exploitation Strategy
The vulnerability lay in the fact that even though the form initially checked for a .gpg
extension, there were no subsequent checks after the file was passed for processing and storage. My plan was to upload a file with a .gpg
extension to satisfy the initial check, then intercept the request and change the extension to something executable (like .php
or .txt
for testing).
Demonstrating the Vulnerability
First, I uploaded a regular PNG file, and as expected, the system changed its extension to .gpg
. Next, I renamed a text file (test.txt
) to test.gpg
to bypass the initial form check. I then intercepted the request using Burp Suite. In the intercepted request, I changed the extension of the randomly generated filename from .gpg
back to .txt
. When I sent the modified request, the text file was successfully uploaded and rendered.
Getting a Shell
To get a shell, I prepared a simple one-liner PHP shell that allowed system commands to be executed via a CMD
GET parameter. I renamed this PHP shell file with a .jpg
extension. I then repeated the upload process: I selected the .jpg
(which was actually PHP) file for upload, intercepted the request, changed the extension of the randomly generated filename to .php
, and forwarded the request. The PHP file was successfully uploaded.
Executing Commands and Retrieving the Flag
I accessed the uploaded PHP shell in the browser and used the CMD
parameter to execute system commands. I ran the id
command to confirm command execution. My goal was to find the password for the user natas13
. I knew from previous challenges that the password files were in the /etc/natas_pass/
directory. I used the cat /etc/natas_pass/natas13
command to display the password.
Moving to the Next Level
I used the retrieved password to log in to level 13. I anticipate that the next challenge (level 13) will have stricter filters on file uploads. The presenter also mentioned having notes on bypassing file upload restrictions available for channel members.
Technical Commands
Here are the technical commands I saw being typed or mentioned in the terminal:
cat test
(Used to display the content of a local test file)id
(Executed via the web shell:[URL_TO_SHELL]?CMD=id
)ls /etc
(Executed via the web shell:[URL_TO_SHELL]?CMD=ls%20/etc
)ls /etc/natas_pass
(Executed via the web shell:[URL_TO_SHELL]?CMD=ls%20/etc/natas_pass
)cat /etc/natas_pass/natas13
(Executed via the web shell:[URL_TO_SHELL]?CMD=cat%20/etc/natas_pass/natas13
)