
Desbordamiento de búfer clásico basado en pila en Savant Web Server 3.1 que demuestra la corrupción de memoria remota de principios de los 2000 mediante una solicitud HTTP manipulada.
Desbordamiento de búfer basado en pila clásico en Savant Web Server 3.1 que demuestra la corrupción remota de memoria de principios de los 2000 mediante una petición HTTP manipulada (una vulnerabilidad de 2002 que exige más a un principiante que la mayoría de los CVEs de desbordamiento de búfer de 2025).
Este repositorio forma parte del material que utilizo cuando enseño explotación de corrupción de memoria (además de mi trabajo habitual, también imparto clases en diferentes cursos de ciberseguridad donde ayudo a formar a la próxima generación de ingenieros inversos). Cuando cubro desbordamientos de búfer basados en pila en clase, trabajo con casos reales en lugar de ejemplos de juguete, y este CVE es uno al que recurro específicamente cuando quiero poner a prueba a estudiantes que ya tienen algo de experiencia con sobrescrituras básicas de EIP.
La razón es que el año en un identificador CVE no dice nada sobre lo difícil que es la explotación. La mayoría de los estudiantes asumen que los CVEs más antiguos deben ser más simples: un desbordamiento directo, un JMP ESP y listo. Este demuestra lo contrario. Algunos CVEs que enseño de 2025 son fundamentalmente más básicos que este, porque la clase de vulnerabilidad es más simple o hay menos restricciones. CVE-2002-1120 requiere comprender cosas que algunos exploits modernos no exigen: por qué ciertos opcodes no pueden usarse en ciertas partes de la petición, cómo construir un salto condicional que siempre se ejecute cuando el incondicional está bloqueado, cómo entregar shellcode cuando no cabe donde normalmente lo pondrías, y cómo un egghunter resuelve un problema de espacio que de otro modo haría imposible el exploit.
Es el CVE que asigno cuando quiero ver si alguien realmente entiende lo que está haciendo.
Esta vulnerabilidad afecta a Savant 3.1, un servidor HTTP gratuito para Windows de 2002. Lo que hace que valga la pena estudiarlo en 2025 no es la antigüedad, sino la combinación de restricciones que introduce y las técnicas necesarias para sortearlas:
Cada una de estas restricciones es una lección en sí misma.
Savant es un servidor HTTP gratuito y de código abierto para Windows, diseñado originalmente para convertir cualquier computadora de escritorio en un servidor web. Escucha en el puerto TCP 80 y procesa peticiones GET HTTP estándar. El desbordamiento ocurre en el manejador que copia la ruta de la URI en un búfer de pila de tamaño fijo sin validar su longitud.
Detalles técnicos clave:
Savant procesa las peticiones GET HTTP entrantes y copia la ruta de la URI en un búfer de pila de tamaño fijo sin comprobar su longitud. Una versión simplificada de la lógica vulnerable se ve así:
char uri_buffer[270];
strcpy(uri_buffer, uri_path);
Enviar una petición GET con una URI de aproximadamente 271 bytes sobrescribe la dirección de retorno guardada en la pila. El desbordamiento está restringido; enviar significativamente más que eso provoca el fallo de una manera en la que EIP ya no está controlado, por lo que la ventana utilizable es estrecha.
La explotación es más compleja que una sobrescritura estándar de EIP debido a dos propiedades adicionales del servidor: el campo de método HTTP también se copia en memoria y se ejecuta, y el cuerpo de la petición HTTP se almacena en una región separada del heap en lugar de en la pila (ambas propiedades se convierten en partes esenciales de la cadena de explotación).
El fallo se puede reproducir enviando una petición GET con una URI lo suficientemente larga. No se requiere autenticación. Ejemplo usando Python:
import socket
HOST = '127.0.0.1'
PORT = 80
payload = b"A" * 271
request = (
b"GET /" + payload + b" HTTP/1.1\r\n"
b"Host: 127.0.0.1\r\n"
b"Connection: close\r\n"
b"\r\n"
)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(request)
s.close()
Cuando se ejecuta bajo un depurador, el fallo muestra EIP sobrescrito con datos controlados por el usuario:
EIP = 41414141
confirmando que la dirección de retorno guardada ha sido corrompida por el desbordamiento.
El objetivo de este repositorio no es solo demostrar el fallo, sino recorrer el proceso completo de explotación paso a paso, incluyendo cada restricción que hace que este caso sea más difícil que una sobrescritura estándar de EIP y cada decisión tomada para sortearlas.
Para mantener limpio el README principal, las notas detalladas de explotación, los scripts y los pasos del depurador se encuentran dentro de la carpeta Vulnerability 📂 de este repositorio.
Allí encontrarás el flujo de trabajo completo utilizado para explotar este CVE, incluyendo: