Skip to Main Content
July 07, 2022

Scraping Login Credentials With XSS

Written by Drew Kirkpatrick
Application Security Assessment Penetration Testing Red Team Adversarial Attack Simulation Remediation Assistance & Training Security Testing & Analysis

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.

Fig.1 - Dave is now 3x bigger than this. Beefcake.

First we'll need an XSS vulnerability to test against. Here is a simple PHP page with a reflected XSS vulnerability:

Fig.2 - Good old alert box.

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.

Fig.3 - Update function called every 200 milliseconds.
Fig.4 - Retrieve username and password values and exfil.

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:

Fig.5 - Including remote JavaScript file.
Fig.6 - Login page framed.

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.

Fig.7 - Copy IFrame URL into browser address bar.
Fig.8 - URL faked in browser address bar.

Now we'll configure our IFrame to take the full window and hide the actual XSS page that the user is really on.

Fig.9 - Hide the background XSS page.
Fig.10 - Hide the background XSS page.

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.

Fig.11 - Username captured.
Fig.12 - Password captured.

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:

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.