
Entorno de reproducción mínimo basado en Docker para la vulnerabilidad de doble liberación previa a la autenticación en OpenSSH 9.1p1 (CVE-2023-25136), que demuestra corrupción de memoria y denegación de servicio mediante un cliente PoC en Python.
Este proyecto proporciona un entorno experimental mínimo local para reproducir la vulnerabilidad de corrupción de memoria double free antes de la autenticación en OpenSSH 9.1p1 (CVE-2023-25136) y observar el efecto de caída del proceso del servidor (DoS).
Nota: Tanto los análisis oficiales como los principales consideran que esta vulnerabilidad es "difícil de explotar prácticamente para ejecución remota de código" bajo la configuración de seguridad predeterminada. Este entorno se utiliza principalmente para demostrar el error de memoria y el efecto de denegación de servicio.
Máquina objetivo:
sshd de separación de privilegios--with-sandbox=no para desactivar la jaula seccomp22 y lo mapea al puerto 2222 del host (WSL)Máquina atacante:
paramiko para ejecutar el PoC, construyendo un identificador de cliente SSH específico e iniciando un handshake previo a la autenticaciónEstructura de directorios:
Dockerfile: Imagen para construir el entorno vulnerable de OpenSSH 9.1p1poc.py: PoC de cliente mínimo para desencadenar el double free en la fase previa a la autenticaciónAntes de realizar las siguientes operaciones en este directorio, asegúrese de:
pipEjecute en este directorio:
docker build -t sshd-9.1p1-vuln .
docker run --rm -d --name sshd-vuln -p 2222:22 sshd-9.1p1-vuln
Explicación:
--rm: elimina automáticamente el contenedor al salir--name sshd-vuln: nombre del contenedor-p 2222:22: mapea el puerto 22 del contenedor al puerto 2222 del hostdocker ps
Debería ver algo como:
CONTAINER ID IMAGE COMMAND STATUS PORTS
xxxxxx sshd-9.1p1-vuln "/usr/sbin/sshd -D…" Up ... 0.0.0.0:2222->22/tcp
Ejecute en este directorio:
pip install paramiko
poc.py utiliza paramiko.Transport para establecer activamente una conexión con el servidor SSH objetivo y falsifica el identificador del cliente en la fase previa a la autenticación, intentando desencadenar el double free.
Características clave:
127.0.0.1:2222 (el contenedor Docker local)SSH-2.0-PuTTY_Release_0.64-t/--target: IP del objetivo (por defecto 127.0.0.1)-p/--port: puerto del objetivo (por defecto 2222)-c/--client-id: identificador SSH de cliente falsificado--timeout: tiempo de espera (segundos)-v/--verbose: muestra información detallada de erroresAsegurándose de que el contenedor sshd-vuln esté en ejecución, ejecute en este directorio:
python3 poc.py
O especifique explícitamente los parámetros:
python3 poc.py -t 127.0.0.1 -p 2222 -v
Ejemplo de salida esperada del cliente:
==============================================
CVE-2023-25136 OpenSSH Pre-Auth Double Free
Minimal PoC Client
==============================================
[2024-xx-xx xx:xx:xx] Target: 127.0.0.1:2222, ClientID: SSH-2.0-PuTTY_Release_0.64
[+] Sending crafted pre-auth handshake...
[-] Authentication failed or connection closed early.
Por favor, revise los registros de sshd del servidor para ver si aparece 'free(): double free detected' u otra información, para confirmar si se ha desencadenado CVE-2023-25136.
Explicación:
Authentication failed o connection closed es un comportamiento esperado, ya que el subproceso de pre-autenticación del servidor puede fallar o cerrar la conexión activamente durante el procesamiento.Después de ejecutar el PoC, revise los registros del contenedor en el host:
docker logs sshd-vuln
Se espera ver una salida similar a:
Server listening on 0.0.0.0 port 22.
Server listening on :: port 22.
Invalid user from 172.17.0.1 port xxxxx
free(): double free detected in tcache 2
Donde:
Invalid user: debido a que el PoC utiliza un nombre de usuario vacío, OpenSSH registra un intento de usuario no válidofree(): double free detected in tcache 2: glibc detecta un double free y termina el subproceso sshd actual. Este es el fenómeno de corrupción de memoria/DoS que este experimento pretende observar.Nota: Para poder ver esta línea, al compilar OpenSSH desactivamos la jaula seccomp (
--with-sandbox=no); de lo contrario, la jaula podría interceptar el comportamiento anómalo antes del double free y terminar directamente el subproceso.
sshd continuará generando nuevos subprocesos para conexiones posteriores.