5 min read

Identifying Blind XSS Attack Vectors with XSSHunter

Setting up a self-hosted instance of XSSHunter to identify blind XSS vectors.
Identifying Blind XSS Attack Vectors with XSSHunter
Photo by Taras Chernus / Unsplash

In the ever-evolving world of cybersecurity, the ability to stay ahead of potential threats is paramount. One of the threats, often overlooked but packing a surprising punch, is Blind Cross-site Scripting (bXSS).

What is bXSS?

Unlike traditional XSS, where immediate feedback is given upon the execution of a malicious payload, bXSS payloads are like silent assassins. They're typically triggered somewhere in the background, away from the originally tested web page.

For example, if an XSS payload is stored in a database and later retrieved from a different web application or internal backend system to visualize or process the data again. Our payload may then execute in those applications and not on the originally tested web page, where we inserted our XSS payload initially. This makes bXSS particularly sneaky, as such payloads are able to execute within other systems that may not alert back.

So, while the proverbial "guards" are busy looking out for front-end disruptions, our quiet bXSS ninja can wreak havoc in the background on systems with a different scope. However, how do we notice such potential havoc on other systems?

We need a way of interaction!

Detecting bXSS Vulnerabilities

To detect blind XSS vulnerabilities, we need a way of interaction between our JavaScript payload run on external systems; and ourself, as security researcher.

Typically, one would advice the JavaScript payload to call back to a server under our control. The JS payload would then send over some typically interesting data, such as information about the victim, cookies and maybe details on where the payload was executed (IP, URL, hostname etc.).

As crafting such payloads and setting up a functional server may be time consuming, XSSHunter was developed. XSSHunter is a web application crafted to detect these hidden bXSS attack vectors and report back potential findings and details into a beautiful web interface.

XSSHunter has grown in popularity due to its effectiveness and ease of use. But, like many open-source projects, it needed constant care and updates. That's where the company Truffle Security came into the picture. Taking up the mantle of maintaining XSSHunter since March 2023, they have breathed new life into this previously deprecated tool.

However, in today's blog post, we are not just talking about any version of XSSHunter. We're diving into a unique GitHub fork of XSSHunter, which comes packed with a slew of cool features not available in the original repo. Perhaps most notably:

  • Single user support and multi user support: you can setup XSSHunter in either single user mode with only your account or in multi user mode using either the env file or with Google OAuth(allowing only the Gmail accounts you want to login). Compared, the original XSSHunter version only allows Google OAuth login and does not restrict the Gmail accounts allowed(all Gmail accounts can create an user and login).
  • Full Trufflehog support: Detect secrets on the page your payload fired. The original version implemented simple regex checks for AWS, GCP and Slack keys. This fork supports all the current ~750 detectors from Trufflehog.
  • No blurred screenshots: Inspect the webpage your payload fired. No blurred screenshots as introduced in the commits by Truffle Security.
  • Local Storage: Read all data stored in Local Storage for the page the payload fired on.
  • Slack, Discord, Telegram and custom notifications: Send notifications to Slack, Discord and to your custom HTTP hook when a bXSS triggers. Compared, the original XSSHunter version only sends email notifications.

Spawning XSSHunter

XSSHunter is available as Docker container. The original GitHub fork requires you to build the Docker image yourself. Furthermore, a reverse proxy is recommened to expose and use XSSHunter's web interfaces.

For this blog post, I forked the GitHub repository and overhauled some missing key features:

  1. GitHub Actions to automatically build a Docker Image. The resulting docker images are available on l4rm4nd/xsshunter.
  2. Adjustment of the provided docker-compose.yml file to support external Docker images and Traefik as reverse proxy instead of Caddy.

Docker Compose

In order to spawn your self-hosted XSSHunter application, you can use the provided docker-compose.yml example from my GitHub repository. It consists of three containerized services (a database, the xsshunter frontend and trufflehog for secret scanning). Finally, an example .env file is provided for you to adjust.

You can spawn up the XSSHunter instance via the following commands:

# clone the github repository
git clone https://github.com/l4rm4nd/xsshunter && cd xsshunter

# copy the provided example .env file
cp env.example .env 

# adjust the environment variables to your needs
nano .env

# adjust compose file to your needs
nano docker-compose.yml

# spawn up the containers
docker compose up

Afterwards, the XSSHunter web application will be available at your definied hostname on TCP/8080. The login credentials were defined in your .env file.

Use an SSL/TLS reverse proxy such as Traefik to expose XSSHunter productively. Not part of this blog post though.

Why two hostnames?

The new XSSHunter application maintained by Truffle Security introduced a separation between the internal admin panel and the public facing panel for providing the XSS stager payload.

Therefore, you are tasked to provide two hostnames. One to access the admin panel and one to host your bXSS payloads. Technically, there is no difference between those two hostnames. Both will directly communicate with the XSSHunter Docker container. However, the hostname used for the admin panel will automatically redirect to /app, where the admin panel lives. The other one will not.

You can access the admin panel by manually appending /app to your hostname url for the XSS payloads. Therefore, ensure to configure access controls for the /app endpoint, if necessary.

The admin panel is already protected by authentication but you may want to restrict access with other measures like Basic Authentication, IP whitelisting or Authelia as identify provider.

After spawning up XSSHunter and logging in, you are presented with a few application areas.

The 'Settings' Area

This application area allows you to manage and adjust the XSSHunter settings. You can configure webhooks to receive notifications or configure additional JavaScript payload chains.

The 'XSS Payloads' Area

This application area provides you with common bXSS example payloads. Choose wisely according to your injection area.

If the JavaScript payload is triggered, you will receive a new entry at the XSS PayloadFires area.

The 'XSS Payload Fires' Area

This application area will contain your successful bXSS attacks.

As soon as one of your bXSS payloads fires, a new entry will popup with a screenshot of the affected website as well as further details. The detailed report section will contain various information such as:

  • The URL and title of the webpage your payload was fired on
  • The victim's IP address
  • The victim's user agent
  • The victim's cookies not protected by HttpOnly cookie flag
  • Sensitive data and secrets from Local Storage
  • Sensitive secrets found by Trufflehog in HTML and JavaScript files
  • Misconfigured Cross-Origin-Resource-Sharing (CORS)
  • and a few more things but less mention-worthy
Screenshot of a successful bXSS attack
Report details of a successful bXSS attack

Operating with XSSHunter

As soon as XSSHunter is up and running, you can start hunting for blind XSS attack vectors.

  1. Head to the XSS Payloads section and choose your preferred payload that fits your target's injection point.
  2. Inject your payload into the target site.
  3. If the payload fires somewhere, you will receive a new bXSS report in the XSS Payload Fires section of XSSHunter. Inspect the report details for juicy information and secrets.
Please be aware that unauthorized hacking is illegal in most countries.