Vulnerabilidad Type Juggling y Magic Hashes

El lenguaje de programación PHP presenta un comportamiento denominado type juggling, al realizar una comparación “loose (==)”. Esta comparación tiene un conjunto de reglas de conversión de operandos con las que primero intenta convertirlos a un tipo común y comparable.

Al comparar una cadena con un número, tratará de convertir la cadena en un número y luego realizará la comparación. Incluso, si ambos operandos parecen números, aunque sean cadenas, los convertirá a ambos en número y ejecutará la comparación numérica. A continuación, se enlistan algunos ejemplos de comparaciones donde el resultado será verdadero:
• TRUE : “0000” == int(0)
• TRUE : “0e12” == int(0)
• TRUE : “0e12” == “0e98”
• TRUE : “0xF”   == “15”
• TRUE : “0e12” <= “1”

La anterior vulnerabilidad tiene una implicación específica para los hashes (MD5 y SHA1) que en PHP se codifican en base 16. Por ejemplo, al venir en forma “0e8578698…”, y como todos los siguientes caracteres después del “0e” son números, la cadena es interpretada como cero elevado a la potencia de algún valor. Por lo tanto, siempre tendrá un valor de cero.

Los magic hashes son aquellos que cumplen con la estructura “0+e[0-9]+” , como son:
• MD5(240610708) = 0e462097431906509019562988736854
• MD5(QNKCDZO) = 0e830400451993494058024219903391
• SHA1(10932435112) = 0e07766915004133176347055865026311692244

Un ejemplo de uso de magic hashes sería: al tomar la cadena “10932435112” y enviarla como contraseña (en un sistema que almacena sus contraseñas con SHA1), se va a comparar con el hash del valor real almacenado. Si ambos se procesan como “0”, el valor de retorno será verdadero y podrá iniciar sesión en la cuenta sin la contraseña válida.

Para evitar la vulnerabilidad type juggling, se deben emplear comparaciones tipo strict (===), que comprueba que ambas variables tengan el mismo tipo y valor, por lo que al evaluar la cadena 7===”7” regresará un valor falso.

Es conveniente verificar qué tipo de comparación (loose o strict) se lleva a cabo para funciones particulares. En caso de que sea posible utilizar una comparación strict, especificar esa opción en el código. Por ejemplo, “in_array()” por defecto es una comparación loose, sin embargo, es posible cambiarla a strict.

Bibliografía:
• https://owasp.org/www-pdf-archive/PHPMagicTricks-TypeJuggling.pdf
• https://www.netsparker.com/blog/web-security/php-type-juggling-vulnerabilities/
• https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09
• https://www.whitehatsec.com/blog/magic-hashes/