Introducción

El 17 de junio de 2026, VulnCheck asignó oficialmente el CVE-2026-55200 a un fallo de memoria crítica en libssh2 que permite a un servidor SSH malicioso o comprometido corromper la memoria de un cliente que se conecta sin necesidad de credenciales ni interacción del usuario. El error afecta todas las versiones de libssh2 hasta la 1.11.1 inclusive y tiene un score CVSS 4.0 de 9.2, categorizado como «crítico».

El detalle clave aquí es que libssh2 es una librería cliente SSH, no un servidor. Esto significa que cualquier aplicación que utilice libssh2 para conectarse a servidores SSH externos —desde herramientas de línea de comandos hasta frameworks de automatización— puede verse afectada si ese servidor externo está bajo control de un atacante. La vulnerabilidad reside en la función ssh2_transport_read() dentro de transport.c, encargada de parsear paquetes SSH durante el handshake. El problema es un clásico integer overflow a buffer overflow (CWE-680), donde un valor malicioso en packet_length puede desencadenar una escritura fuera de límites en el heap del cliente.

Qué ocurrió

El 12 de junio de 2026, los mantenedores de libssh2 fusionaron un parche mediante el pull request #2052. El investigador de seguridad Tristan Madani reportó la vulnerabilidad, pero no existe aún un release oficial con versión parcheada (a la fecha de este artículo). VulnCheck asignó el CVE el 17 de junio, y horas después se publicó una prueba de concepto (PoC) en el repositorio exploitarium de GitHub. Según el autor del repositorio, los exploits se publicaron sin notificación previa a los mantenedores.

El PoC incluye:

  • Un esqueleto local para desencadenar el fallo mediante un servidor SSH controlado.
  • Un harness de ejecución remota de código (RCE) para entornos controlados, aunque no es un exploit funcional listo para producción.
  • Fuzzing automatizado con IA, según admite el autor, lo que sugiere que la calidad del PoC podría mejorar con el tiempo.

La base técnica del fallo es la siguiente:

  1. La función ssh2_transport_read() lee el campo packet_length controlado por el atacante.
  2. El código verifica que packet_length > 1, pero no impone un límite superior.
  3. La suma de packet_length + valores fijos se realiza con aritmética de 32 bits. Si packet_length = 0xffffffff, la operación envuelve el valor a un número pequeño (ej: 4294967295 → 4 en 32 bits).
  4. libssh2 asigna un buffer de ese tamaño pequeño, pero luego escribe los datos reales del paquete (de 4 GiB) en ese espacio reducido.
  5. El resultado es una escritura fuera de límites en el heap del cliente, permitiendo corrupción de memoria y, potencialmente, ejecución de código arbitrario.

Este es el segundo fallo de este tipo en libssh2 en siete años: en 2019, el CVE-2019-3855 —un desbordamiento de enteros casi idéntico en la misma función— permitía a un servidor malicioso ejecutar código en el cliente. La recurrencia del mismo patrón en el mismo código subraya la necesidad de revisar los límites de validación en parsers de protocolos.

Impacto para DevOps / Infraestructura / Cloud / Seguridad

Riesgo actual y horizonte de explotación

A la fecha, CISA no ha reportado explotación en la naturaleza y el PoC publicado no es un exploit funcional de forma inmediata. Sin embargo, el riesgo es alto porque:

  • No requiere autenticación: cualquier cliente que utilice libssh2 y se conecte a un servidor SSH controlado por el atacante es vulnerable.
  • Sin interacción del usuario: el ataque ocurre durante el handshake SSH, antes de cualquier login.
  • Embedding oculto: libssh2 está embebido en herramientas comunes como curl, git, PHP, agentes de backup, actualizadores de firmware y miles de appliances. Muchos de estos binarios están estáticamente enlazados, por lo que una actualización del paquete del sistema operativo no los parchea. Ejemplos concretos:
AWS: Algunas instancias AMI o herramientas de CI/CD embeben libssh2 estáticamente.

Rust: La crate ssh2 (wrapper de libssh2) también es vulnerable si usa una versión afectada.

Debian: Ya tiene un paquete parcheado en testing (versión 1.11.2-1), pero los sistemas en producción pueden estar usando versiones estáticas antiguas.

Escenario de ataque realista

