
Una prueba de concepto para CVE-2022-30600
Este repositorio contiene 2 implementaciones de una prueba de concepto que explota CVE-2022-30600.
CVE-2022-30600 es una vulnerabilidad de seguridad que permite a un atacante eludir el umbral de bloqueo de cuenta dentro de la aplicación web Moodle.
Según lo indicado por la siguiente entrada en la base de datos NVD https://nvd.nist.gov/vuln/detail/CVE-2022-30600, las versiones siguientes se sabe que son vulnerables a este exploit.
3.9 - 3.9.13 3.10 - 3.10.10 3.11 - 3.11.6
Como se describe en el commit utilizado para parchear esta vulnerabilidad, el problema radica en la lógica utilizada para acceder e incrementar el valor login_failed_count en la base de datos.
Si se produce más de 1 solicitud de inicio de sesión concurrente, entonces la aplicación web Moodle puede fallar al verificar y actualizar correctamente el valor de inicio de sesión dentro de la aplicación. Esto da como resultado que 2 o más fallos de inicio de sesión solo se cuenten como 1 fallo de inicio de sesión.
Para comprender mejor esto, el siguiente diagrama es un desglose de alto nivel de una solicitud de inicio de sesión fallida desde la perspectiva del cliente, la aplicación web y la base de datos.
sequenceDiagram
participant C as Cliente
participant W as Aplicación web
participant D as Base de datos
C->>W: Solicitud de inicio de sesión
W->>D: Solicita failed_login_attempt
D->>W: failed_login_attempt = 0
W->>W: local failed_login_attempt = 0
W->>W: local failed_login_attempt = 1
W->>D: failed_login_attempt = 1
W->>C: Inicio de sesión fallidoEl resultado es que el valor failed_login_attempt en la base de datos es correcto y los intentos de inicio de sesión posteriores actualizarán correctamente el valor.
Si un atacante envía una serie de solicitudes de inicio de sesión concurrentes, ocurre el siguiente problema.
sequenceDiagram
participant C as Cliente
participant W as Aplicación web
participant D as Base de datos
C->>W: Solicitud de inicio de sesión (sesión 1)
C->>W: Solicitud de inicio de sesión (sesión 2)
W->>D: Solicita failed_login_attempt (sesión 1)
W->>D: Solicita failed_login_attempt (sesión 2)
D->>W: failed_login_attempt = 0 (sesión 1)
D->>W: failed_login_attempt = 0 (sesión 2)
W->>W: local failed_login_attempt = 0 (sesión 1)
W->>W: local failed_login_attempt = 0 (sesión 2)
W->>W: local failed_login_attempt = 1 (sesión 1)
W->>W: local failed_login_attempt = 1 (sesión 2)
W->>D: failed_login_attempt = 1 (sesión 1)
W->>D: failed_login_attempt = 1 (sesión 2)
W->>C: Inicio de sesión fallido (sesión 1)
W->>C: Inicio de sesión fallido (sesión 2)El resultado de esta interacción es que el valor failed_login_attempt en la base de datos solo se incrementa en 1 a pesar de que se hayan producido 2 solicitudes de inicio de sesión fallidas. Esto se puede escalar hasta cientos de solicitudes, con los límites siendo la cantidad de solicitudes concurrentes que el cliente puede realizar y la cantidad de solicitudes que el servidor web puede gestionar simultáneamente.
Además, si un atacante tiene acceso a múltiples clientes (como una botnet) y puede sincronizar el momento en que se realizan estas solicitudes, entonces el atacante puede superar las limitaciones de usar un solo cliente y hacer que el ataque sea más difícil de mitigar.
poc.py es la implementación en Python3 de este ataque. Utiliza hilos para realizar las solicitudes concurrentes. Si bien esta prueba de concepto funciona, el bloqueo global de intérpretes (GIL) presente en Python3 dificulta el beneficio de usar múltiples hilos en esta circunstancia. Recomiendo encarecidamente usar la implementación en C++, ya que funciona mejor cuando el ataque se realiza desde un solo cliente.
poc.py [-h] -u USERNAME -url TARGET -w WORDLIST -t THREADS [-a ATTEMPTS] [-d DELAY]
opciones:
-h, --help
muestra este mensaje de ayuda
-u USERNAME, --username USERNAME
El nombre de usuario de la cuenta objetivo
-url TARGET, --target TARGET
URL base de la aplicación web Moodle objetivo
-w WORDLIST, --wordlist WORDLIST
La ruta al archivo de lista de palabras utilizado
-t THREADS, --threads THREADS
La cantidad de hilos creados para cada intento
-a ATTEMPTS, --attempts ATTEMPTS
La cantidad de intentos que desea realizar. El valor predeterminado es 1
-d DELAY, --delay DELAY
La cantidad de segundos entre cada intento. El valor predeterminado es 2
python3 poc.py -u admin -url https://moodle/ -w /usr/share/wordlists/rockyou.txt -t 15 -a 8
objetivo: https://moodle/
nombre de usuario de la cuenta: admin
lista de palabras: /usr/share/wordlists/rockyou.txt
hilos: se realizarán 15 solicitudes de inicio de sesión en cada intento
intentos: el ataque se repetirá 8 veces en total.
En este ejemplo, se realizarán un total de 120 (8 * 15) solicitudes de inicio de sesión. Habrá un retraso de 2 segundos entre cada intento.
poc.cpp es la implementación en C++ del ataque que utiliza la biblioteca curl para realizar el ataque. Por lo tanto, necesita algunas banderas del compilador para que la aplicación se compile. En general, esta implementación funciona mejor que la versión en Python3, ya que los hilos pueden utilizar todos los núcleos del dispositivo cliente, lo que permite más conexiones concurrentes en menos tiempo. Esto significa que el exploit puede funcionar de manera más consistente.
g++ poc.cpp -o poc -lcurl
Uso:
poc [OPCIÓN...]
-a, --attempts
La cantidad de veces que se realiza el ataque.
-t, --threads
La cantidad de hilos a usar en cada intento.
-n, --username
El usuario de la cuenta que está atacando.
-u, --URL
URL base de la aplicación web Moodle.
-d, --delay
El retraso de tiempo entre intentos. El valor predeterminado es 5.
-v, --version
Muestra la versión.
-h, --help
Muestra el mensaje de ayuda.
-w, --wordlist arg
Lista de palabras de contraseñas.
./poc -w /usr/share/wordlists/rockyou.txt -u https://moodle/ -n admin -a 3 -t 5 -d 2
lista de palabras: /usr/share/wordlists/rockyou.txt
URL: https://moodle/
nombre de usuario de la cuenta: admin
intentos: se realizarán 3 intentos
hilos: se usarán 5 hilos en cada intento
retraso: habrá un retraso de 2 segundos entre cada intento
Para desarrollar, probar y depurar estos scripts, creé una máquina virtual. Esta máquina virtual utilizó el siguiente software y versiones.
Moodle 3.9.0 PHP 7.2.34 MySQL 8.0.30 Ubuntu 5.15.0-41-generic Apache 2.4.52
No apruebo el uso de mi código fuente en actividades ilegales.