Universidad Tecnológica de León Ingeniería en Redes Inteligentes y Ciberseguridad
Asignatura: Hacking Ético
Profesor: José Luis Alejandro Hernández Ramírez
Título del trabajo: Google XSS Game
Presenta: Fátima Abigail Porras Noriega
Matrícula: 18002125
Grupo: IRIC 901
León, Guanajuato. A 18 de agosto de 2021
INTRODUCCIÓN El Cross Site Scripting o XSS es un tipo de ciberataque por el cual se buscan vulnerabilidades en una aplicación web para introducir un script dañino y atacar su propio sistema, partiendo de un contexto fiable para el usuario. Los scripts son archivos de comandos o programas escritos en lenguajes de programación −como JavaScript− que se ejecutan en el navegador web. En su versión más inocua se ejecutan ventanas emergentes y, en el peor de los casos, son utilizados por atacantes para acceder a información sensible o al equipo del usuario. Siempre que una aplicación web transfiera datos de usuario no validados al navegador, habrá riesgo de un ataque por Cross Site Scripting o XSS, ya que este es el camino por el que los archivos dañinos van a parar al cliente o navegador. Una vez aquí, las aplicaciones infectadas manipulan scripts propios de la página tales como formularios de registro y, mientras que para el usuario todo indica que se trata de una página protegida, en realidad los datos están siendo transferidos a otro sitio sin ningún tipo de filtro. Pero no todos los ataques de XSS tienen como objetivo robar información privada o dañar al cliente afectado. Hay scripts muy extendidos que manipulan al cliente para convertirlo en iniciador de tácticas de phishing y de ataques de malware, o que cambian el contenido de una página afectándolo negativamente. Los causantes del ataque permanecen la mayor parte de las veces en el anonimato. Según el sitio oficial de OWASP las fallas XSS ocurren cada vez que una aplicación incluye datos que no son de confianza en una nueva página web sin la validación o el escape adecuados, o actualiza una página web existente con datos proporcionados por el usuario utilizando una API de navegador que puede crear HTML o JavaScript. XSS permite a los atacantes ejecutar scripts en el navegador de la víctima que pueden secuestrar sesiones de usuario, desfigurar sitios web o redirigir al usuario a sitios maliciosos. XSS es el segundo problema más frecuente en el Top 10 de OWASP y se encuentra en alrededor de dos tercios de todas las aplicaciones. Las herramientas automatizadas pueden encontrar algunos problemas de XSS automáticamente, particularmente en tecnologías maduras como PHP, J2EE / JSP y ASP.NET. Para aprender un poco más sobre este ataque, Google cuenta con un juego que nos ayuda a practicarlo, el cual es XSS Game y en el presente informe se explicará dicho juego. Este juego de seguridad consta de varios niveles que se asemejan a aplicaciones del mundo real que son vulnerables a XSS: en este caso, nuestra tarea será encontrar el problema y atacar las aplicaciones, similar a lo que podría hacer un hacker malvado. Los errores XSS son comunes porque tienen la desagradable costumbre de aparecer dondequiera que una aplicación web se ocupa de entradas que no son de confianza. En este juego, la motivación es resaltar patrones de codificación comunes que conducen a XSS para ayudarlo a detectarlos en su código para finalmente cambiar el sentido del código original, agregando y restándole elementos de manera que podamos aprender el funcionamiento de este ataque.
CROSS SITE SCRIPTING Regularmente en algunas aplicaciones web o aplicaciones de escritorio hay dos campos que se nos solicitan para iniciar sesión: Usuario y Contraseña, de modo que se tienen dos cajas de texto en las cuales se introducirán. Normalmente se tiene una sentencia del siguiente tipo: SELECT usuario, password FROM usuarios WHERE usuario = ‘x’ AND password = ‘y’De este modo, el código que se le inyectaría normalmente sería mediante lo siguiente: usuario ‘ OR a=’a’ --, de modo que se mostraría de la siguiente manera: SELECT usuario, contrasena FROM usuarios WHERE usuario = ‘x’ OR a=’a’ --‘ AND password = ‘y’, en donde a = cualquier cosa y podría ser 1=1, r=’r’, lo que se busca es que sea verdadero. Esta instrucción será verdadera todas las veces, sin importar que el usuario no coincida, como siempre es verdadera, nos va a arrojar siempre una función verdadera. Los dos guiones en SQL sirven para poner comentarios, de tal modo que ‘AND password = ‘y’ no tiene ningún valor ya que es un comentario. Y de esta manera se puede inyectar código, a través de las cajas de texto (los campos input) o de las URL. Como la sentencia SELECT se utiliza en una base de datos, se puede utilizar en cualquier programa que tenga una conexión a una base de datos, así es susceptible a una inyección de SQL. Y este ejemplo es precisamente cuando no se tiene ni el usuario ni la contraseña, de modo que se cambia el sentido al código original, agregándole y restándole elementos. En el Top 10 de OWASP https://owasp.org/www-project-top-ten/ se puede observar que la inyección de código SQL es el riesgo de seguridad que se encuentra en primer lugar. Mientras que otro es el Cross-Site Scripting https://owasp.org/www-project-top-ten/2017/A7_2017-Cross-Site_Scripting_(XSS). Hay tres formas de XSS, generalmente dirigidas a los navegadores de los usuarios: •
XSS reflejado: la aplicación o API incluye entrada de usuario no validada y sin escape como parte de la salida HTML. Un ataque exitoso puede permitir al atacante ejecutar HTML y JavaScript arbitrarios en el navegador de la víctima. Por lo general, el usuario deberá interactuar con algún enlace malicioso que apunte a una página controlada por el atacante, como sitios web, anuncios o similares de abrevaderos maliciosos.
•
XSS almacenado: la aplicación o API almacena la entrada de usuario no desinfectada que otro usuario o administrador ve en un momento posterior. El XSS almacenado a menudo se considera un riesgo alto o crítico.
•
DOM XSS: los marcos de JavaScript, las aplicaciones de una sola página y las API que incluyen dinámicamente datos controlables por el atacante en una página son vulnerables a DOM XSS. Idealmente, la aplicación no enviaría datos controlables por atacantes a API de JavaScript inseguras.
¿Qué impactos tiene? El impacto de XSS es moderado para XSS reflejado y DOM, y severo para XSS almacenado, con ejecución remota de código en el navegador de la víctima, como robar credenciales, sesiones o entregar malware a la víctima.
Como prevenir este ataque: La prevención de XSS requiere la separación de los datos que no son de confianza del contenido activo del navegador. Esto se puede lograr mediante: •
Uso de marcos que escapan automáticamente de XSS por diseño, como el último Ruby on Rails, React JS. Conozca las limitaciones de la protección XSS de cada marco y maneje adecuadamente los casos de uso que no están cubiertos.
•
Escapar de datos de solicitud HTTP no confiables basados en el contexto en la salida HTML (cuerpo, atributo, JavaScript, CSS o URL) resolverá las vulnerabilidades reflejadas y almacenadas de XSS. La hoja de trucos de OWASP 'Prevención XSS' contiene detalles sobre las técnicas de escape de datos requeridas.
•
La aplicación de codificación sensible al contexto al modificar el documento del navegador en el lado del cliente actúa en contra de DOM XSS. Cuando esto no se puede evitar, se pueden aplicar técnicas de escape sensibles al contexto similares a las API del navegador como se describe en la hoja de trucos de OWASP 'Prevención XSS basada en DOM'.
•
Habilitación de una Política de seguridad de contenido (CSP) como un control de mitigación de defensa en profundidad contra XSS. Es eficaz si no existen otras vulnerabilidades que permitan colocar código malicioso a través de archivos locales incluidos (p. Ej., Sobreescritura de rutas transversales o bibliotecas vulnerables de redes de entrega de contenido permitidas). GOOGLE XSS GAME
Google XSS Game es una plataforma de formación proporcionada por Google para aprender y practicar XSS. Consta de 6 niveles y en cada nivel, debes ejecutar una alerta de JavaScript para avanzar al siguiente nivel. En cada nivel, se le proporcionarán diferentes problemas y deberá ejecutar la alerta utilizando diferentes técnicas en cada nivel. Esto le ayudará a comprender varios métodos que se pueden utilizar para ejecutar XSS en una página web. Este juego se encuentra disponible en el siguiente enlace: http://xss-game.appspot.com/
Nivel 1: Hello, world of XSS. Objetivo: Inyectar un script para que aparezca un alert() de JavaScript.
Este nivel demuestra una causa común de secuencias de comandos entre sitios donde la entrada del usuario se incluye directamente en la página sin un escape adecuado. En este nivel se debe interactuar con la ventana de la aplicación vulnerable y buscar una forma de hacer que ejecute JavaScript. Se pueden tomar acciones dentro de la ventana vulnerable o editar directamente su barra de URL. La caja de texto es susceptible a inyección de código. En Target code (toogle) se nos brinda el código de cómo está construido el código de arriba. Y finalmente se nos dan pistas para que podamos averiguar cómo solucionar el nivel. Este nivel es sólo un desafío introductorio para mostrar cómo funciona un XSS, por supuesto, es un ejemplo muy básico y no realista. Todo lo que escribimos se incrusta en la página. Por lo tanto, simplemente se debe inyectar una etiqueta de secuencia de comandos con un código de alerta. Target code:
Pistas: 1. Para ver la fuente de la aplicación, puedes hacer clic con el botón derecho en el marco y elegir View Frame Source en el menú contextual o utilizar herramientas de desarrollo del navegador para inspeccionar el tráfico de la red. 2. ¿Qué sucede cuando ingresa una etiqueta de presentación como <h1>? 3. Muy bien, una última pista: <script> ... alert ... Al insertar simplemente texto plano, ocurre lo siguiente:
Las dos formas en las que se puede mandar un formulario es GET y POST, en este caso se está usando GET porque está visible en la URL. De manera que no se necesita usar el input para mandar información, sino que el código se podría inyectar incluso desde la URL. Así pues, siguiendo las indicaciones que se nos dan en las pistas anteriormente mencionadas, se inyectó la siguiente línea de código: <script>alert(“Hola”);</script> y de esta manera se pudo visualizar la ventana de alerta. El código simplemente se agrega a la entrada del usuario en la página web sin la desinfección, por lo que se entiende por el navegador como parte del código de la página y se ejecuta.
Nivel 2: Persistence is key. Objetivo: Inyectar un script para que aparezca un alert() en el contexto de la solicitud. Las aplicaciones web a menudo mantienen los datos del usuario en el lado del servidor y, cada vez más, bases de datos del lado del cliente que luego se muestran al usuario. No importa de dónde provienen, deben manejarse con cuidado. Este nivel muestra la facilidad con la que se pueden introducir errores XSS en aplicaciones complejas.
Al igual que en el nivel anterior, la vulnerabilidad de esta página es incluir HTML directamente en la página. Pero, esta vez hay una validación que nos impide usar la etiqueta script. Para evitarlo, podemos insertar una etiqueta de imagen con una URL no válida y un atributo onerror que ejecutará una alerta de JavaScript. Target code:
Pistas: 1. Tenga en cuenta que la publicación de "bienvenida" contiene HTML, que indica que la plantilla no escapa al contenido de los mensajes de estado. 2. Ingresar una etiqueta <script> en este nivel no funcionará. En su lugar, pruebe un elemento con un atributo de JavaScript. 3. Este nivel es patrocinado por las letras i , m y g y el atributo onerror. En caso de que no se pueda cargar la imagen se utiliza el atributo onerror, de manera que se lanzará un alert. De esta forma, basándonos en las pistas, el payload que se manda es el siguiente: <img src='x' onerror='alert("Hola Mundo")'>. La página intentará cargar la imagen de la fuente ' x', lo que fallará y luego activará el código del atributo onerror.
De esta manera, se muestra la ventana de alerta al no encontrarse la imagen y se puede avanzar al tercer nivel.
Nivel 3: That sinking feeling... Objetivo: Inyectar un script para que aparezca un JavaScript alert() en la aplicación. Dado que no se puede ingresar el payload en ninguna parte de la aplicación, se tendrá que editar manualmente la dirección en la barra de URL.
Como se ha visto en el nivel anterior, algunas funciones comunes de JS son sumideros de ejecución, lo que significa que causarán que el navegador ejecute cualquier script que aparezca en su entrada. En este nivel, la aplicación elige la pestaña de imagen basándose en el primer fragmento de URL (el hash después de la URL) y pasa un fragmento malicioso que se insertará en la página para activar la alerta. Target code:
Pistas: 1. Para localizar la causa del error, revise JavaScript para ver dónde maneja la entrada proporcionada por el usuario. 2. Datos en el window.location el objeto puede ser influenciado por un atacante. 3. Cuando haya identificado el punto de inyección, piense en lo que debe hacer para colarse en un nuevo elemento HTML. 4. Como antes, usando <script> ...como un payload no funcionará porque el navegador no ejecutará scripts agregados después de que la página se haya cargado. De esta manera, basándonos en las pistas se debe mandar un alert en cada una de las imágenes: document.querySelectorAll(‘1’), document.querySelectorAll(‘2’), document.querySelectorAll(‘3’), con el siguiente payload: ‘ onerror=’alert(“Hola Mundo”)’; Este código se debería ingresar en la URL que es donde se ejecuta. ¿Cómo funciona? El código fuente de la página muestra que obtiene el fragmento de URL y lo pasa a la función choosetab: window.onload = function () {chooseTab (unescape ( self.location.hash.substr (1)) || "1");} Esta función agrega y luego fragmenta texto a la fuente de la etiqueta de imagen y carga la nueva etiqueta en la página. function chooseTab(num) {// Dynamically load the appropriate image.var html = "Image " + parseInt(num) + "<br>";html += "<img src='/static/level3/cloud" + num + ".jpg' />";$('#tabContent').html(html);... Podemos engañar esto cerrando el atributo src con una comilla simple, y luego agregando un atributo onerror con una función de alerta como en el nivel anterior, y comentando la parte '.jpg' con barras dobles, de manera que creará la siguiente etiqueta img, que funciona bien. <img src = '/ static / level3 / cloud1' onerror = 'alert (); //. jpg' />
De esta forma se manda la ventana de alerta y se puede avanzar al siguiente nivel:
Nivel 4: Context matters. Objetivo: Inyectar un script para que aparezca un JavaScript alert() en la aplicación.
Cada bit de datos proporcionados por el usuario debe escaparse correctamente para el contexto de la página en la que aparecerá. Este nivel muestra por qué. La página de índice muestra un formulario en el que podemos pasar un número, que se pasa a la página del temporizador cuya función es solo contar el número que pasamos en segundos y luego redirigirnos al principio. Podemos engañar a su función de temporizador para ejecutar código arbitrario, ya que se agrega directamente a la página. Target code:
Pistas: 1. Eche un vistazo a cómo la función startTimer es llamada. 2. Cuando los navegadores analizan los atributos de las etiquetas, decodifican sus valores en HTML primero. <foo bar = 'z'> es lo mismo que <foo bar = '& # x7a;' 3. Intente ingresar una comilla simple (') y observe la consola de errores. Un ejemplo de payload que se podría inyectar es el siguiente, basándonos en las pistas: '**alert(“Hola Mundo!”));// ¿Cómo funciona? El valor que pasamos por la página de índice se agrega directamente al parámetro de función en el temporizador. <img src = "/ static / loading.gif" onload = " startTimer ('{{timer}}'); " />. Entonces podemos
manipular el javascript ejecutado aquí. Si pasamos el siguiente parámetro: 3 '** alert ()); // El javascript intentará evaluar 3 ** alert () antes de llamar a la función startTimer. Además, para evaluar el resultado de 3 ** alert () necesita obtener el valor devuelto por la función alert (), que hará que el navegador ejecute la función de alerta.
Se muestra la ventana de alerta:
Nivel 5: Breaking protocol. Objetivo: Inyectar un script para que aparezca un alert() en el contexto de la aplicación.
La secuencia de comandos entre sitios no se trata solo de escapar correctamente de los datos. A veces, los atacantes pueden hacer cosas malas incluso sin inyectar nuevos elementos en el DOM. En realidad, esta página inicial que se muestra no hace nada, solo nos lleva a la página de registro, donde ocurre la magia. En la página se puede introducir una dirección de correo electrónico (o cualquier cosa, no es evaluada después de todo), y
pulsa el enlace Go que nos llevará a la página aprobada por el parámetro next (por ejemplo: next = confirm). Podemos engañar a este parámetro inyectando código javascript en él, ejecutando la función de alerta. Target code:
Pistas: 1. El título de este nivel es una pista. 2. Es útil mirar la fuente del marco de registro y vea cómo se usa el parámetro de URL. 3. Si desea hacer clic en un enlace, ejecute Javascript (sin usar la onclick), ¿cómo puedes hacerlo? 4. Si estás realmente atascado, mira esto Borrador de IETF Para este nivel, basándonos en las pistas, un payload de solución podría ser el siguiente, primero mandando la sentencia
en
“Go”
y
posteriormente
en
game.appspot.com/level5/frame/signup?next=javascript:alert("Hola mundo!");
next:
http://xss-
¿Cómo funciona? El código de la página simplemente ingresa el valor del parámetro next en el atributo href del siguiente enlace: <href = "{{next}}"> Next >> </ a >. Entonces podemos inyectar código javascript en el atributo, que será entendido por el navegador como un bookmarklet. Y de esta manera se muestra la alerta:
Nivel 6: Follow the Rabbit. Objetivo: Encontrar una manera de hacer que la aplicación solicite un archivo externo que hará que ejecute un alert().
Las aplicaciones web complejas a veces tienen la capacidad de cargar dinámicamente Bibliotecas de JavaScript basadas en el valor de su URL parámetros o parte de location.hash. Esto es muy complicado de hacer bien, ya
que permite que la entrada del usuario influya en la URL. Al cargar scripts u otros tipos de datos potencialmente peligrosos, como XMLHttpRequest a menudo conduce a vulnerabilidades graves. En este nivel, la página agrega una etiqueta de secuencia de comandos con el atributo src que apunta al valor del primer fragmento de URL. Pero, antes de hacerlo, evalúa si el fragmento comienza con las palabras 'http' o 'https', para evitar que carguemos archivos externos. Pero podemos omitir esta validación omitiendo el protocolo 'http'. Para esta solución, estoy usando el archivo predeterminado proporcionado por Google en el desafío (reemplazando 'foo' por 'alert'). Target code:
Pistas: 1. Vea cómo el valor del fragmento de ubicación (después #) influye en la URL del script cargado. 2. ¿Es realmente infalible el control de seguridad de la URL del dispositivo? 3. A veces, cuando estoy frustrado, tengo ganas de gritar ... 4. Si no puede alojar fácilmente su propio archivo JS malvado, consulte si google.com/jsapi?callback=foo te ayudará aquí. Basándonos en las pistas, entonces el payload de solución puede ser el siguiente: http://xssgame.appspot.com/level6/frame#data:text/plain,alert('Hola mundo!');
De esta forma, se muestra la ventana de alerta y se finaliza el juego.
CONCLUSIÓN Cuando hablamos de seguridad web, cualquier precaución que podamos tomar es poca. Y ya no solo cuando tenemos una página web, sino también a nivel de usuario. Los hackers aprovechan cualquier vulnerabilidad o agujero de seguridad para tomar el control y aprovecharse para lanzar una campaña de phishing o malware. Una de las vulnerabilidades más conocidas y explotadas por los ciberdelincuentes es el cross-site scripting (XSS). El cross-site scripting (XSS) es un tipo de vulnerabilidad informática muy común en las aplicaciones web que permite a los atacantes colocar secuencias de comandos maliciosas en páginas web y, a su vez, instalan malware en los navegadores web de los usuarios. Estos ataques no se limitan solamente a las páginas web disponibles en Internet, sino que también puede haber aplicaciones que tengas instaladas en tu ordenador que sean vulnerables a estos ataques de cross-site scripting (XSS). Los perjuicios que puede ocasionar un ataque de Cross Site Scripting no deben ser subestimados, tanto para usuarios como para administradores de páginas web. Sin saberlo, un usuario puede arriesgar sus datos privados y actuar como cómplice de los atacantes. Los administradores web han de tener en cuenta que son responsables de los datos de sus usuarios y/o clientes. Si una web es víctima de tales ataques, los contenidos maliciosos y las caídas del servidor son causa de la pérdida de visitas de los usuarios. A la larga los buscadores reaccionan con penalizaciones y los internautas con desconfianza, lo que conlleva, en última instancia, a pérdidas económicas. Por todo esto los administradores y los usuarios deberían poner todos los medios para evitar ataques de XSS. El Google XSS Game fue de gran ayuda para aprender y sobre todo practicar este tipo de ataques, ya que nos permite darnos cuenta de las vulnerabilidades que una aplicación web pudiera tener para que de esta forma, estemos alertas en estas situaciones. Para concluir, los atacantes se las saben todas, pero es importante que se tomen ciertas medidas para prevenir este tipo de ataques y no ser una víctima más de los ciberdelincuentes. Tanto si eres un usuario de la World Wide Web o como si eres el propietario de una web. Unas de las medidas de seguridad que pude concluir son las siguientes a nivel de usuario de una aplicación web: En primer lugar no entrar en páginas web que no parezcan sospechosas no es suficiente. Es necesario que seas proactivo y cuides tu actividad en la red. Por ejemplo, utilizar un antivirus y mantener al día tus aplicaciones pueden ahorrarte más de un susto, manteniendo actualizada incluso la versión de tu navegador. De hecho, ellos trabajan proactivamente y liberan nuevas versiones frecuentemente para mantenernos a salvo. Por ejemplo: Google Chrome utiliza un filtro llamado XSSAuditor que analiza la solicitud HTTP y elimina funciones sospechosas de JavaScript; Mozilla Firefox utiliza un filtro XSS que modifica la carga útil mediante entidades HTML o codificaciones de URL. Esto evita que se ejecute código malicioso en el navegador y Microsoft Internet Explorer utiliza un filtro que divide los datos enviados en dos categorías: confiables y no confiables con el objetivo de verificar la ejecución inmediata del código. De este modo, considero que podemos mantenernos un poco más protegidos ante este tipo de ataques que suelen ser, tal y como se vio en OWASP, uno de los ataques más llevados a cabo en la era actual.