Un atacante podría:

  1. Comprometer un servidor SSH legítimo (ej: mediante otro fallo como el CVE-2026-55199, un DoS que bloquea clientes en un bucle CPU).
  2. Esperar a que herramientas de DevOps, CI/CD o monitoreo se conecten al servidor malicioso (ej: un pipeline de GitHub Actions que usa curl para descargar artefactos).
  3. Enviar un paquete SSH con packet_length = 0xffffffff, desencadenando la corrupción de memoria en el cliente.
  4. Lograr ejecución de código en el contexto de la aplicación cliente (ej: en un pipeline de CI/CD, lo que podría escalar a compromiso de la infraestructura).

Matriz de impacto por tecnología

TecnologíaVersiones afectadasRiesgo de exposiciónAcción recomendada
libssh2Hasta 1.11.1 inclusiveAltoParchear a versión 1.11.2+ o fuente mainline
curlVersiones estáticas con libssh2 <= 1.11.1MedioVerificar enlazado estático y actualizar
GitVersiones con libssh2 embebidoMedioActualizar Git y dependencias
Rust (crate ssh2)Todas con libssh2 <= 1.11.1Bajo-MedioActualizar dependencia a ssh2 >= 0.9.4
Debianlibssh2 <= 1.11.1 en *stable*AltoActualizar a libssh2 1.11.2-1 (ya en *testing*)
AWS (AMI)Algunas imágenes con libssh2 estáticoDependeRevisar AMI y actualizar pipelines
PHPVersiones con libssh2 <= 1.11.1MedioActualizar PHP y librerías asociadas
## Detalles técnicos

Vector de ataque específico

El fallo ocurre en src/transport.c, función ssh2_transport_read():

static int ssh2_transport_read(LIBSSH2_SESSION *session)
{
    unsigned char *data;
    size_t datalen;
    /* ... */
    unsigned long packet_length = _libssh2_ntohl(buffer); /* valor controlado por atacante */
    if (packet_length < 1) {
        return -1;
    }
    /* ... cálculo de tamaño con aritmética de 32 bits ... */
    packet_length += 10; /* ejemplo de offset fijo */
    if (packet_length > session->max_packet_size) {
        return -1;
    }
    /* ... */
    _libssh2_buffer_read(buffer, data, packet_length); /* escribe packet_length bytes reales */
}

El problema es que no hay verificación de límite superior antes de la suma. Si packet_length = 0xffffffff:

  • La suma 0xffffffff + 10 en 32 bits resulta en 0x00000009 (9 en decimal).
  • Se asigna un buffer de 9 bytes.
  • Se escriben 0xffffffff bytes (4 GiB) en ese buffer, sobrescribiendo memoria adyacente en el heap.

Relación con otros CVEs recientes

El mismo repositorio exploitarium incluye dos CVEs más en libssh2:

  • CVE-2026-55199 (CVSS 8.2): Un DoS que bloquea al cliente en un bucle CPU mediante un conteo de extensiones malicioso.
  • CVE-2025-15661 (CVSS 8.3): Un heap over-read en operaciones SFTP.

Ambos comparten el mismo contexto de cliente SSH y refuerzan la necesidad de parchear todos los CVEs recientes en libssh2, no solo el CVE-2026-55200.

Contexto histórico y comparativa

libssh2 ha tenido múltiples vulnerabilidades de memoria en su parser SSH:

AñoCVETipoImpactoNotas
2019CVE-2019-3855Integer overflowRCEMismo patrón que CVE-2026-55200
2020CVE-2020-14145Buffer overflowRCEEn BLOCK33
2023CVE-2023-4879Integer overflowDoSBloqueo en handshake
La recurrencia de estos fallos sugiere que el parser de SSH de libssh2 ha sido históricamente difícil de auditar completamente, especialmente en código legado escrito en C.

Qué deberían hacer los administradores y equipos técnicos

Paso 1: Identificar libssh2 embebido en tu infraestructura

No confíes en que un apt upgrade libssh2 o yum update libssh2 te proteja. Muchos binarios están estáticamente enlazados. Ejecuta estos comandos para detectar libssh2 en sistemas Linux:
# Buscar binarios estáticamente enlazados con libssh2 (requiere 'binutils')
find / -type f -executable -exec file {} + | grep "statically linked" | xargs -I {} sh -c 'ldd {} 2>/dev/null | grep -q libssh2 || echo {}' > /tmp/static-bins.txt

# Verificar versiones de libssh2 en paquetes dinámicos
dpkg -l | grep libssh2  # Debian/Ubuntu
rpm -qa | grep libssh2     # RHEL/CentOS
Ejemplo de salida preocupante:
/usr/local/bin/custom-backup-agent (estático, vinculado con libssh2 1.10.0)
/opt/aws-cli/lib/libssh2.so.1.0.1 (estático en entorno AWS)

