¿Cómo OWASP ZAP encuentra Reflected XSS?

0

Lo que estoy haciendo:

Estoy usando OWASP Zap para encontrar vulnerabilidades en un sitio (tengo el consentimiento del propietario) y Zap ideó una vulnerabilidad de XSS reflejada después de realizar una exploración activa en una solicitud POST. Me dijo que la variable "cn" (el nombre de usuario) era vulnerable al XSS reflejado y que la carga útil "><script>alert(1);</script> funcionaría.

Mi proceso:

Seguí adelante e intenté ingresar esto en el campo de entrada llamado "cn". El campo de entrada tenía una longitud máxima de 12, seguí adelante e hice un elemento de inspección rápida y lo cambié. Luego ingresé a la carga útil, puse un valor aleatorio para el campo de entrada de contraseña y hice clic en enviar.

El resultado:

Lamentablemente, no apareció un cuadro de alerta, solo un mensaje de usuario y contraseña incorrectos. Noté un poco "> que apareció después de insertar la carga útil. Cuando observé esto, descubrí que la etiqueta de secuencia de comandos había causado que "> se analizara como caracteres normales. <input type="text" name="cn" size="20" maxlength="20" value="<script>alert(1);</script>"> es el html. Sin embargo, el "> no debería haber modificado el js.

La conclusión

ACTUALIZACIÓN: Entonces, después de pensar en esto en la ducha, me di cuenta de que todo el punto de XSS reflejado ... que el valor proporciona al usuario tenía que reflejarse de nuevo. El parámetro un nunca fue realmente reflejado hacia mí. Pero esto todavía no responde a la pregunta ... ¿por qué ZAP lo tomó como una vulnerabilidad XSS cuando claramente no hay ningún XSS?

    
pregunta CoderPE 09.11.2018 - 02:08
fuente

1 respuesta

8

Estas verificaciones automáticas funcionan al poner una etiqueta de script que contiene un token aleatorio en cada campo. Por ejemplo, /someRequest?foo=x&bar=y podría convertirse en:

GET /someRequest?foo=<script>alert("147230578")</script>&bar=<script>alert("561972456")</script>

Mantiene un mapa de campos y los valores aleatorios que eligió (en este caso foo = 147230578, bar = 561972456) para rastrear qué parámetro es inyectable.

A continuación, comprueba si <script>alert("147230578")</script> o <script>alert("561972456")</script> aparecen en la página sin codificación . Si se encuentra la cadena, sabe que XSS es muy posible. Si no, no apareció en la página o se codificó en HTML.

En su caso, descubrió que si reflejaba esas cadenas de vuelta, identificaba qué campo era inyectable. La razón por la que no se ejecutó es que la etiqueta de script se inyectó en un atributo HTML.

Entonces, mirando su inyección:

<input type="text" name="cn" size="20" maxlength="20" value="<script>alert(1);</script>">

Lo que sucede aquí es que el HTML tiene un formato incorrecto, por lo que el renderizador del navegador simplemente intenta sacarle el máximo partido, ignora ambas etiquetas y cierra todo después de </script> . Luego ve "> que asume que es contenido y lo muestra en la página.

Si en cambio inyectamos "><script>alert(1)</script> en el parámetro, obtenemos esto:

<input type="text" name="cn" size="20" maxlength="20" value=""><script>alert(1)</script>">

Esta vez la etiqueta de entrada está cerrada, lo que hace que la etiqueta script se ejecute. Exitoso XSS! De nuevo, el "> al final solo se trata como contenido.

Para una ronda de bonos, ¿qué podríamos hacer si el parámetro vulnerable no permite el uso de corchetes triangulares? Como ya estamos en un atributo, podemos manipular el elemento input que estamos inyectando para ejecutar el script:

" onmouseenter="alert(1)" x="

Esto crea el siguiente resultado:

<input type="text" name="cn" size="20" maxlength="20" value="" onmouseenter="alert(1)" x="">

Tenga en cuenta que el atributo x no hace nada, solo nos permite mantener un HTML válido; los atributos desconocidos son simplemente ignorados.

En este caso, cuando el mouse del usuario ingresa al elemento de entrada, ejecuta el JavaScript y obtenemos XSS nuevamente.

Pero requiriendo la interacción del usuario apesta! Podríamos usar onload pero esto es a menudo delicado. En su lugar, podemos utilizar algunos trucos CSS para forzar la interacción del usuario:

" onmouseenter="alert(1)" style="display:block;position:absolute;top:0;left:0;width:50000px;height:50000px;z-index:999999;

Esto se convierte en:

<input type="text" name="cn" size="20" maxlength="20" value="" onmouseenter="alert(1)" style="display:block;position:absolute;top:0;left:0;width:50000px;height:50000px;z-index:999999;">

El estilo aquí parece un bocado, pero es bastante simple:

  • Haga que el elemento se muestre como un elemento de bloque (para que podamos dimensionarlo arbitrariamente)
  • Haga que la posición del elemento sea absoluta dentro de la ventana (para que podamos establecer su posición en cualquier lugar)
  • Mueve el elemento a (0,0)
  • Haga que el elemento llene completamente la página (de modo que el mouse del usuario tiene para ingresarlo)
  • Haz que el elemento aparezca encima de todo lo demás.

Esperemos que esto explique cómo funciona todo esto y cómo puede pasar del ejemplo dado por ZAP a un exploit XSS en funcionamiento.

    
respondido por el Polynomial 09.11.2018 - 02:39
fuente

Lea otras preguntas en las etiquetas