Add writeup for HackTheBox "Instant" machine

This commit is contained in:
raul 2024-10-20 20:01:21 +02:00
parent 995eed3b5b
commit 8260d46043
20 changed files with 222 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 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: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,111 @@
+++
draft = false
date = 2024-10-20T09:50:54+02:00
title = "HackTheBox Instant Writeup"
description = "A walkthrough for the HTB \"Instant\" machine"
slug = ""
authors = ["Raul Bulgariu Suciu"]
tags = ["Tutorial", "Hacking", "HTB"]
categories = []
externalLink = ""
series = []
+++
{{<betterfigure src="files/title.png" alt="Title card">}}
Greetings, and welcome to my second HackTheBox writeup. Today I'll be guiding you through the machine "Instant" from HTB.
# Basic reconnaissance
Running a basic Nmap scan will show us that there are only two ports open, HTTP and SSH, so that immediately tells us that we'll have to attack the available website.
{{<betterfigure src="files/scan.png" alt="Nmap scan">}}
Once scanned, we can go ahead and associate the machine's domain name to its IP.
{{<betterfigure src="files/hosts.png" alt="Hosts file">}}
# Gaining a foothold
The first thing you'll notice about the website is that it offers a multi-purpose banking application in the form of an APK, since this seems like a completely static site, we'll download the APK.
{{<betterfigure src="files/apk.png" alt="APK Download">}}
## Decompiling the APK
While you might be tempted to try installing the APK to your mobile phone, you won't get much out of it.
What we'd like to know is how this application communicates with the backend server since we don't have any info on this machine beyond its static website, and for that we'll use the tool ***apktool***.
{{<betterfigure src="files/decomp.png" alt="Decompiled APK">}}
After decompiling, you'll notice that there are a lot of files, roughly around 8200 different ones, so how can we go about trying to find any useful information?
As I stated earlier, we want to know how this application interacts with the backend server of the machine, so naturally we'd assume that the domain name must have been hardcoded somewhere in the source code in order to make any API calls.
{{<betterfigure src="files/grepscreen.png" alt="Grepping for domains">}}
Using Grep, we instantly find find several lines of code detailing two subdomains of the machine: *"swagger-ui"* and *"mywalletv1"*, with the latter clearly being the address for making API calls.
However, the most interesting one is "swagger-ui", as this is a popular program used for creating ***API documentation***.
{{<betterfigure src="files/swagtee.png" alt="Adding swagger-ui to /etc/hosts">}}
{{<betterfigure src="files/swaggerui.png" alt="swagger-ui dashboard">}}
## What the heck is a "JWT"?
We're getting somewhere, the API documentation site even lets you make API requests from the comfort of your browser by letting you edit the json body of each request.
Nonetheless, as you'll notice, there's not much you can do as an unauthenticated user, which requires you to create an account and log in, logging in will give you a **"JWT"** token.
{{<betterfigure src="files/jwt.png" alt="Login token">}}
> JWT tokens are base64-encoded json strings composed of a header, body and tail separated by a ".", with the header detailing encryption methods, the body containing the information about the user logging in, and the tail being a cryptographic signature of both header and body combined.
> ***You'll find out why this is important later.***
{{<betterfigure src="files/jwtdecoded.png" alt="Login token decoded">}}
Once obtained, we can finally add our login token to the Authorization header within the API documentation website and realize that we can... not do a whole lot actually.
As you'll realize, all of the administrative API calls are forbidden to regular users like us *(and there don't seem to be any misconfigured/exploitable API calls available to us either)*, but as you'll remember, JWT tokens seem to share a common header for handling encryption methods.
So, what if we try searching for one of those headers in the decompiled APK codebase?
## The Rabbit R1 called, it wants its hardcoded API key back
{{<betterfigure src="files/jwtadmin.png" alt="Hardcoded admin JWT token">}}
Bingo, if we try this JWT key we'll be able to test that it is indeed functional and we now have access to all the administrative API calls. But how can we use this to gain a foothold within the machine?
You may have noticed two of the special API calls revolving around logging. If we try showing the available logs we'll see the following:
{{<betterfigure src="files/availablelogs.png" alt="Available logs">}}
The first thing you'll most likely notice is the directory where the logs are located, right within a /home user folder called "shirohige", and while at the same time letting us give input on which file we'd like to consult, *take a wild guess at how we can exploit this*.
{{<betterfigure src="files/LFI.png" alt="LFI">}}
If you guessed Local File Inclusion *(or LFI)* via the "log_file_name" parameter then you were right! But as you'll notice, we can only consult existing files without being able to check the contents of directories, so trying to navigate the filesystem to find any credentials is not gonna be an easy task.
***Or is it?***
As I mentioned, the first thing you probably noticed about the available log commands was the fact that they were located within the user's home folder, which means that we have read access to the contents of this directory. ***And what kind of credentials can we find within a user's home folder?***
{{<betterfigure src="files/idrsa.png" alt="Private SSH key">}}
After sanitizing the private key into a usable SSH format, we can then log in to the "shirohige" user of the machine and recover the user.txt flag!
{{<betterfigure src="files/usertxt.png" alt="user.txt">}}
# Escalating privileges
Once inside, you'll notice that there's not much we can do as this user either, since we logged in using the SSH key, we don't have access to the password necessary to execute something like `sudo -l` for example.
After navigating the filesystem for a while, you may come across the contents of the /opt folder and its "sessions-backup.dat" file.
{{<betterfigure src="files/opt.png" alt="/opt contents">}}
After researching for a bit, you'll learn that this is a file containing critical data about an SSH session in the "Solar-PuTTY" program. After doing a bit of digging, you'll be able to find a repo like [this one](https://github.com/RainbowCache/solar_putty_crack) that can help you crack the session file open.
Once you download the Solar-PuTTY session-cracking tool of your choice, exfiltrate the "sessions-backup.dat" file via whatever means you consider convenient, and supply the tool with our good old rockyou.txt wordlist.
{{<betterfigure src="files/cracked.png" alt="Cracked session password">}}
As you can see here, we have plaintext access to the root password of the machine, so now we can go back to our SSH session as "shirohige", execute `su -` and use try the password we found in the Solar-PuTTY session:
{{<betterfigure src="files/roottxt.png" alt="Root flag">}}
And there you go! You have now completed the HackTheBox "Instant" machine.

View File

@ -0,0 +1,111 @@
+++
draft = false
date = 2024-10-20T09:50:54+02:00
title = "Guía de Instant en HackTheBox"
description = "Un tutorial para la máquina HTB \"Instant\""
slug = ""
authors = ["Raul Bulgariu Suciu"]
tags = ["Tutorial", "Hacking", "HTB"]
categories = []
externalLink = ""
series = []
+++
{{<betterfigure src="files/title.png" alt="Title card">}}
Saludos, y bienvenidos a mi segunda guía de HackTheBox. Hoy os estaré guiando a través de la máquina "Instant" de HTB.
# Reconocimiento básico
Ejecutar un escaneo básico de Nmap nos mostrará que solo hay dos puertos abiertos, HTTP y SSH, por lo que inmediatamente nos indica que tendremos que atacar el sitio web disponible.
{{<betterfigure src="files/scan.png" alt="Nmap scan">}}
Una vez escaneado, podemos seguir adelante y asociar el nombre de dominio de la máquina a su IP.
{{<betterfigure src="files/hosts.png" alt="Hosts file">}}
# Ganando un punto de apoyo
Lo primero que notarás de la web es que ofrece una aplicación bancaria polivalente en forma de APK, ya que parece un sitio completamente estático, descargaremos el APK.
{{<betterfigure src="files/apk.png" alt="APK Download">}}
## Descompilando el APK
Si bien es posible que tengáis la tentación de intentar instalar el APK en vuestro teléfono móvil, no sacaréis mucho de ello.
Lo que nos gustaría saber es cómo se comunica esta aplicación con el servidor backend, ya que no tenemos nada de información sobre esta máquina más allá de su sitio web estático, y para ello utilizaremos la herramienta ***apktool***.
{{<betterfigure src="files/decomp.png" alt="Decompiled APK">}}
Después de descompilar, veréis que hay una gran cantidad de archivos, aproximadamente alrededor de 8200 diferentes, entonces, ¿cómo podemos tratar de encontrar información útil?
Como dije anteriormente, queremos saber cómo interactúa esta aplicación con el servidor backend de la máquina, por lo que, naturalmente, asumiríamos que el nombre de dominio debe haber sido codificado en algún lugar del código fuente para realizar cualquier llamada a la API.
{{<betterfigure src="files/grepscreen.png" alt="Grepping for domains">}}
Usando Grep, encontramos instantáneamente varias líneas de código que detallan dos subdominios de la máquina: *"swagger-ui"* y *"mywalletv1"*, siendo este último claramente la dirección para realizar llamadas a la API.
Sin embargo, el más interesante es "swagger-ui", ya que este es un programa popular utilizado para crear ***documentación de API***.
{{<betterfigure src="files/swagtee.png" alt="Adding swagger-ui to /etc/hosts">}}
{{<betterfigure src="files/swaggerui.png" alt="swagger-ui dashboard">}}
## ¿Qué diablos es un "JWT"?
Estamos llegando a alguna parte, el sitio de documentación de la API incluso nos permite realizar peticiones de API desde la comodidad de nuestro navegador al permitirnos editar el cuerpo json de cada petición.
No obstante, como podréis ver, no hay mucho que se pueda hacer como usuario no autenticado, lo que requiere que creemos una cuenta e iniciemos sesión, iniciar sesión nos dará un token **"JWT"**.
{{<betterfigure src="files/jwt.png" alt="Login token">}}
> Los tokens JWT son cadenas json codificadas en base64 compuestas por un encabezado, un cuerpo y una cola separados por un ".", con el encabezado detallando los métodos de cifrado, el cuerpo que contiene la información sobre el usuario que inicia sesión y la cola es una firma criptográfica de tanto el encabezado como el cuerpo combinados.
> ***Ya veréis por qué esto es importante más adelante.***
{{<betterfigure src="files/jwtdecoded.png" alt="Login token decoded">}}
Una vez obtenido, finalmente podemos agregar nuestro token de inicio de sesión a la cabecera de autorización dentro del sitio web de documentación de la API y darnos cuenta de que podemos... En realidad, no hacer mucho.
Como te daréis cuenta, todas las llamadas a la API administrativa están prohibidas para los usuarios habituales como nosotros *(y tampoco parece haber ninguna llamada a la API mal configurada/explotable disponible)*, pero como recordaréis, los tokens JWT parecen compartir un encabezado común para manejar los métodos de cifrado.
Entonces, ¿qué pasa si intentamos buscar uno de esos encabezados en el código base APK descompilado?
## El Rabbit R1 acaba de llamar, quiere su llave API hardcodeada de vuelta
{{<betterfigure src="files/jwtadmin.png" alt="Hardcoded admin JWT token">}}
Bingo, si probamos esta clave JWT podremos comprobar que efectivamente funciona y ya tenemos acceso a todas las llamadas administrativas de la API. Pero, ¿cómo podemos usar esto para ganar un punto de apoyo dentro de la máquina?
Es posible que hayais visto dos de las llamadas especiales a la API que giran en torno a los logs. Si intentamos mostrar los logs disponibles veremos lo siguiente:
{{<betterfigure src="files/availablelogs.png" alt="Available logs">}}
Lo primero de lo que probablemente os daréis cuenta es el directorio donde se encuentran los logs, justo dentro de una carpeta de usuario /home llamada "shirohige", y mientras al mismo tiempo nos permite dar información sobre qué archivo nos gustaría consultar, *adivinad cómo podemos explotar esto*.
{{<betterfigure src="files/LFI.png" alt="LFI">}}
Si adivinasteis la inclusión de archivos locales *(o LFI)* a través del parámetro "log_file_name", ¡estabais en lo cierto! Pero como se puede ver, solo podemos consultar los archivos existentes sin poder verificar el contenido de los directorios, por lo que tratar de navegar por el sistema de archivos para encontrar cualquier credencial no va a ser una tarea fácil.
***¿O sí?***
Como mencioné, lo primero que de lo que probablemente os disteis cuenta sobre los comandos de registro disponibles fue el hecho de que estaban ubicados dentro de la carpeta de inicio del usuario, lo que significa que tenemos acceso de lectura al contenido de este directorio. ¿Y qué tipo de credenciales podemos encontrar dentro de la carpeta de inicio de un usuario?***
{{<betterfigure src="files/idrsa.png" alt="Private SSH key">}}
Después de limpiar la llave privada a un formato SSH utilizable, podemos iniciar sesión en el usuario "shirohige" de la máquina y recuperar la bandera user.txt!
{{<betterfigure src="files/usertxt.png" alt="user.txt">}}
# Escalada de privilegios
Una vez dentro, os daréis cuenta de que tampoco hay mucho que podamos hacer como este usuario, ya que al iniciar sesión con la llave SSH, no tenemos acceso a la contraseña necesaria para ejecutar algo como 'sudo -l' por ejemplo.
Después de navegar por el sistema de archivos durante un rato, es posible que os encontréis con el contenido de la carpeta /opt y su archivo "sessions-backup.dat".
{{<betterfigure src="files/opt.png" alt="/opt contents">}}
Después de investigar un poco, aprenderéis que este es un archivo que contiene datos críticos sobre una sesión SSH en el programa "Solar-PuTTY". Después de indagar un poco, podréis encontrar un repositorio como [este](https://github.com/RainbowCache/solar_putty_crack) que puede ayudaros a abrir el archivo de sesión.
Una vez descarguéis la herramienta de descifrado de sesiones Solar-PuTTY de vuestra elección, exfiltrad el archivo "sessions-backup.dat" a través de cualquier medio que consideréis conveniente y suministrad a la herramienta nuestra buena lista de contraseñas rockyou.txt.
{{<betterfigure src="files/cracked.png" alt="Cracked session password">}}
Como podéis ver aquí, tenemos acceso en texto plano a la contraseña de root de la máquina, por lo que ahora podemos volver a nuestra sesión SSH como "shirohige", ejecutar 'su -' y usar probar la contraseña que encontramos en la sesión de Solar-PuTTY:
{{<betterfigure src="files/roottxt.png" alt="Root flag">}}
¡Y ahí lo tenéis! Habéis completado la máquina HackTheBox "Instant".