Scraping Login Credentials With XSS
Unauthenticated JavaScript Fun
In prior blog posts I've shown the types of weaponized XSS attacks one can perform against authenticated users, using their session to access and exfiltrate data, or perform actions in the application as that user. But what if you only have unauthenticated XSS? Perhaps your client hasn't provided you with credentials to the application and you're looking to demonstrate XSS impact, or you're on a Red Team engagement.
In this blog post, I'll expand upon my previous blog post covering IFrame Traps. We'll use a reflected XSS vulnerability to frame the application login page in the IFrame trap, scrape the credentials from the login form as the victim types their credentials, and then exfiltrate those credentials to a third-party server.
If the site doesn't allow you to IFrame it from its own domain, you can still use JavaScript to create a fake login page that looks similar to the real one, and fake the URL address bar using window.history.replaceState(). However, using the real login page in an IFrame is considerably less effort if the target application allows it.
Once again, I'll be beating up on my favorite target, InfoSec Fashionistas.
First we'll need an XSS vulnerability to test against. Here is a simple PHP page with a reflected XSS vulnerability:
Instead of a simple JavaScript alert, we'll instead include a remote JavaScript file containing our actual payload. This file will contain our IFrame trap and the login form scraper. The credential scraper code will regularly poll the current value of the login form input fields.
For demonstration, we'll start our IFrame trap in debug mode, with the IFrame not drawn in full window. This will allow us to see the actual page the user is on with the XSS vulnerability. We'll color this page with a pink background to make it easier to see in the screenshots.
We'll change our payload to include our hosted malicious JavaScript file:
The IFrame trap update code will retrieve the current URL of the page in the IFrame that the user is interacting with and copy this path to the browsers URL bar making the ruse more compelling.
Now we'll configure our IFrame to take the full window and hide the actual XSS page that the user is really on.
Now we can see the result of our scraping code. As we begin to enter our username and password, we see the values we're typing received on our server as image names.
So, there is an example of being able to demonstrate impact for an unauthenticated XSS vulnerability. The JavaScript source code used in this example can be found on github: https://gist.github.com/hoodoer/f58ac94755ba2faf5d971d4350a580ed.
If you have issues or ideas how this can be improved, my DMs are always open @hoodoer.
This example exploits XSS vulnerabilities and the ability to IFrame the site. To prevent such vulnerabilities, see the OWASP links in the references.
References
- https://gist.github.com/hoodoer/f58ac94755ba2faf5d971d4350a580ed (POC Source Code)
- https://www.trustedsec.com/blog/persisting-xss-with-iframe-traps (IFrame Trap Blog)
- https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html (XSS Prevention Cheat Sheet)
- https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html (Clickjacking Prevention Cheat Sheet)