Today we learn from StandardUser Security Engineer Anthony Cruz, who says, "In truth, I didn’t just stumble across this challenge entirely. I am fascinated when it comes to offensive security. My curiosity was sparked by using computers in my youth without understanding their inner workings. At the age of 18, I wanted to fill this gap in my knowledge and found a wonderful ever expanding career path alongside with it.
In the following Capture the Flag provided by Proving Ground Practice (BackupBuddy), vulnerabilities such as “Directory Traversal” and “Shared Library Hijacking” were leveraged to gain initial access, privilege escalation, and both the local and root flags on this device.
Photo by Sergei Starostin
Enumeration
Service scan
Portscan
The scans reveal that only ports 80 (Apache) and 22 (SSH) are open.
Gobuster Scan
Gobuster scan results
Using Gobuster, we find 3 directories on the Apache server; however, only 2 are available to our local machine.
The 'files' directory seems to be hosting files that are uploaded via the 'filemanager.php' application that the web server is hosting, but I could not use directory traversal or upload a web shell.
The 'readme' directory is rather useful and reveals that the default username and password for the php file manager is 'fm_admin'.
/readme credentials
Successful Login
/backup/important_images directory
Upon further inspection, it seems the upload function isn't present for our current user (Brian). Interestingly enough, however, when we traverse to the '/backup/important_images' directory, the '/' character is url encoded (%2F) by the ‘p’ (path) parameter. Knowing this, we can potentially leverage a directory traversal attack by url encoding the '.' character to its corresponding value (%2E).
Since we are likely in the '/var/www/html/files' directory, we traverse 4 directories from the assumed root directory of the file server.
Successful directory traversal
Initial Access
The ‘/etc/shadow’ file was not readable; however, Brian’s SSH keys were readable and available to download via the PHP file manager.
Upon trying to use Brian's SSH key to authenticate, the password for his key is prompted.
Key password prompt
Using 'ssh2john' we can convert the key to a hash and attempt to brute-force the SSH keys password using 'JohnTheRipper' and the 'rockyou.txt' password list.
Cracking Brian’s SSH key password
It worked! Now we login to Brian's account using SSH key and the password 'eugene' and collect our first flag.
Local flag
Privilege Escalation:
After some manual enumeration, it seemed that Brian is only in the (var-www) group and seemingly had no sudo privileges. Additionally, Brian could not write to any useful files that had root permissions. Next, while checking for SUID binaries, I found nothing usable on GTFObins, but there was an interesting file in the '/opt' directory named 'backup'.
Backup file Discovery
/opt/backup permissions
The 'backup' file is a linux elf file which is set to execute as the root user and group, and Brian has execute permissions. Time for strings and some unnecessary Ghidra!
Strings command output
Ghidra decompiler
After some research into the above functions, it looks like the file opens a shared object (.so) file in the '/home/brian/.config/libm.so' directory (which does not exist) and then loads it into memory, retrieving its functions. If this fails, we get an error message. If the file successfully links, however, we get the 'Backup successful' message
Using the privesc cheat sheet on github below, I ran a simple C script in the LD_PRELOAD section and altered the script to only run bash as root. With the hopes that the backup file will load our malicious ‘.so’ file and execute the code within it:
Shortened C Script
Troubleshooting the Exploit:
Two things about this exploit were discovered through research. The first was that the exploit was missing the <unistd.h> header file necessary for the ‘setresuid’ function. The other issue was that the 'setresuid' function was seemingly not available on the machine, but the 'setreuid' function was suggested when trying to compile the link file.
The function takes two arguments, the 'real user id' (RUID) and the 'effective user id' (EUID). Knowing this, I set them both to root (0) to see if gcc is able to compile the malicious shared object link file.
Unaltered exploit
Successful compile of malicious .so file
Next, I ran the backup binary to see if I could run bash as root via the malicious shared object link file.
Root flag
Got root and the second flag!
Lessons Learned:
When I attempted this CTF, saying it was outside of my comfort zone would be quite the understatement. I took several breaks, had a few sleepless nights or so, and had to change my approach several times. Not to mention there were no hints or community forums discussing this box specifically. So, I offer not technical advice, but rather mental advice. I urge readers to STAY DETERMINED. There were definitely times I felt out of my bounds or “inadequate” for the task at hand, but despite the outcome of a single attempt I learned something each and every time. As a result, I eventually beat a challenge that I once thought too difficult for myself. I would like to challenge readers to stay determined, take breaks when you need them, and get those root flags!
Comments