Debo de ser aficionado a meter los Ddos en los lugares más recónditos enelpc y fuera de él, pues de casualidad llegué de nuevo, a una sentencia vulnerable en el mundo de las aulas virtuales. Anteriormente ya publiqué algo similar en esta entrada, aunque esta vez, el fallo se encuentra en un algoritmo creado para dar el refresco de actualización, a las ventanas de Chat que reciben los mensajes dentro de la conocida plataforma Moodle.
El contador de espera, que recoge la variable “&wait=”, tiene una peculiar forma de ir aumentando su tasa de refresco, según aumenta a su vez los segundos a la espera. La URL es la siguiente:
http://Dominio.com/Moodle/message/refresh.php?id=1&name=enelpc.com&wait=1
A su vez el campo “&name=”, rescata el nombre de usuario de la base de datos que contiene mensajes nuevos.
Me llamó la atención ver como la tasa de refresco, se incrementaba con no demasiada lógica, pues la variable “&wait=”, mostraba la siguiente secuencia de números.
&wait=1, &wait=3, &wait=4, &wait=5, &wait=6, &wait=8, &wait=10, &wait=12, &wait=15, &wait=18, &wait=22, &wait=27, &wait=33...
¿Qué cojones está pasando? ¿No saben sumar 1 y evitan problemas?
Así que no dudé dos veces en acceder a través del Terminal Service, para leer el dichoso PHP que creaba este comportamiento.
Refresh.php me contaba lo siguiente:
**************************************************************************
if ($wait < 300) { // Until the wait is five minutes
if ($wait < 300) { // Until the wait is five minutes
$wait = ceil(1.2 * (float)$wait); // Exponential growth
**************************************************************************
**************************************************************************
Obviamente, solo me tenía que centrar en esta línea.
********************************************************
$wait = ceil(1.2 * (float)$wait); // Exponential growth
********************************************************
********************************************************
La función ceil en php, devuelve el siguiente valor entero mayor, redondeando el valor si es necesario, así que si el resultado es por ejemplo 1,2 aun siendo más lógico redondear al valor menor, se transformaría a ser un 2.
Realmente la práctica es mucho más sencilla que el trabalenguas que os acabo de explicar, así que para entender el algoritmo mejor, veamos un ejemplo:
1
1*1,2 = 1,2 ->2
2*1,2 = 2,4 ->3
3*1,2 = 3,6 ->4
4*1,2 = 4,8 ->5
5*1,2 = 6 ->6
6*1,2 = 7,2 ->8
8*1,2 = 9,6 ->10
10*1,2 = 12 -> 12
12*1,2 = 14,4 ->15
15*1,2 = 18 -> 18
18*1,2 = 21,6 -> 22
22*1,2 =26,4 -> 27
27*1,2 = 32,4 -> 33
33...
1*1,2 = 1,2 ->2
2*1,2 = 2,4 ->3
3*1,2 = 3,6 ->4
4*1,2 = 4,8 ->5
5*1,2 = 6 ->6
6*1,2 = 7,2 ->8
8*1,2 = 9,6 ->10
10*1,2 = 12 -> 12
12*1,2 = 14,4 ->15
15*1,2 = 18 -> 18
18*1,2 = 21,6 -> 22
22*1,2 =26,4 -> 27
27*1,2 = 32,4 -> 33
33...
Hasta aquí todo perfecto, el valor se incrementa constantemente, y nunca tiene el motivo de llevar a error.
¿Pero que número es el único que multiplicado por 1,2 consiga un comportamiento anómalo?
0
0*1,2 = 0 -> 0 (Cada cero segundos repite su ejecución) Cero por cualquier número es igual a cero.
El redondeo lleva a un número entero mayor que -1 y menor que 1, del cual no se puede esperar una tasa de refresco con incremento, así que las peticiones que este conlleva al servidor, se ahogan en continuos e infinitos GET.
Llevemos a la práctica mi teoría, mientras Tamper Data hace el trabajo sucio.
En intervalos de imperceptibles milisegundos, se lleva a cabo innumerables peticiones GET que el servidor no tiene más remedio que contestar, así incrementando el tráfico hasta poder llegar a colapsarlo sin necesidad de otro software que automatice la tarea, a lo que están acostumbrados nuestros amigos Anonymous.
Con esto no solo disminuiremos la velocidad para responder peticiones del servidor, si no también sus recursos entre otras cosas, porque estamos haciendo conexiones directamente a la base de datos, para recuperar el nombre de usuario y leer las tablas.
Así que desde la parte servidor nos encontraremos con este panorama:
Seguro más de un administrador, se volvería loco al ver tantas peticiones desde su localhost, siendo estas invocadas por el archivo refresh.php, hacia el puerto 3306, o más bien el utilizado por defecto en MySQL. Todo esto incluso podría llegar a Crashear la tabla de la base de datos, como alguna vez pasó con indetectables y algún listillo que dentro de poco se verá acusado por posesión de Botnets.
Por otro lado el FIX para las versiones de Moodle, sería tan simple como agregar un “if”. Si el valor es menor a 1, que devuelva 1, de esta forma conseguiremos que el algoritmo creado por los desarrolladores del proyecto, no pudiese ser modificado a manos de terceros.
Para aquellos que quieran corregir el archivo o simplemente sean tan despiadadamente paranoicos como Germán, en este tema de la seguridad, ya saben lo que deben de hacer.
Saludos 4n4les! ;)
La verdad es que Moodle respecto a su programación es de risa. Es de lo peor programado que he visto.
ResponderEliminarEspero que lo mejoren ya que es una plataforma muy usada y muy importante en el mundo de la enseñanza. De echo en el centro en el que estudio usamos esta plataforma.
Saludos!!! y muy buena entrada, como siempre... XD
bueno bueno.
ResponderEliminarSe nota el nivel en comparacion al año pasado, me gustan tus entradas, sigue asi n_n
ResponderEliminar@byhanzo
ResponderEliminarMil gracias hermano! La verdad que un porcentaje bien alto de universidades u otros centros de enseñanzas, ya se aventuran a la creación de cursos online.
@ar3sw0rmed
Buenos días! no creo que cambie tanto mis temas, aunque ya como habrás visto odio la programación, sino seguramente tendría más de este estilo. Igualmente muchas gracias :)
bro como puedo ver las resupuestas de un cuestionario de la moodle es muy interesante todo esto de lo que hablas
ResponderEliminar