Add writeup for MonitorsThree (HackTheBox)

This commit is contained in:
raul 2024-11-04 22:01:01 +01:00
parent 1176578fb7
commit d2a2e5e600
40 changed files with 460 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,230 @@
+++
draft = false
date = 2024-11-04T10:57:43+01:00
title = "HackTheBox MonitorsThree Writeup"
description = "A walkthrough for the HTB \"MonitorsThree\" machine"
slug = ""
authors = ["Raul Bulgariu Suciu"]
tags = ["Tutorial", "Hacking", "HTB"]
categories = []
externalLink = ""
series = []
+++
{{<betterfigure src="files/title.png" alt="Title card">}}
Hello again, today we'll be tackling the HackTheBox "MonitorsThree" machine, let's get to it, shall we?
# Basic reconnaissance
Once again after scanning the box, we'll be met with the two classic HTTP and SSH ports, along with a websnp port that we cannot access.
{{<betterfigure src="files/scan.png" alt="Nmap scan">}}
Given that we don't have any other attack vectors beyond the web server, let's add as always the domain name to our /etc/hosts file.
{{<betterfigure src="files/hosts.png" alt="Hosts file">}}
# Gaining a foothold
Once in, we can find yet another generic corporate website, although this one has a login function which we could try to exploit, although we currently have no credentials to our name that we could try, so let's focus on something else for now.
{{<betterfigure src="files/web.png" alt="Website">}}
While enumerating subdomains we get a single hit for a subdomain called "cacti", so we can go ahead and also add it to our hosts file.
> When fuzzing subdomains with ffuf, remember to filter out false positives by checking the response size of the majority of subdomains and filtering them out with `-fs 13560` like in this case.
{{<betterfigure src="files/subscan.png" alt="Website">}}
> Totally unrelated but please whenever using any bruteforce fuzzing tool like ffuf remember to use a rate-limiting parameter like `-rate 100` to avoid overloading the machine, especially shared machines.
{{<betterfigure src="files/cactiweb.png" alt="Cacti website">}}
Once we add the subdomain, we can find a server for a program called "Cacti", lucky for us they went out of their way to tell us the version being currently used, [so after 5 seconds of search we find an RCE exploit for the vulnerable version!](https://github.com/5ma1l/CVE-2024-25641)
***One snag though***, the exploit requires authentication with the target server, and we still don't have any credentials that we could try.
Probably a good time to check out that login form from the initial page:
{{<betterfigure src="files/loginform.png" alt="Login form">}}
Considering the fact that this dynamic website seems to be self-programmed instead of using a regular CMS like Drupal/Wordpress, we can assume that there might be unsanitized SQL calls in the login form, so we send a POST request and capture it with Burpsuite.
{{<betterfigure src="files/loginformtest.png" alt="Login form injection attempt">}}
> While we could try to use SQLMap to automatically scan the login form, it's unreliable unless supplied with an ample amount of context, so it's better to manually test for SQL injections by adding special characters like `'` to the end of a parameter and see how the server reacts.
However, in this case it seems like the website didn't produce any abnormal behaviours, so the login form seems to be mostly safe, although there is still one remaining place we haven't tested.
# The forgotten password form? Really?
{{<betterfigure src="files/forgotten.png" alt="Forgotten password form">}}
While the login form might seem like the most obvious choice, any and all attacks are clearly failing so let's go ahead and try the password reset form.
{{<betterfigure src="files/forgottentest.png" alt="Password reset injection attempt">}}
We're getting somewhere, the `username` parameter for the password reset request is clearly vulnerable to SQL injection, and not only that, the server has just told us the name of the backend database system, "MariaDB".
## Time to find some credentials!
As I mentioned before, SQLMap is mostly unreliable without the context to remove a lot of unnecessary scanning, however we now have the context we were looking for:
{{<betterfigure src="files/requestfile.png" alt="Request file">}}
Right now we'll just add the original POST request to a text file and read it with SQLMap *(`-r reset_password.txt`)*, define `username` as the specific parameter to scan *(`-p username`)* and tell SQLMap to only run MariaDB queries, as the webserver had been so kind to us earlier as to tell us the name of the database backend *(`--dbms=mariadb`)*.
> The `--level 5` and `--risk 3` flags are used to tell SQLMap to be as noisy as it needs to be, in most real world scenarios a scan as noisy as that would result in your IP address being automatically blocked.
> As for the `--tables` flag, with it the tool will automatically show us all the available tables in the database if it manages to properly exploit it.
{{<betterfigure src="files/tablesfound.png" alt="The tables">}}
As you can see, SQLMap managed to succeed in exploiting the SQL injection vulnerability and showed us the available tables in the database, the most interesting of them all being the "users" table, so let's go ahead and dump its contents!
{{<betterfigure src="files/usertable.png" alt="The user table">}}
> Bear in mind that some of these screenshots are edited to reduce the amount of text output in the SQLMap commands being utilized for the sake of the tutorial.
As you can see, we just managed to find the hashed passwords for several users in the database, and if we try to analyze them in a website like [this](https://hashes.com/en/tools/hash_identifier) we'll find out that they are using the extremely insecure MD5 algorithm.
# Cracking open a hash
Naturally our first instinct will be to try cracking the MD5 hash for the admin account using John the Ripper, and for that we'll use the classic "rockyou.txt" wordlist.
{{<betterfigure src="files/crackedhash.png" alt="The cracked hash">}}
As expected, we'll immediately gain access to the admin password. We could try to log in to the main page, but do you remember that one exploitable subdomain we needed credentials for?
{{<betterfigure src="files/cactilogin.png" alt="Cacti web page">}}
And bingo! These credentials are valid for the exploitable subdomain, which means we can now try using the exploit we had found so long ago.
# Reaching the user flag
{{<betterfigure src="files/revshell.png" alt="Exploit">}}
> Remember to modify the `./php/monkey.php` file with your own IP and listen port before executing the exploit.
As you can see, the reverse shell worked and we now have remote access to the machine. Now we can begin scouting out the machine for any possible attack vectors, preferably ones that could let us access the "marcus" user inside the /home folder.
One common place to look for vectors is usually in the root of the webserver, as usually it's possible to find things like configuration files with database passwords, and as you can see here, we managed to find a file containing exactly that!
{{<betterfigure src="files/dbconfig.png" alt="DB Configuration">}}
We immediately get to work on accessing the database, as this seems to be a completely different one from the one we managed to exploit earlier.
{{<betterfigure src="files/accessdb.png" alt="Accessing the DB">}}
The first table that catches our attention is "user_auth", and as you'll be able to see, we find the credentials for the Cacti users, including two credentials belonging to a single person both for the administrator account we used to execute the exploit and a personal account for the user "marcus", just the user we were trying to access earlier!
> By the way if you hadn't noticed by now, not only is Password-Based authentication disabled in the SSH server, but the credentials we first found to execute the exploit don't work when trying to `su -` into the "marcus" account, don't worry though, ***we'll correct that soon***.
{{<betterfigure src="files/userauth.png" alt="The Cacti user credentials">}}
We can now once again use John the Ripper with the "rockyou.txt" wordlist to crack it but not before checking what hashing algorithm is being used by the passwords, and [after consulting the website again](https://hashes.com/en/tools/hash_identifier), we'll find that it is using bcrypt, so we'll adjust John for it:
{{<betterfigure src="files/crackedmarcus.png" alt="Marcus' password">}}
With the hash now cracked, we can go ahead and try to `su -` our way into marcus' account.
{{<betterfigure src="files/su.png" alt="Access granted">}}
Success! With this we managed to reach MonitorsThree's user flag!
# Escalating our privileges
Before trying anything, we should probably find some way to properly access the marcus user without having to rely on a flimsy reverse shell, since the machine only allows pubkey based authentication, it makes sense that we'd look for private SSH keys within the user's home directory:
{{<betterfigure src="files/id_rsa.png" alt="Access granted">}}
> ***Tip:***
> You can use netcat to easily exfiltrate files from a Linux machine without opening any ports that might confuse other players.
There you go, an infinitely more reliable shell, anyways, as you look for privilege escalation vectors, you may come across the currently open ports in the server, with one server on port 8200 of the loopback interface standing out in particular.
{{<betterfigure src="files/netstat.png" alt="Netstat">}}
Since we have proper SSH access, we can now use SSH forwarding to access the hidden service from our browser as follows.
{{<betterfigure src="files/forwarding.png" alt="Do people even read these?">}}
{{<betterfigure src="files/duplicati.png" alt="Duplicati login page">}}
For those who don't know, Duplicati is a popular software for performing backups, but for us it seems like a path to the root flag. However, none of the credentials we found earlier will work, so let's see if we can find any useful configuration files that might let us in:
{{<betterfigure src="files/sqlite.png" alt="Found sqlite file">}}
You may have probably come across the /opt folder's contents, and you may also be tempted to go straight for the backups folder but you'll quickly realize that it's only backups for the Cacti service's files which we have already completely compromised.
What *we're interested in* is the Duplicati configuration file, since as you can see, we find a `server-passphrase` and a `server-passphrase-salt` variables, however, you'll also quickly realize that none of these values actually work when you try to log in to the Duplicati page.
***So, what do we do now?***
## The most convoluted exploit known to man
Naturally the best course of action would be to search for ways to bypass Duplicati's authentication process using only its `server-passphrase`, and that will immediately yield you with a link to [this Github issue in the Duplicati repo](https://github.com/duplicati/duplicati/issues/5197).
Basically, these two variables (saltedpwd and noncedpwd) you can find here when inspecting the login page's Javascript dictate the hashing of the combination of the "nonce" token generated for every login request and the inputted password plus the salt we found earlier in the configuration file.
> A "nonce" is an arbitrary token that can be used just once in a cryptographic communication to prevent replay attacks.
{{<betterfigure src="files/inspect.png" alt="Javascript variables">}}
The way we're supposed to exploit it is by converting the `server-passphrase` variable we found earlier from Base64 to Hexadecimal with a tool like [CyberChef](https://cyberchef.org/) and then manually setting the `saltedpwd` variable to the resulting value.
After this, we fire up Burpsuite again and tell it to intercept a login request, but instead of immediately sending it to the Repeater, we tell it to also intercept the response to the request as follows:
{{<betterfigure src="files/intercept.png" alt="Intercept the response">}}
Now we can forward the request, except this time we'll also be able to intercept the response and check its contents:
{{<betterfigure src="files/nonce.png" alt="The nonce">}}
As you can see here, not only we receive the single-use nonce token, but we also see the same salting passphrase we found in the .sqlite config file for Duplicati.
Now, while the page is still frozen from our intercepted request, we're supposed to open the console, and paste the following code *(and also remember to modify it please)*:
```js
var saltedpwd = 'HexOutputFromCyberChef';
var noncedpwd = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse('NonceFromBurp') + saltedpwd)).toString(CryptoJS.enc.Base64);
console.log(noncedpwd);
```
Then you must replace the contents of `saltedpwd` with the hexadecimal `server-passphrase` variable we converted earlier and `NonceFromBurp` with the Nonce value we received after intercepting the response from the server.
Once properly edited, you can execute the copied commands and `console.log(noncedpwd)` will print the calculated hash.
{{<betterfigure src="files/javascript.png" alt="Javascript variables">}}
Now we're supposed to forward the request we intercepted and then we'll intercept our own POST request including the hashed password the page generated for us, now we're supposed to replace the contents of the `password` parameter with the hash `console.log(noncedpwd)` printed out earlier:
{{<betterfigure src="files/modifiedpass.png" alt="Modified password">}}
> Remember to use `Ctrl+U` in Burpsuite to URL-Encode the new hashed password
Now if you forward this request, you'll find that the page allowed you to log in regardless of whichever password you used!
{{<betterfigure src="files/duplicatipage.png" alt="Duplicati main webpage">}}
# Capturing the root flag
Once here, we'll be able to see that Duplicati has an already configured backup setting for the Cacti server files as we had spoken about before, but what we'd like is some way to access the root.txt flag in the machine.
One way we could try is by editing the pre-existing backup configuration!
{{<betterfigure src="files/sources.png" alt="Duplicati sources">}}
> Any perspicacious hackers might have already noticed that Duplicati was being ran on a Docker container, which explains the `/source` folder preceding any file path within the target machine.
Right now we can go ahead and add the root.txt file within `/sources/root` to the list of files being backed up.
{{<betterfigure src="files/sourcesroot.png" alt="Duplicati sources">}}
After saving the new settings, we can manually run the backup configuration from the main page and head into the "Restore" section, where we can choose to individually restore the root.txt file our manual backup managed to copy:
{{<betterfigure src="files/restore.png" alt="Duplicati restoration">}}
We can now choose where we'll store the flag, for now let's create a temporary folder in `/sources/tmp/` with full write permissions for everyone (`chmod 777 /tmp/.topsecret`):
{{<betterfigure src="files/restoreto.png" alt="Duplicati restoration">}}
And once the restoration process is executed, we can head over to our temporary folder and we'll be able to find the root.txt file waiting for us, marking the end of the "MonitorsThree" box.
{{<betterfigure src="files/rootflag.png" alt="Root flag">}}

View File

@ -0,0 +1,230 @@
+++
draft = false
date = 2024-11-04T10:57:43+01:00
title = "Guía de MonitorsThree en HackTheBox"
description = "Un tutorial para la máquina HTB \"MonitorsThree\""
slug = ""
authors = ["Raul Bulgariu Suciu"]
tags = ["Tutorial", "Hacking", "HTB"]
categories = []
externalLink = ""
series = []
+++
{{<betterfigure src="files/title.png" alt="Title card">}}
Hola de nuevo, hoy nos ocuparemos de la máquina HackTheBox "MonitorsThree", vamos a ello, ¿de acuerdo?
# Reconocimiento básico
Una vez más, después de escanear la máquina, nos encontraremos con los dos puertos HTTP y SSH clásicos, junto con un puerto websnp al que no podemos acceder.
{{<betterfigure src="files/scan.png" alt="Nmap scan">}}
Dado que no tenemos ningún otro vector de ataque más allá del servidor web, agreguemos como siempre el nombre de dominio a nuestro archivo /etc/hosts.
{{<betterfigure src="files/hosts.png" alt="Hosts file">}}
# Ganando un punto de apoyo
Una vez dentro, podemos encontrar otra web corporativa genérica, aunque esta tiene una función de inicio de sesión que podríamos intentar explotar, aunque actualmente no tenemos credenciales a nuestro nombre que podamos probar, así que centrémonos en algo diferente por ahora.
{{<betterfigure src="files/web.png" alt="Website">}}
Al enumerar subdominios, obtenemos un solo resultado para un subdominio llamado "cacti", por lo que podemos seguir adelante y también agregarlo a nuestro archivo hosts.
> Al hacer fuzzing de subdominios con ffuf, recordad filtrar los falsos positivos comprobando el tamaño de respuesta de la mayoría de los subdominios y filtrándolos con `-fs 13560` como en este caso.
{{<betterfigure src="files/subscan.png" alt="Website">}}
> Totalmente no relacionado, pero por favor, siempre que utiliceis cualquier herramienta de fuzzing por fuerza bruta como ffuf, recordad usar un parámetro de limitación de velocidad como `-rate 100` para evitar sobrecargar la máquina, especialmente las máquinas compartidas.
{{<betterfigure src="files/cactiweb.png" alt="Cacti website">}}
Una vez que añadimos el subdominio, podemos encontrar un servidor para un programa llamado "Cacti", por suerte para nosotros hicieron todo lo posible para decirnos la versión que se está utilizando actualmente, [así que después de 5 segundos de búsqueda encontramos un exploit RCE para la versión vulnerable!](https://github.com/5ma1l/CVE-2024-25641)
***Sin embargo, un inconveniente***, el exploit requiere autenticación con el servidor de destino, y todavía no tenemos ninguna credencial que podamos probar.
Probablemente sea un buen momento para revisar ese formulario de inicio de sesión de la página inicial:
{{<betterfigure src="files/loginform.png" alt="Login form">}}
Teniendo en cuenta el hecho de que este sitio web dinámico parece estar autoprogramado en lugar de usar un CMS regular como Drupal/Wordpress, podemos suponer que puede haber llamadas SQL no desinfectadas en el formulario de inicio de sesión, por lo que enviamos una solicitud POST y la capturamos con Burpsuite.
{{<betterfigure src="files/loginformtest.png" alt="Login form injection attempt">}}
> Si bien podríamos intentar usar SQLMap para escanear automáticamente el formulario de inicio de sesión, no es confiable a menos que se proporcione una gran cantidad de contexto, por lo que es mejor probar manualmente las inyecciones SQL agregando caracteres especiales como `'` al final de un parámetro y ver cómo reacciona el servidor.
Sin embargo, en este caso parece que el sitio web no produjo ningún comportamiento anormal, por lo que el formulario de inicio de sesión parece ser mayormente seguro, aunque todavía queda un lugar que no hemos probado.
# ¿El formulario de contraseña olvidada? ¿En serio?
{{<betterfigure src="files/forgotten.png" alt="Forgotten password form">}}
Si bien el formulario de inicio de sesión puede parecer la opción más obvia, todos y cada uno de los ataques están fallando claramente, así que sigamos adelante y probemos el formulario de restablecimiento de contraseña.
{{<betterfigure src="files/forgottentest.png" alt="Password reset injection attempt">}}
Estamos llegando a alguna parte, el parámetro `username` para la solicitud de restablecimiento de contraseña es claramente vulnerable a inyección SQL, y no solo eso, el servidor nos acaba de decir el nombre del sistema de base de datos backend, "MariaDB".
## ¡Hora de encontrar algunas credenciales!
Como mencioné antes, SQLMap es en su mayoría poco confiable sin el contexto para eliminar una gran cantidad de escaneo innecesario, sin embargo, ahora tenemos el contexto que estábamos buscando:
{{<betterfigure src="files/requestfile.png" alt="Request file">}}
Ahora, simplemente agregaremos la solicitud POST original a un archivo de texto y lo leeremos con SQLMap *(`-r reset_password.txt`)*, definiremos `username` como el parámetro específico para escanear *(`-p username`)* y le diremos a SQLMap que solo ejecute consultas MariaDB, ya que el servidor web había sido tan amable con nosotros anteriormente como para decirnos el nombre del backend de la base de datos *(`--dbms=mariadb`)*.
> Los parámetros `--level 5` y `--risk 3` se utilizan para indicar a SQLMap que sea tan ruidoso como necesite ser, en la mayoría de los escenarios del mundo real, un análisis tan ruidoso como ese resultaría en vuestra dirección IP siendo bloqueada automáticamente.
> En cuanto al parámetro `--tables`, con él, la herramienta nos mostrará automáticamente todas las tablas disponibles en la base de datos si consigue explotarla adecuadamente.
{{<betterfigure src="files/tablesfound.png" alt="The tables">}}
Como podéis ver, SQLMap logró explotar con éxito la vulnerabilidad de inyección SQL y nos mostró las tablas disponibles en la base de datos, siendo la más interesante de todas la tabla "users", ¡así que sigamos adelante y volquemos su contenido!
{{<betterfigure src="files/usertable.png" alt="The user table">}}
> Tened en cuenta que algunas de estas capturas de pantalla se editan para reducir la cantidad de salida de texto en los comandos SQLMap que se utilizan por el bien del tutorial.
Como podéis ver, acabamos de encontrar las contraseñas hasheadas de varios usuarios en la base de datos, y si intentamos analizarlas en un sitio web como [este](https://hashes.com/en/tools/hash_identifier) descubriremos que están utilizando el algoritmo extremadamente inseguro MD5.
# Descifrando un hash
Naturalmente, nuestro primer instinto será intentar descifrar el hash MD5 de la cuenta de administrador usando John the Ripper, y para eso usaremos la clásica lista de palabras "rockyou.txt".
{{<betterfigure src="files/crackedhash.png" alt="The cracked hash">}}
Como era de esperar, obtendremos acceso inmediato a la contraseña de administrador. Podríamos intentar iniciar sesión en la página principal, pero ¿recordáis ese subdominio explotable para el que necesitábamos credenciales?
{{<betterfigure src="files/cactilogin.png" alt="Cacti web page">}}
¡Y bingo! Estas credenciales son válidas para el subdominio explotable, lo que significa que ahora podemos intentar usar el exploit que habíamos encontrado hace tanto tiempo.
# Alcanzando la bandera de usuario
{{<betterfigure src="files/revshell.png" alt="Exploit">}}
> Recordad modificar el archivo `./php/monkey.php` con vuestra propia IP y puerto de escucha antes de ejecutar el exploit.
Como podéis ver, la shell inversa funcionó y ahora tenemos acceso remoto a la máquina. Ahora podemos comenzar a explorar la máquina en busca de posibles vectores de ataque, preferiblemente aquellos que nos permitan acceder al usuario "marcus" dentro de la carpeta /home.
Un lugar común para buscar vectores suele ser en la raíz del servidor web, ya que generalmente es posible encontrar cosas como archivos de configuración con contraseñas de bases de datos, y como podéis ver aquí, ¡logramos encontrar un archivo que contiene exactamente eso!
{{<betterfigure src="files/dbconfig.png" alt="DB Configuration">}}
Inmediatamente nos ponemos a trabajar en el acceso a la base de datos, ya que esta parece ser completamente diferente a la que logramos explotar anteriormente.
{{<betterfigure src="files/accessdb.png" alt="Accessing the DB">}}
La primera tabla que nos llama la atención es "user_auth", y como podréis ver, encontramos las credenciales de los usuarios de Cacti, incluyendo dos credenciales pertenecientes a una misma persona tanto para la cuenta de administrador que utilizamos para ejecutar el exploit como para una cuenta personal para el usuario "marcus", ¡justo el usuario al que intentábamos acceder anteriormente!
> Por cierto, si aún no lo habíais notado, no solo está deshabilitada la autenticación basada en contraseña en el servidor SSH, sino que también las credenciales que encontramos por primera vez para ejecutar el exploit no funcionan cuando intentamos meternos por `su -` a la cuenta "marcus", aunque no os preocupéis, ***corregiremos eso pronto***.
{{<betterfigure src="files/userauth.png" alt="The Cacti user credentials">}}
Ahora podemos volver a usar John the Ripper con la lista de palabras "rockyou.txt" para descifrarla, pero no sin antes comprobar qué algoritmo de hash están utilizando las contraseñas, y [después de consultar de nuevo el sitio web](https://hashes.com/en/tools/hash_identifier), descubrimos que está usando bcrypt, así que ajustaremos a John para ello:
{{<betterfigure src="files/crackedmarcus.png" alt="Marcus' password">}}
Con el hash ahora descifrado, podemos seguir adelante e intentar meternos por `su -` a la cuenta de marcus.
{{<betterfigure src="files/su.png" alt="Access granted">}}
¡Éxito! ¡Con esto logramos alcanzar la bandera de usuario de MonitorsThree!
# Escalando nuestros privilegios
Antes de intentar nada, probablemente deberíamos encontrar alguna manera de acceder correctamente al usuario marcus sin tener que depender de una shell inversa endeble, ya que la máquina solo permite la autenticación basada en llaves públicas, tiene sentido que busquemos claves SSH privadas dentro del directorio de inicio del usuario:
{{<betterfigure src="files/id_rsa.png" alt="Access granted">}}
> ***Consejo:***
> Podéis usar netcat para exfiltrar fácilmente archivos de una máquina Linux sin abrir ningún puerto que pueda confundir a otros jugadores.
Ahí lo tenéis, una shell infinitamente más confiable, de todos modos, a medida que buscamos vectores de escalada de privilegios, es posible que os encontréis con los puertos actualmente abiertos en el servidor, con un servidor en el puerto 8200 de la interfaz loopback que destaca en particular.
{{<betterfigure src="files/netstat.png" alt="Netstat">}}
Dado que tenemos un acceso SSH más adecuado, ahora podemos usar SSH forwarding para acceder al servicio oculto desde nuestro navegador de la siguiente manera.
{{<betterfigure src="files/forwarding.png" alt="Do people even read these?">}}
{{<betterfigure src="files/duplicati.png" alt="Duplicati login page">}}
Para aquellos que no lo saben, Duplicati es un software popular para realizar copias de seguridad, pero para nosotros parece un camino hacia la bandera root. Sin embargo, ninguna de las credenciales que encontramos anteriormente funcionarán, así que veamos si podemos encontrar algún archivo de configuración útil que nos permita entrar:
{{<betterfigure src="files/sqlite.png" alt="Found sqlite file">}}
Es probable que os hayáis encontrado con el contenido de la carpeta /opt, y también es posible que tengáis la tentación de ir directamente a la carpeta de copias de seguridad, pero rápidamente os daréis cuenta de que solo se tratan de copias de seguridad de los archivos del servicio Cacti que ya hemos comprometido por completo.
Lo que *nos interesa* es el archivo de configuración de Duplicati, ya que como podéis ver, encontramos una variable `server-passphrase` y una variable `server-passphrase-salt`, sin embargo, también os daréis cuenta rápidamente de que ninguno de estos valores funciona realmente cuando intentamos iniciar sesión en la página de Duplicati.
***Entonces, ¿qué hacemos ahora?***
## El exploit más enrevesado conocido por el hombre
Naturalmente, el mejor curso de acción sería buscar formas de eludir el proceso de autenticación de Duplicati utilizando solo su `server-passphrase`, y eso os proporcionará inmediatamente un enlace a [esta issue de Github en el repositorio de Duplicati](https://github.com/duplicati/duplicati/issues/5197).
Básicamente, estas dos variables (saltedpwd y noncedpwd) que podéis encontrar aquí al inspeccionar el Javascript de la página de inicio de sesión dictan el hash de la combinación del token "nonce" generado para cada solicitud de inicio de sesión y la contraseña ingresada más la salt que encontramos anteriormente en el archivo de configuración.
> Un "nonce" es un token arbitrario que se puede usar solo una vez en una comunicación criptográfica para evitar ataques de replay.
{{<betterfigure src="files/inspect.png" alt="Javascript variables">}}
La forma en que se supone que debemos explotarlo es convirtiendo la variable `server-passphrase` que encontramos anteriormente de Base64 a Hexadecimal con una herramienta como [CyberChef](https://cyberchef.org/) y luego configurando manualmente la variable `saltedpwd` en el valor resultante.
Después de esto, volvemos a encender Burpsuite y le decimos que intercepte una solicitud de inicio de sesión, pero en lugar de enviarla inmediatamente al repetidor, le decimos que también intercepte la respuesta a la solicitud de la siguiente manera:
{{<betterfigure src="files/intercept.png" alt="Intercept the response">}}
Ahora podemos reenviar la solicitud, solo que esta vez también podremos interceptar la respuesta y verificar su contenido:
{{<betterfigure src="files/nonce.png" alt="The nonce">}}
Como podéis ver aquí, no solo recibimos el token nonce de un solo uso, sino que también vemos la misma passphrase de salt que encontramos en el archivo de configuración .sqlite para Duplicati.
Ahora, mientras la página aún siga congelada por nuestra solicitud interceptada, se supone que debemos abrir la consola y pegar el siguiente código *(y también recordar modificarlo por favor)*:
```js
var saltedpwd = 'HexOutputFromCyberChef';
var noncedpwd = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse('NonceFromBurp') + saltedpwd)).toString(CryptoJS.enc.Base64);
console.log(noncedpwd);
```
A continuación, hay que reemplazar el contenido de `saltedpwd` por la variable hexadecimal `server-passphrase` que convertimos anteriormente y `NonceFromBurp` por el valor Nonce que recibimos después de interceptar la respuesta del servidor.
Una vez editado correctamente, podemos ejecutar los comandos copiados y `console.log(noncedpwd)` imprimirá el hash calculado.
{{<betterfigure src="files/javascript.png" alt="Javascript variables">}}
Ahora se supone que debemos reenviar la solicitud que interceptamos y luego interceptaremos nuestra propia solicitud POST que incluye la contraseña hash que la página generó para nosotros, ahora tenemos que debemos reemplazar el contenido del parámetro `password` con el hash que `console.log(noncedpwd)` imprimió anteriormente:
{{<betterfigure src="files/modifiedpass.png" alt="Modified password">}}
> Recordad usar `Ctrl+U` en Burpsuite para codificar en URL la nueva contraseña con hash
Ahora, si reenviáis esta solicitud, veréis que la página os permite iniciar sesión independientemente de la contraseña que se haya utilizado.
{{<betterfigure src="files/duplicatipage.png" alt="Duplicati main webpage">}}
# Capturando la bandera root
Una vez aquí, podremos ver que Duplicati ya tiene configurada una configuración de copia de seguridad para los archivos del servidor Cacti como habíamos hablado antes, pero lo que nos gustaría es alguna forma de acceder a la bandera root.txt en la máquina.
Una forma de intentarlo es editando la configuración de copia de seguridad preexistente.
{{<betterfigure src="files/sources.png" alt="Duplicati sources">}}
> Algunos hackers perspicaces podrían haberse dado cuenta de que Duplicati se estaba ejecutando en un contenedor Docker, lo que explica la carpeta `/source` que precede a cualquier ruta de archivo dentro de la máquina de destino.
Ahora podemos seguir adelante y agregar el archivo root.txt dentro de `/sources/root` a la lista de archivos de los que se está haciendo una copia de seguridad.
{{<betterfigure src="files/sourcesroot.png" alt="Duplicati sources">}}
Después de guardar la nueva configuración, podemos ejecutar manualmente la configuración de la copia de seguridad desde la página principal y dirigirnos a la sección "Restore", donde podemos elegir restaurar individualmente el archivo root.txt que nuestra copia de seguridad manual logró copiar:
{{<betterfigure src="files/restore.png" alt="Duplicati restoration">}}
Ahora podemos elegir dónde almacenaremos la bandera, por ahora vamos a crear una carpeta temporal en `/sources/tmp/` con permisos de escritura completos para todos (`chmod 777 /tmp/.topsecret`):
{{<betterfigure src="files/restoreto.png" alt="Duplicati restoration">}}
Y una vez ejecutado el proceso de restauración, podemos dirigirnos a nuestra carpeta temporal y podremos encontrar el archivo root.txt esperándonos, marcando el fin de la máquina "MonitorsThree".
{{<betterfigure src="files/rootflag.png" alt="Root flag">}}