Bounty
Windows (IIS 7.5) en el que una subida de ficheros se convierte en ejecución de comandos subiendo un web.config que reconfigura la carpeta para ejecutar .config como ASP; de ahí shell como merlin, y con SeImpersonatePrivilege y JuicyPotato se salta a NT AUTHORITY\SYSTEM.
Bounty
| Máquina | SO | Dificultad | IP |
|---|---|---|---|
| Bounty | Windows | Easy | 10.129.89.135 |
A tener en cuenta...
Resumen
Bounty es un Windows antiguo con un único servicio: un servidor web IIS que deja subir ficheros. La vía de entrada no es un fallo del código de subida, sino una peculiaridad de IIS: una carpeta puede reconfigurarse a sí misma con un web.config, y eso permite hacer que ejecute como código lo que debería servir como texto.
Subiendo un web.config malicioso a la carpeta de subidas consigo ejecución de comandos, y de ahí una shell como merlin.
La escalada es la clásica de un servidor Windows viejo con SeImpersonatePrivilege: con JuicyPotato se abusa de la suplantación de tokens para saltar a NT AUTHORITY\SYSTEM.
No es tan directa como promete su dificultad — hay que encadenar varios pasos y pelearse con los detalles — pero cada pieza es un patrón que conviene tener muy visto.
Vulnerabilidad
Son dos piezas, una por cada mitad de la máquina.
01 · Subida de ficheros + ejecución vía web.config
La web deja subir ficheros y filtra por extensión, pero el filtro es débil y, sobre todo, no contempla lo importante: en IIS, el fichero web.config configura el comportamiento de la carpeta donde está. Si puedo dejar un web.config en la carpeta de subidas, puedo decirle a IIS que ejecute los ficheros .config de esa carpeta como código ASP clásico — y de paso quitar .config de la lista de extensiones bloqueadas. Es una técnica conocida: subir configuración es, en la práctica, subir código.
02 · SeImpersonatePrivilege (abuso de tokens)
La cuenta de servicio de IIS tiene habilitado SeImpersonatePrivilege, el permiso para suplantar a un cliente tras autenticarlo. En un Windows de esta época eso es una escalada directa: herramientas de la familia Potato (aquí JuicyPotato) engañan a un servicio privilegiado para que se autentique contra ellas y les entregue su token, y con ese token se lanza un proceso como SYSTEM.
Reconocimiento
Barrido completo de puertos contra la víctima, con detección de sistema operativo
| Puerto | Servicio |
| 80 | http |
Un único puerto abierto, el 80, y el resto filtrados. El fingerprinting no es fiable sin un puerto cerrado con el que comparar, pero apunta claramente a un Windows antiguo — Server 2008 / 7 / Vista. Con solo la web, ahí está todo.

Enumeración
Enumeración de versiones sobre el puerto 80

Microsoft IIS 7.5, que es el de Windows Server 2008 R2. Miro qué más cuenta el servidor con whatweb

X-Powered-By: ASP.NET — la web es ASP.NET, así que las extensiones que me interesan son .aspx. Enumero directorios

dirsearch no saca gran cosa, así que insisto con gobuster forzando la extensión .aspx

Ahí aparece /transfer.aspx, que no salía antes. Al visitarlo, un formulario de subida de ficheros

Explotación
Lo primero es ver qué acepta el formulario. Pruebo a subir directamente una webshell con extensión .aspx

Invalid File. Please try again — hay un filtro de extensiones. En cambio, una imagen .jpg sube sin problema

El primer intento de bypass es un byte nulo: interceptando con Burp, renombro el fichero a prueba.aspx%00.jpg. El filtro ve un .jpg al final y lo deja pasar, pero el byte nulo trunca el nombre y en disco se guarda como .aspx

El fichero sube, pero para que sirva de algo tiene que ejecutarse, y para eso necesito saber dónde aterminan las subidas y que esa carpeta interprete ASP. Ahí entra la técnica que de verdad resuelve la máquina.
El truco del web.config
En IIS, el fichero web.config configura la carpeta donde está. Si consigo dejar uno en la carpeta de subidas, reconfiguro esa carpeta a mi gusto. Lo compruebo primero con un web.config inofensivo que, además de la configuración, lleva una línea de ASP que escribe «hola»

Lo subo

