Saltar al contenido principal

Almacenado

Bajo

Este tipo de XSS implica que el código malicioso se almacena en el servidor y se muestra a los usuarios cuando acceden a una página específica. En el primer nivel nos encontramos con un libro de visitas, donde el código relevante de PHP maneja la entrada del usuario y la prepara para ser almacenada en una base de datos. Al introducirlo, observamos que el sistema imprime directamente lo que se ha ingresado en el campo nombre y mensaje.

Libro de visitias

<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>

Analizando el código el mensaje y el nombre son "sanitizados" utilizando mysqli_real_escape_string(), que es una función adecuada para proteger contra SQL injection pero no necesariamente contra XSS. Sin embargo, la función stripslashes se utiliza para eliminar las barras de un string con comillas escapadas. Esto puede no ser suficiente para prevenir un ataque XSS persistente.

Por esta razón, volvemos a empezar por las mismas pruebas que en el reflejado, introduciendo el siguiente código malicioso en el campo de comentario:

<script>alert("low")</script>

Este código nos permitirá evaluar si existe una vulnerabilidad XSS persistente y determinar si podemos ejecutar código malicioso en la aplicación. Al introducir este código en el campo de mensaje y enviarlo, la página web muestra una alerta con el mensaje "low", entonces está claro que la aplicación es vulnerable a ataques de Cross-Site Scripting. Esto se debe a que la entrada del usuario no está siendo debidamente validada o saneada antes de ser renderizada en la página web.

Input ataque básico

Medio

En este nivel, nos enfrentamos a una mayor complejidad al intentar ejecutar un ataque XSS almacenado en la aplicación. En el nivel medio, observamos que la vulnerabilidad XSS almacenada inicial ya no se ejecuta utilizando el método tradicional debido a una medida de mitigación implementada en el código PHP del servidor.

<script>alert("medium")</script>

Ataque medio no funcional

Aunque nuestra estrategia inicial no tuvo éxito, seguimos explorando nuevas técnicas para superar las medidas de seguridad implementadas en el servidor.

Input medio

Comprobamos que existe una limitación en el campo del nombre, restringido a 10 caracteres, lo que complicó la posibilidad de inyectar un script más largo o complejo.

Input medio

Una posible solución, implica ajustar esta restricción modificando el atributo maxlength del campo de entrada. Al cambiar este valor a uno mayor, como 100 caracteres, podemos permitir la entrada de una cantidad significativamente mayor de texto.

Input medio

<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );

// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );

// Sanitize name input
$name = str_replace( '<script>', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

//mysql_close();
}
?>

La solución propuesta implica ajustar esta restricción modificando el atributo maxlength del campo de entrada. Al cambiar este valor a uno mayor, como 100 caracteres, podemos permitir la entrada de una cantidad significativamente mayor de texto. Además, si la limitación también está presente en la base de datos, podemos ampliar el tamaño del campo correspondiente para garantizar que no haya restricciones adicionales más allá de las que hemos establecido en el frontend.

<SCRIPT>alert("medium")</SCRIPT>

Y ya tenemos nuestro premio.

Input medio

En situaciones donde la limitación del campo de entrada está controlada por JavaScript y el código está ofuscado, puede resultar complicado encontrar el punto de validación para eludirlo. En tales casos, podemos aprovechar herramientas como OWASP ZAP para interceptar y modificar las solicitudes antes de que lleguen al servidor, lo que nos permite realizar bypass de manera efectiva.

Para utilizar la intercepción de peticiones mediante OWASP ZAP, solo tenemos que abrir el navegador controlado desde el propio OWASP ZAP haciendo clic en el icono del navegador, como se muestra en la siguiente imagen resaltado en el cuadro rojo.

Desde el navegador que se nos abre, vamos a la web que necesitemos interceptar y activamos la intercepción haciendo clic en el icono verde, que vemos resaltado en la imagen con el cuadro azul.

Input medio

Después de haber introducido los textos "title" y "message" en los campos de entrada correspondientes, tenemos la oportunidad de modificar estos textos según nuestras necesidades antes de enviar la solicitud al servidor. Una vez que hayamos realizado las modificaciones deseadas, simplemente hacemos clic en el botón "Forward" para enviar la solicitud al servidor.

Input medio

La solicitud modificada contendrá los nuevos valores que hemos introducido en los campos "title" y "message", lo que nos permitirá aprovechar cualquier vulnerabilidad de XSS persistente que exista en la aplicación. Este proceso nos proporciona la capacidad de manipular los datos enviados al servidor y, en última instancia, ejecutar nuestro código XSS deseado.

Input medio

Input medio

Este enfoque nos permite realizar pruebas y explotar vulnerabilidades de XSS persistente de manera controlada, lo que nos ayuda a comprender mejor las posibles implicaciones de seguridad y a desarrollar estrategias de mitigación efectivas.

Alto

En el nivel alto de nuestro análisis de XSS, volvemos a aplicar el enfoque de comenzar desde los ataques más simples hasta los más complejos. Repetimos el proceso utilizado en el nivel medio, esta vez con la herramienta OWASP ZAP para aprovechar al máximo sus capacidades avanzadas de interceptación y modificación de solicitudes.

Input medio

Al abordar el nivel alto de nuestro análisis de XSS, nos encontramos con un obstáculo inesperado. Al observar la salida de la aplicación, notamos una diferencia en la forma en que se manejan los campos del nombre y del mensaje. Al analizar el código fuente relevante, descubrimos que, mientras uno de los campos se está saneando correctamente, el otro presenta una vulnerabilidad idéntica a la que encontramos en los niveles anteriormente mencionados.

Input medio

<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>

En este caso lo vamos ha hacer con img. Estamos poniéndolo en los dos porque nosotros realmente no sabemos el código que se esta ejecutando por detrás.

Input medio

Y ya tenemos nuestro XSS conseguido.

Esta discrepancia nos brinda una nueva oportunidad para intentar explotar la vulnerabilidad de XSS persistente utilizando las técnicas que hemos empleado en niveles anteriores. Al tener una comprensión más profunda del funcionamiento interno de la aplicación y de las medidas de seguridad implementadas, podemos repetir cualquiera de los ataques que demostraron ser efectivos en el pasado.

Input medio

Este proceso de retroalimentación y aprendizaje continuo es fundamental en el campo de la seguridad informática. Al enfrentarnos a desafíos inesperados y adaptarnos a nuevas circunstancias, fortalecemos nuestras habilidades y desarrollamos estrategias más efectivas para identificar y mitigar vulnerabilidades en aplicaciones web.