Estudio técnico de la vulnerabilidad CVE-2025-5548
En este trabajo se analiza la vulnerabilidad CVE-2025-5548, asociada a un desbordamiento de búfer en la pila presente en FreeFloat FTP Server v1.0. El objetivo principal del laboratorio es entender cómo se comporta una aplicación vulnerable ante entradas manipuladas y observar, en un entorno controlado, cómo un fallo de validación puede terminar afectando al flujo de ejecución del programa.
El desarrollo del repositorio no se limita a mostrar el resultado final, sino que recoge el proceso completo de investigación: preparación del entorno, selección de herramientas, observación del fallo, análisis de memoria y validación del impacto real de la vulnerabilidad.
El trabajo está planteado en dos bloques diferenciados.
En este apartado se explica cómo se ha montado el entorno de práctica, qué sistema operativo se ha utilizado, cuál es la aplicación vulnerable y qué herramientas se han considerado necesarias para llevar a cabo el análisis.
La segunda parte se centra en la parte práctica. Aquí se describe el proceso seguido para detectar el fallo, confirmar la corrupción de memoria, estudiar la sobrescritura de registros y comprobar cómo puede aprovecharse la vulnerabilidad.
La práctica se ha realizado sobre una máquina virtual con Windows 11 Pro 25H2 (Build 26200.6584). El software vulnerable seleccionado ha sido FreeFloat FTP Server v1.0, una aplicación antigua que resulta adecuada para este tipo de ejercicios por carecer de muchas de las protecciones habituales en programas actuales.
La red de la máquina virtual se configuró en modo NAT, lo que permitió acceso a Internet para instalar dependencias, descargar herramientas y mantener la conectividad básica del laboratorio.
Para cubrir todas las fases del análisis fue necesario apoyarse en varias utilidades. Algunas se utilizaron para preparar el entorno, otras para revisar el binario y otras para observar el comportamiento del proceso cuando se producía el fallo.
Se empleó para descargar repositorios, mantener organizados determinados recursos y facilitar la gestión del material utilizado durante la investigación.
Se utilizó como apoyo para verificar conectividad, identificar el servicio expuesto y comprobar que el objetivo estaba respondiendo correctamente en el puerto esperado.
Se instaló para disponer de bibliotecas, cabeceras y herramientas útiles en tareas de depuración y análisis a bajo nivel dentro del sistema Windows.
Se utilizó para ediciones rápidas, revisión de scripts y manipulación sencilla de cadenas o datos de prueba.
Sirvió como entorno cómodo para escribir scripts, probar automatizaciones y trabajar con código de forma más ordenada.
Fue útil especialmente cuando hubo que revisar scripts más largos o depurar lógica relacionada con la construcción de cargas.
Se contemplaron dos versiones:
Fue necesario para ejecutar Ghidra, ya que esta herramienta está desarrollada sobre Java.
Se utilizó para observar el estado del programa durante la ejecución, comprobar registros, revisar memoria y analizar el punto exacto en el que se produce el fallo.
Se empleó en la fase de análisis estático para revisar el binario y localizar funciones que resultaban sospechosas desde el punto de vista de la seguridad.
Se usó como apoyo para decompilar y entender mejor la lógica interna del programa vulnerable.
Este complemento facilitó tareas como la creación de patrones, el cálculo del offset y la identificación de caracteres problemáticos en la carga.
El componente principal del laboratorio fue FreeFloat FTP Server v1.0, que actúa como sistema objetivo dentro de la prueba de concepto. Su interés reside en que incorpora una vulnerabilidad clásica de desbordamiento en la pila, lo que lo convierte en un caso muy apropiado para análisis formativo.
Aunque existen máquinas virtuales ya preparadas para este tipo de ejercicios, en este caso se optó por documentar el entorno y justificar las herramientas utilizadas. Esto permite comprender mejor por qué cada aplicación forma parte del laboratorio y qué papel desempeña durante el análisis.
El primer paso consistió en comprobar que el servicio FTP estuviera accesible y funcionando correctamente. Una vez confirmada la conectividad, se revisó el binario mediante herramientas de análisis estático para localizar posibles puntos débiles relacionados con la gestión de cadenas.
Durante esta revisión aparecieron funciones inseguras como strcpy y strcat, lo que reforzó la sospecha de que el servicio podía ser vulnerable a entradas excesivamente largas. También se examinaron varias órdenes del protocolo FTP susceptibles de recibir datos controlados por el usuario, seleccionando una de ellas como candidato principal para las pruebas.
Con esta base, el proceso se cargó en un depurador para observar su comportamiento durante la ejecución.
La siguiente fase consistió en enviar cadenas cada vez más largas para comprobar si el programa dejaba de responder correctamente. Este procedimiento permitió verificar que, a partir de cierto tamaño, el servicio fallaba y acababa provocando una alteración en memoria.
Ese comportamiento confirmó que no se trataba de un simple error de validación superficial, sino de una corrupción real que afectaba al flujo del proceso.
Tras provocar el fallo, fue necesario calcular con precisión cuántos bytes hacían falta para alcanzar la dirección de retorno. Para ello se utilizó una secuencia no repetitiva, de modo que el valor reflejado en EIP en el momento del crash pudiera relacionarse con una posición exacta dentro de la entrada enviada.
Gracias a este procedimiento se obtuvo el desplazamiento concreto necesario para sobrescribir el registro de control.
Con el offset ya conocido, se preparó una nueva prueba en la que la dirección de retorno fue sustituida por un valor fácilmente reconocible. El objetivo era comprobar si el programa permitía modificar EIP de forma controlada.
La prueba fue satisfactoria, ya que el depurador mostró que el registro contenía exactamente el valor introducido. Esto demostraba que era posible alterar el flujo de ejecución y redirigirlo hacia una dirección elegida.
Una vez alcanzado ese punto, se analizó qué bytes podían interferir con la carga útil. En este tipo de vulnerabilidades es habitual que ciertos caracteres provoquen truncados, cambios inesperados o finalización prematura de la cadena.
Mediante comparaciones sucesivas en memoria se identificaron varios bad characters, entre ellos:
\x00\x0a\x0dDetectarlos fue importante para construir una carga final estable y compatible con el comportamiento del programa vulnerable.