Serverless Blind XSS hunter with Cloudflare Workers
6 minutes to read
If you are not familiar with XSS Hunter by @IAmMandatory, it's an awesome tool for penetration testers and bug bounty hunters that allows easily hunt for blind XSS vulnerabilities. It's open-source with a ton of features. You can use the SaaS version, deploy it yourself or even go serverless with Refinery! You should absolutely give it a try :)
I was thinking about writing something similar for a while. I just wanted something way simpler, where I could experiment with different payloads, CSP bypasses and other stuff. Right now it can grab basic info about the visitor and website, take a screenshot and notify me on Telegram and E-mail. If you are fancier, you can easily add support for Slack or Discord notifications ...
TLDR; I did a simple XSS hunter as a Cloudflare Worker, source code is here: https://gist.github.com/vavkamil/d40e3b8dd1373445506517684959531e
WTF is CF Worker?
Assuming you already have Cloudflare account, just select any domain and start right away, or you can create custom workers.dev subdomain. Once finished, you can start hunting for blind XSS with simple payload e.g.:
With paid Cloudflare plan, please highly consider using Workers KV (Key-Value Store) for storing secrets.
Starting with Telegram, you will need to create a bot and get the API token. It's really easy, just talk to @BotFather and give it a name. Next, you will need to provide the bot with your user ID. Just talk to @RawDataBot or @userinfobot and they will respond with your ID.
To be able to send e-mails, my best recommendation is to use Mailgun. I'm really happy with the service that they are offering and you can configure it in 5 minutes (too lazy to write a step-by-step guide). Great for simulated phishing awareness too :)
The last part of the secrets is your Cloudflare worker route. Decide which path you want to use, once you are finished, create the route and pair the worker with it.
There comes the interesting stuff. Our blind.js script can behave differently based on the GET/POST requests and parameters. If it receives POST data from successful blind XSS attack, it will pass info about the website along with the screenshot to Telegram and e-mail.
I had some problems with message limits on Telegram side due to a huge base64 encoded strings, so I'm just sending basic notification and more detailed info is send to e-mail.
Sending messages from Telegram bot is very easy, you can even use HTML/markdown or just a plain text.
Same goes for Mailgun, just pass the basic HTTP auth headers and you are good to go.
You can even send a response to your victim after the successful execution :)
When the Workers route is requested via GET, there are three possibilities what can happen.
base64 parameter, it will decode the string and respond with the screenshot. I have implemented it this way because at the time it's not possible to do stuff with files or buffer, but it would be way more elegant to just send the screenshot as an attachment ...
This part is bothering me. To be able to do a screenshot of the victim's browser, you need to somehow serve html2canvas.min.js. With
html2canvas=1 parameter, it will do just that. This way it's possible to get the content from 3rd party domain and serve it from our origin, but it's a huge privacy risk. I was thinking about it and will probably just leverage Cloudflare cache and add hash checking mechanism to notice changes in the remote code.
And the last part is the most important one. This is the payload that will be injected everywhere :) It will inject
html2canvas.min.js and after the screenshot is ready, POST request with the data is fired to the worker to process.
I hope that it's not a total garbage script and somebody will appreciate it :) Have a lucky bug hunting ...