๐ Submission
A detailed write-up of the Web challenge 'Submission' from x3CTF - 2025
๐ Challenge Overview
Category Details Additional Info ๐ Event x3CTF - 2025 Event Link ๐ฐ Category Web ๐ ๐ Points 500 Out of 500 total โญ Difficulty ๐ข Easy Personal Rating: 4/10 ๐ค Author rebane2001 Profile ๐ฎ Solves (At the time of flag submission) 16 XX% solve rate ๐ Date 24-01-2025 x3CTF - 2025 Day X ๐ฆพ Solved By xtea418 Team: QnQSec
๐ Challenge Information
Could you help us out?
๐ฏ Challenge Files & Infrastructure
Provided Files
Files:
๐ Initial Analysis
First Steps
Initially, the website appears as follows:
There is a file upload section where only
.txt
files can be uploaded. Reading the attached files, there was only a PHP file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
if (isset($_FILES['file'])) { $uploadOk = 1; $target_dir = "/var/www/html/uploads/"; $target_file = $target_dir . basename($_FILES["file"]["name"]); if (file_exists($target_file)) { ย echo "Sorry, file already exists."; ย $uploadOk = 0; } if ($_FILES["file"]["size"] > 50000) { ย echo "Sorry, your file is too large you need to buy Nitro."; ย $uploadOk = 0; } if (!str_ends_with($target_file, '.txt')) { ย echo "Due to exploit you can only upload files with .txt extensions sorry about this but we got hacked last time so we have to check this from now on."; ย $uploadOk = 0; } // Check if $uploadOk is set to 0 by an error if ($uploadOk == 0) { ย echo "Sorry, your file was not uploaded."; // if everything is ok, try to upload file } else { ย if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) { ย ย echo "The file ". htmlspecialchars( basename( $_FILES["file"]["name"])). " has been uploaded."; ย } else { ย ย echo "Sorry, there was an error uploading your file."; ย } } $old_path = getcwd(); chdir($target_dir); // make unreadable shell_exec('chmod 000 *'); chdir($old_path); }
As we can see, the files are uploaded to the
/uploads
folder, followed by various checks, including one on the file size and another on the extension, which must always end with.txt
. Initially, I thought of uploading a malicious PHP file to readflag.txt
, which was located under theuploads
folder, since trying to access/uploads/flag.txt
returned403 Forbidden
. I attempted to bypass the extension check with a null byte, usingexploit.php%00.txt
, but it didnโt work. Searching online, I found another type of attack that allowed command execution through the.htaccess
file. Interestingly, when I tried uploading a file starting with.
, I was able to read it using the/uploads/filename
route (but I quickly realized why). As we can see, achmod 000 *
command is executed right after the upload, setting all permissions to null for every file in theuploads
folder. This was why accessing files through the browser returned403 Forbidden
. It is also the reason why I was able to read the files I uploaded with a.
at the beginning of the name. Thechmod ... *
command affects all visible files but doesnโt include hidden files (those starting with.
or special characters, such as-
). Since their permissions werenโt nullified, I could still access them. From there, I did some research to better understand howchmod
works and realized it was an issue of insecure file permissions. Now, let’s move on to the exploit.
๐ฌ Vulnerability Analysis
Potential Vulnerabilities
- Insecure File Permission
- Bash Glob Injection
๐ฏ Solution Path
Exploitation Steps
Initial setup
After doing some research, I discovered that there is a specific flag that can be used with the
chmod
command,--reference=filename file
, which allows you to set the permissions of the target file (passed as an argument) to match those of the reference file (like a copy-and-paste of permissions). So, I decided to exploit this flag, given thatchmod
was being applied to*
(a wildcard indicating “all”). By setting the permissions of all files in the folder, I thought of using this to my advantage.
Exploitation
The exploitation essentially relies on uploading a file named
--reference=foo.txt
, for example (since there is always an extension check):Once the upload is done,
chmod
is called, and all the permissions are set to null. However, the exploit doesn’t stop there. In fact, for the reference flag, you need to specify a file, as we mentioned,foo.txt
, so I uploaded that file as well:Once the file is uploaded,
chmod
will be executed on all the files, and as soon as it reaches the file--reference=foo.txt
, it will treat it as a flag in the execution of the command. This will set the permissions of all files in the folder to match those of thefoo.txt
file (which, being the last one uploaded, still has active read permissions becausechmod
hasnโt been executed on it yet). As a result, the read permission for theflag.txt
file will also be set, and by accessing the/uploads/flag.txt
route, I was able to read the flag.
Flag capture
๐ ๏ธ Exploitation Process
Approach
The exploit does exactly as described manually: it uses the
--reference
flag ofchmod
to apply the permissions of thefoo.txt
file to all the files, includingflag.txt
, and then retrieves the flag by accessing the/uploads/flag.txt
route.
๐ฉ Flag Capture
Flag
Proof of Execution
๐ง Tools Used
Tool Purpose Python Exploit
๐ก Key Learnings
New Knowledge
I learned that
chmod
ignores hidden files (those named with.something
or files starting with-
). I also learned that when the--reference=filename file
parameter is used, it sets the permissions of the target file to match those of the file specified as the reference.
Skills Improved
- Binary Exploitation
- Reverse Engineering
- Web Exploitation
- Cryptography
- Forensics
- OSINT
- Miscellaneous
๐ References & Resources
Learning Resources
๐ Final Statistics
Metric | Value | Notes |
---|---|---|
Time to Solve | 00:20 | From start to flag |
Global Ranking (At the time of flag submission) | 2/975 | Challenge ranking |
Points Earned | 500 | Team contribution |
Created: 24-01-2025 โข Last Modified: 24-01-2025 Author: mH4ck3r0n3 โข Team: QnQSec