XSS con llamadas a funciones Javascript
https://hackcommander.github.io/bug-bounty-3/#
Last updated
https://hackcommander.github.io/bug-bounty-3/#
Last updated
marzo 06, 2023
En este post voy a mostrar un XSS interesante que informé en un programa de recompensas de errores: XSS reflejado sin pasar por una redirección de seguridad 302 debido a la presencia de llamadas a funciones Javascript. Como buena novela, tiene todos los elementos para ser un informe interesante: un bypass, una carga útil personalizada, un artículo de investigación de PortSwigger... ¡Espero que lo disfrutes y aprendas algo nuevo!
Encontré este activo a través de amass + httpx. Si está buscando servicios http en subdominios del dominio example.com y tiene su archivo de configuración en la ruta /home/user/.config/amass/config.ini, puede usar el siguiente comando
Copiar código al portapapeles
Amass es una herramienta OSINT para realizar mapeo de red de superficies de ataque y descubrimiento de activos externos, que es una herramienta muy famosa utilizada en el paso de reconocimiento en la recompensa de errores. La salida del comando amass anterior es una lista de subdominios del dominio dado, es decir, una lista de objetivos potenciales.
Httpx is a multi-purpose HTTP toolkit allow to run multiple probers. In this case, the input of httpx is a list of subdomains and the output is a list of subdomains that have an http service in any of the ports given as a parameter. Also it shows some additional information about the service such as the title, the detected technologies… that I have specified in the parameters to be displayed.
This domain is one of the most important domains of the company in question, so it could also be obtained by googling the name of the company without the need to use any specific subdomain discovery tool.
I found this vulnerability through gau + kxss. If you are looking for XSS in the subdomain www.example.com, you can use the following command
Copy code to clipboard
Gau is a tool used to fetch known URLs from AlienVault’s Open Threat Exchange, the Wayback Machine, Common Crawl, and URLScan for any given domain. This tool does not always find all the URLs of a domain but it is a good starting point to search XSS or other types of vulnerabilities.
Kxss is a tool used to find all the “problematic characters” that are reflected in the response of any URL given as a parameter. The reflection of some problematic characters does not mean that an XSS exists but it is an indication that it could exist.
Both tools are based in other tools of tomnomnom.
In this case I got an output like the following
where the blue color is obfuscating unimportant findings and the red color is obfuscating the XSS candidate URLs.
As you can see, there are 2 parameters that reflect all the dangerous characters: utm_campaign and utm_source. Both parameters belong to the same URL and in fact in the URL there were more UTM parameters in the same situation. It is not the first time I find an XSS in this type of parameters so it is always worth taking a look at them.
Although there are several UTM parameters that may be vulnerable to XSS, I am going to focus on the utm_source parameter. I have seen that the utm_source parameter reflects all the dangerous characters but it’s important to see where the parameter is reflected in the response, that is, the context of the XSS. Why is this important? Because it’s essential to build a customized payload.
By sending the payload HackCommander through the utm_source parameter I got the following response
As you can see the payload is reflected inside a Javascript script, so the potential XSS would be in a Javascript context. Within the script, the payload is reflected inside a dictionary that is passed as a parameter to the push method of the dataLayer array. The yellow color is obfuscating the value of one of the dictionary keys so the payload HackCommander is reflected inside one of the dictionary values, not inside one of the keys.
So if I want to inject Javascript code I have to send a payload with the following characters:
” to close the string.
} to close the dictionary.
) to close the call to the push method.
; to close the Javascript line of code which calls the push method of the dataLayer array.
A Javascript payload such as alert(1);.
A </script> tag to close the Javascript script to avoid Javascript syntax errors.
Before injecting any Javascript payload, let’s see if I can close the push method and inject some string into the script. Sending a payload like the following
Copy code to clipboard
I got the following response
So far so good! Then I tried to send the following payload
Copy code to clipboard
and I got the following response
The server didn’t like something because when I changed the HackCommander payload to the Javascript payload alert(1) it returned a 302 Security Redirect. It is possible that there was some WAF or server-side configuration implemented to detect potentially dangerous payloads, in this case Javascript function calls.
Javascript allows to use `` instead of () to call functions such as alert (Template literals), that is, it allows to use calls of the form alert`1`. Not all security measures take into account this flexibility of Javascript and only blacklist expressions of the form string1(string2). Therefore, a typical bypass for this type of situation is to change the () to ``, that is, use a payload of the type
Copy code to clipboard
In spite of this, I received the following response
DAMN! It doesn’t work. So… I had to follow another strategy.
After a while, I remembered a Linkedin post I had seen from the PortSwigger researching team that talked about different ways to call a JavaScript function without parentheses
The seventh way to call a JavaScript function without parentheses (PortSwigger)
After taking a look at all the proposed payloads, I thought that the seventh method discovered might fit my needs. Therefore I sent the following payload
Copy code to clipboard
and I received the following response
The payload is completely reflected! Redirection bypassed!
After that, clicking in the option Show response in browser I got the following response
con una alerta vacía. Después de hacer clic en Aceptar obtuve la siguiente respuesta
con la alerta(1). No estoy seguro de por qué apareció la alerta vacía, pero el hecho importante es que la alerta(1) se ejecutó.
Por eso es importante mantenerse al día en el campo de la ciberseguridad y leer todos los artículos de investigación.
No es el propósito de esta sección explicar el significado de la carga útil, ya que esto se puede ver en el enlace PortSwigger anterior. Lo que esta sección pretende explicar es... ¿Por qué esta carga útil omite la redirección de seguridad 302? Es imposible saber con certeza la respuesta a esta pregunta sin tener el código fuente, pero aquí está mi teoría.
Si recuerda, en la sección anterior, la siguiente carga útil
Copiar código al portapapeles
devolvió un redireccionamiento de seguridad 302.
Pero... ¿Cuál es el origen de esta redirección? ¿La cadena de alerta? ¿Los paréntesis? ¿La combinación de ambos?. La siguiente carga útil
Copiar código al portapapeles
es el mismo que el anterior pero cambiando la cadena de alerta a la cadena HackCommander, y obtuve la siguiente respuesta
así que... ¿El problema era la cadena de alerta? Para resolver esta pregunta envié la siguiente carga útil
Copiar código al portapapeles
y obtuve la siguiente respuesta
Así que el problema no era la cadena de alerta. Como puede ver, el problema fue la combinación de la cadena de alerta más el argumento de entrada.
Entonces, lo que creo que está causando la redirección es algún mecanismo similar a regex que rechaza las cargas útiles del tipo keyword (inputParams) o keyword 'inputParams' (llamadas a funciones y métodos de Javascript, en general) donde keyword es cualquier elemento de una lista negra compuesta de nombres de métodos Javascript, una lista negra del tipo.
Copiar código al portapapeles
Así que la siguiente carga útil
Copiar código al portapapeles
Probablemente omita la redirección porque la llamada de cadena no está en la lista negra.
En pocas palabras, creo que la vulnerabilidad proviene del uso de una lista negra de métodos de Javascript para rechazar cargas útiles sospechosas en lugar de usar otro método de validación más robusto y general.
Como dije antes, el dominio afectado era uno de los dominios más importantes de la empresa, por lo que la criticidad de los activos se clasificó como alta. De hecho, en el momento en que informé de esta vulnerabilidad había un multiplicador de recompensa 3X en cualquier vulnerabilidad reportada en ciertos dominios de la compañía, incluido este. Además, un XSS generalmente se considera una vulnerabilidad de gravedad media y, debido a que no pude registrarme e iniciar sesión en el sitio web, no pude demostrar un impacto alto, como el secuestro de sesión. Por lo tanto, el informe se clasificó como
Criticidad de los activos: Alta
Gravedad de la vulnerabilidad: Media
Recompensa: Más de $600 (debido al multiplicador de recompensa 3X)
Escanea todos los dominios de la empresa, no dejes de buscar vulnerabilidades en un dominio porque es bien conocido y piensas que todas las vulnerabilidades ya están reportadas. En este caso descubrí un XSS en un dominio muy conocido de la empresa porque el XSS no era obvio, requería un bypass, que aunque era simple nadie había descubierto antes. Así que... Sé humilde con tus colegas pero ten confianza, es fundamental si quieres dedicarte seriamente a la recompensa de errores.
Es importante mantenerse actualizado en el campo de la ciberseguridad y leer todos los artículos de investigación. Los descubrimientos de hoy pueden invalidar las medidas de seguridad de ayer.
Este error fue reportado en un programa privado de recompensas de errores en el que no está permitido publicar las vulnerabilidades encontradas. Por lo tanto, esta es una divulgación parcial, solo se exponen los detalles técnicos esenciales.
Tenga en cuenta los multiplicadores aplicados a los programas en los que participa. Estos multiplicadores pueden convertir una fruta baja en un plátano grande.