Entrada

Insecure Deserialization Lab 2

Insecure Deserialization Lab 2

Skills

  • Modifying serialized objects

Certificaciones

  • eWPT
  • eWPTXv2
  • OSWE
  • BSCP

Descripción

Este laboratorio utiliza un mecanismo de sesión basado en serialización y es vulnerable a un bypass de autenticación como resultado. Para resolver el laboratorio, debemos editar el objeto serializado en la cookie de sesión para acceder a la cuenta de administrador. Luego, debemos eliminar al usuario carlos. Podemos iniciar sesión en nuestra propia cuenta utilizando las credenciales wiener:peter


Resolución

Al acceder a la web nos sale esto

Pulsamos sobre My account y nos logueamos utilizando las credenciales wiener:peter

Si recargamos la página web y capturamos la petición con Burpsuite veremos esta petición, vemos que el parámetro session contiene una cadena en base64

Cambiamos el nombre de usuario de wiener a administrator para ver si el access_token no se valida adecuadamente y podemos acceder a /admin. Para obtener la longitud de una palabra podemos usar el comando echo -n 'administrator' | wc -c, es importante usar el parámetro -n para que nos elimine el salto de línea

1
O:4:"User":2:{s:8:"username";s:13:"administrator";s:12:"access_token";s:32:"gvjt9t5t7t5pb6qnk8x8frmxz5bkweiu";}

Al mandar la petición a /admin con los nuevos datos nos responde con un Internal Server Error

La lógica basada en PHP es particularmente vulnerable a este tipo de manipulación debido al comportamiento de su operador de comparación flexible (==) al comparar diferentes tipos de datos. Por ejemplo, si realiza una comparación flexible entre un entero y una cadena, PHP intentará convertir la cadena de texto a un entero, lo que significa que 5 == "5" daría como resultado true

Esto también funciona para cualquier cadena alfanumérica que comience con un número. En este caso, PHP convertirá efectivamente toda la cadena en un valor entero basado en el número inicial. El resto de la cadena se ignora por completo. Por lo tanto, 5 == "5 of something" en la práctica se trata como 5 == 5

En PHP 7.x y anteriores la comparación 0 == "Example string" se evalúa como true, porque PHP trata la cadena completa como el entero 0

En PHP 8 y ​​versiones posteriores, la comparación 0 == "Example string" se evalúa como false porque las cadenas ya no se convierten a 0 en las comparaciones flexibles. Como resultado, esta vulnerabilidad no es posible en estas versiones de PHP

El comportamiento al comparar una cadena alfanumérica que comienza con un número sigue siendo el mismo en PHP 8. Como tal, 5 == "5 of something" todavía se trata como 5 == 5

Teniendo en cuenta la vulnerabilidad de PHP en versiones anterior a las 8, he modificado el valor del atributo access_token a un tipo booleano y con el valor 1 que es el de administrador. Lo que estamos haciendo aquí es aprovechando que al hacer esta comparación 0 == "Example string" entre un entero y un string devuelva true. A esta vulnerabilidad se le llama Type juggling, a parte de usar un integer con valor 0 para obtener true, también hay otros métodos https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Type%20Juggling para hacer lo mismo en la versión 8 de PHP y superiores

Se podría hacer de esta forma, así cuando se compare el access_token la comparación será 0 == "valor_access_token" lo que dará como resultado true, porque al comparar un integer con un string, en PHP 7 se convierte el string a 0 y por lo tanto el resultado de la igualdad sería true

1
O:4:"User":2:{s:8:"username";s:13:"administrator";s:12:"access_token";i:0;}

Otra alternativa es esta, la cual funciona en PHP 8, si se compara un booleano cuyo valor es true con un string o número el resultado de la igualdad será true

1
O:4:"User":2:{s:8:"username";s:13:"administrator";s:12:"access_token";b:1;}

Podemos hacer la prueba ejecutando este script de php, veremos que nos devuelve true dos veces

1
2
3
4
<?php
    var_dump(true == "xys");
    var_dump(true == 34);
?>

Una vez creado el token nos dirigimos al navegador y pulsamos Ctrl + Shift + i y pegamos el nuevo valor de session

Refrescamos con F5 y ya podemos acceder a /admin y borrar al usuario carlos

Esta entrada está licenciada bajo CC BY 4.0 por el autor.