Y al visitarlo, la prueba sale perfecta: la carpeta de subidas es /UploadedFiles y el .config se ejecuta como código, no se sirve como texto

Ese web.config hace dos cosas clave en la carpeta: define un handler que manda cualquier .config al intérprete de ASP clásico (asp.dll), y quita .config de la lista de extensiones bloqueadas. Convierte /UploadedFiles en un sitio donde subir un .config con código dentro equivale a ejecutar.
Para la shell de verdad tiro de HackTricks, que documenta esta técnica y enlaza un ejemplo en el repositorio PayloadsAllTheThings

El web.config de ejemplo trae ya el código para ejecutar comandos: lee un parámetro cmd de la URL y lo pasa a WScript.Shell

Mención importante: descargando de GitHub con wget sobre una URL de tipo /blob/ se baja el HTML de la página, no el fichero. Hay que cambiar /blob/ por /raw/refs/heads/ (con curl -o pasa lo mismo)

Subo ese web.config a /UploadedFiles

Y pruebo a ejecutar un comando añadiendo ?cmd=whoami
http://bounty.htb/UploadedFiles/shell.config?cmd=whoami

Ejecución de comandos como bounty\merlin. El último paso es pasar de ejecutar comandos sueltos a una shell interactiva. Preparo una reverse shell de PowerShell en una línea

La meto en el parámetro cmd, pero hay que codificarla en URL para que el servidor la interprete entera; lo hago cómodamente desde Burp

Dato: el servidor limpia la carpeta /UploadedFiles cada poco, y cuando lo hace la shell vuelve a dar 404. Hay que moverse rápido entre subir y disparar.
Con el nc a la escucha en el 443, la conexión entra

Ya con shell, voy a por la primera bandera. Está en el escritorio de merlin, pero oculta: un dir normal no la muestra, hace falta dir -Force

Escalada de privilegios
Lo primero en un Windows es mirar los privilegios de la cuenta

SeImpersonatePrivilege habilitado. En un Windows Server 2008 R2 eso es una escalada directa con JuicyPotato, que abusa de la suplantación de tokens. Se podría haber ido por el camino de systeminfo + un suggester de parches para buscar un exploit de kernel

…pero teniendo SeImpersonate delante, JuicyPotato es más limpio. Subo a C:\Windows\Temp el JuicyPotato.exe y un nc.exe con certutil

El primer intento, lanzando JuicyPotato para que ejecutara directamente nc.exe, no me funcionó por más vueltas que le di. La solución fue generar una reverse shell propia con msfvenom y pasársela a JuicyPotato como el ejecutable a lanzar

Con el .exe en la víctima, lanzo JuicyPotato apuntando a él
El listener del 1234 recibe la shell, y esta vez el whoami es el bueno

NT AUTHORITY\SYSTEM. Control total, y con él la última bandera, en el escritorio del administrador
Flags
La de usuario, en el escritorio de merlin (oculta, con dir -Force)
Y la de root, en el de Administrator
Cómo se arregla
La cadena nace de una subida mal controlada y de un privilegio peligroso. Por capas:
- Validar bien las subidas: no fiarse de la extensión, y menos de una lista negra. Validar el tipo real del fichero, renombrar lo subido y guardarlo fuera del webroot, en almacenamiento que no ejecute nada.
- Bloquear web.config en las subidas: IIS no debería permitir que un usuario deje un web.config en una carpeta de subidas. La carpeta de uploads debe tener la ejecución de scripts deshabilitada y la escritura de configuración denegada.
- No procesar byte nulo: sanear los nombres de fichero y rechazar caracteres de control como %00.
- Quitar SeImpersonate a la cuenta web: es el privilegio que convierte un RCE de bajo nivel en SYSTEM. La cuenta del application pool debe correr con los mínimos privilegios y sin SeImpersonate/SeAssignPrimaryToken.
- Actualizar el sistema: un Windows Server 2008 R2 está fuera de soporte; las familias Potato clásicas dejan de funcionar en versiones modernas con las mitigaciones al día.
Conclusiones
Una máquina bastante avanzada para el nivel que propone HackTheBox, es verdad que a mi la escalada al hacerlo desde la shell que me pasaba con Burp Suite, un error enorme, se me complicó mucho, he visto otras resouciones y deberia de haberse hecho en 5 minutos, pero de todos modos, no la pondría como nivel Easy, es basante más Medium, muy recomendable