Cómo un "==" puede volverte vulnerable

¡Saludos!

    Hoy recién acabo de terminar los exámenes, con pésimos resultados, y vuelvo a tener tiempo para poder escribir aquí y continuar con los distitnos proyectos que tenía abiertos. Aetsu terminará en breves también sus exámenes… asi que empezaremos las pruebas del podcast en breve. Como ya os dijimos por twitter, sería muy interesante que nos comentarais qué tipo de contenido quereis que incluyamos y sobre qué temás os gustaría que hablasemos.

    En estos días sin escribir por el blog han saltado distintos 0-days gordos, como el de Java, que supuestamente fue parcheado, y volvieron a sacar otro 0-day, y otro, y ya me perdí el culebrón porque era demasiado lío. Recordad: cada vez que instalais un navegador y no desactivais JAVA (ni usais NoScript), Dios mata a un gatito. A parte de JAVA, salieron otras noticias, como la vulne de Ruby on Rails, o las de los foros SMF (ya parcheada). Y es esta última sobre la que vamos a hablar en este post porque me ha resultado muy interesante el disclosure que han hecho, y me parece muy aplicable a otras tantas aplicaciones web 🙂

   La vulnerabilidad de los foros SMF que han liberado estos días permitía a un atacante poder resetear la contraseña a un administrador. Este es el post original del disclosure.

      El problema base que vuelve a la aplicación vulnerable es que hace una comprobación del token generado para resetear la password que es inadecuada, y que puede dar por bueno un token que no lo es. Recordemos que los token son cadenas de caracteres aleatorios que se incluyen en las peticiones de las aplicaciones web para evitar que los usuarios legítimos caigan en ataques CSRF . Se comprueba el token a través de una comparación, usando “==” , entre el supuesto valor del token que se ha generado y el valor que nosotros hemos incluido en la petición (en realidad en el caso de SMF se hace con los diez primeros caracteres de un hash MD5, pero estoy extrapolando la vulnerabilidad para cualquier otra aplicación). En el caso de que el token que nosotros hemos enviado no coincida con el que la aplicación espera, no se permite el reseteo del password, y viceversa, si ambos coinciden te permite cambiar el password.

      En teoría no hay nada extraño, es lo correcto. Compruebo la cadena generada con la que me da el usuario para ver si es la misma. El problema está en cómo se hace dicha comprobación. Resulta que al comprobar con “==” una cadena que empiece con dígitos, ésta se convierte automáticamente en una variable tipo integer. Y esto conlleva una segunda consecuencia, y es que se aplican las mismas reglas que a estas variables. Es decir, podemos usar notación exponencial, colocando una “e” entre la base y el exponente.

      ¿Qué ocurre cuando 0 o 1 es elevado a cualquier número? Que se quedan iguales. 0e123 es igual a 0, 0e523452345234523452345 es igual a 0, y  por lo tanto también igual a 0e123. Y lo mismo ocurre con el 1: 1e124 es igual a 1, y 1e5555 es igual a 1e124. ¿Veis donde está la vulnerabilidad? Probemos el siguiente PoC:

<?php
$key1 = “0e12345”;
$key2 = $_GET[‘k’];
if ($key2 == $key1){

echo $key1 . ‘ es igual a ‘ . $key2;
} else {
echo $key1 . ‘ es diferente a ‘ . $key2;
}
?>

 Si probamos a pasarle ?k=0  nos dirá que son iguales. Pero ambos sabemos que ambas cadenas de caracteres son diferentes. Si probamos con 0e[cualquiercadena de nuemros] nos seguirá diciendo que los dos strings son iguales.  ¿A qué nos lleva esto?

  Una aplicación que genere unos tokens alfanuméricos y que no bloquee el número de intentos para hacer una determinaada petición, en alguno de esos tokens va a generar una cadena que será 0e[numeros] o 1e[numeros], por lo que su valor será 0 o 1. Si nosotros mandamos peticiones de forma continuada, alternando entre un string que empiece con 0e y otro con 1e, cuyo valor por lo tanto también será 0 o 1, llegarán a coincidir en algún momento y la petición será legitima.

  Me parece que esta vulnerabilidad es bastante intersante, y que es muy común encontrarla. Espero que reviseis vuestros códigos y a partir de ahora programeis teniendo en cuenta estas premisas.

Byt3z

Leer artículo original: Cómo un "==" puede volverte vulnerable

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.