Paso 2: Parchear libssh2 en sistemas dinámicos

Si tu sistema usa libssh2 como paquete dinámico, actualiza a la versión más reciente disponible:

# Debian/Ubuntu (versión 1.11.2-1 ya en testing)
echo "deb http://deb.debian.org/debian testing main" | sudo tee /etc/apt/sources.list.d/testing.list
sudo apt update
sudo apt install -t testing libssh2-1

# RHEL/CentOS (esperar release oficial o compilar desde fuente)
sudo yum install epel-release
sudo yum --enablerepo=epel-testing install libssh2

Paso 3: Actualizar dependencias embebidas

Para Rust (crate ssh2):

# Cargo.toml
[dependencies]
ssh2 = ">= 0.9.4"  # Versión parcheada

Para Python (librería paramiko):

pip install --upgrade paramiko==3.4.0  # Usa libssh2 embebido, verifica versión

Para Git:

# Actualizar Git a versión >= 2.45.1 (incluye libssh2 parcheado)
sudo apt install git=1:2.45.1-0+deb12u1  # Debian

Paso 4: Auditar pipelines de CI/CD

Revisa herramientas de automatización que usen SSH:

# Ejemplo: GitHub Actions con curl y SSH
- name: Download artifact
  run: curl -o artifact.tar.gz sftp://malicious-server.com/file.tar.gz

Si curl usa libssh2 <= 1.11.1, el pipeline es vulnerable. Solución:

# Usar versión parcheada de curl
jobs:
  download:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install patched curl
        run: |
          sudo apt update
          sudo apt install -y curl=7.88.1-10+deb12u5
      - run: curl -o artifact.tar.gz sftp://server.com/file.tar.gz

Paso 5: Implementar mitigaciones temporales

Mientras esperas parches definitivos:

  1. Bloquear conexiones SSH a servidores no confiables:
   # En firewalls de red
   iptables -A OUTPUT -p tcp --dport 22 -m string --algo bm --string "SSH-" -j DROP
   
(Nota: Esto es una medida temporal; no reemplaza el parche.)
  1. Usar SSH con ProxyJump a servidores de confianza:
   # ~/.ssh/config
   Host jump-server
     HostName jump.internal
     User ops
     IdentityFile ~/.ssh/jump-key

   Host target-server
     HostName target.external
     ProxyJump jump-server
     IdentityFile ~/.ssh/target-key
   
  1. Reducir permisos de herramientas que usen libssh2:
   # Ejecutar pipelines de CI/CD con usuarios mínimos
   chmod 700 /home/ci-runner/.ssh
   chown -R 1001:1001 /home/ci-runner/.ssh
   

Paso 6: Monitorear y responder a exploits

Configura alertas para detectar intentos de explotación:

# Ejemplo con Auditd (Linux)
echo '-a always,exit -F arch=b64 -S execve -F path=/usr/bin/curl -k' | sudo tee /etc/audit/rules.d/exploit-libssh2.rules
sudo augenrules --load
sudo systemctl restart auditd
Indicadores de compromiso (IoC):
  • Conexiones SSH a servidores con IPs no registradas en CMDB.
  • Procesos hijos de herramientas como curl, git o php con patrones anómalos en argumentos (ej: --max-time 0xffffffff).

Conclusión

CVE-2026-55200 es un recordatorio de que las librerías cliente de protocolos no son menos críticas que los servidores. El fallo expone un patrón recurrente en libssh2: validación insuficiente de límites en parsers de protocolos, lo que lleva a corrupción de memoria pre-autenticación. La publicación temprana de un PoC —aunque incompleto— acelera el cronograma de explotación. Para equipos de DevOps e infraestructura, el riesgo no está en el exploit funcional actual, sino en la inmensa superficie de ataque oculta: binarios estáticamente enlazados en pipelines, appliances y herramientas embebidas.

La acción inmediata debe enfocarse en:

  1. Descubrir dónde está libssh2 en tu infraestructura (estático vs. dinámico).
  2. Actualizar todo lo vinculado a versiones parcheadas o fuentes mainline.
  3. Aislar conexiones a servidores SSH no confiables.
  4. Monitorear intentos de explotación con reglas de auditoría.

La historia de libssh2 —con fallos similares en 2019, 2020 y 2023— sugiere que la revisión de parsers de protocolos debe ser una prioridad en auditorías de seguridad. No esperes a que aparezca un exploit funcional en la naturaleza: actúa ahora.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *