Yesterday, I released version 1.0.0 of the Shuriken XSS command line tool on GitHub. It’s the first public and open source web security tool I have authored, it was quite a learning process and I hope this blog post can help others who are planning on writing similar tools.
Shuriken was written in Python 2 and based off of another Python based XSS tool called XssPy written by Faizan Ahmad. My motivation for creating Shuriken was that I wanted to practice developing security tools in Python and I also wanted to have a quick way of testing a bunch of XSS payloads on a target URL. XssPy was an interesting tool, but it included a variety of features that were more than what I needed in most cases and was better fit for auditing many links on a single domain for XSS.
Some features I thought were missing in other command line XSS tools was the lack of screenshot capabilities and clean logs. With these desired features in mind, I developed Shuriken to allow testers to easily get started with running payloads against a single target URL and checking the results for false positives.
I learned a lot during development of Shuriken and it really helped me improve my rusty Python programming skills. I discovered a fantastic Python library for leveraging headless browsers to do XSS audits, I highly encourage anyone interested in doing similar development to see the Splinter docs. The browser I chose to use for this testing is PhantomJS and so far, I haven’t had any issues with it. It captures screenshots nicely and appears to websites as a legitimate user browsing around, instead of an illegitimate hacking tool.
Early on I had some difficulty getting the PhantomJS browser to play nice with Splinter, but after consulting with Google-sensei, I was able to get it installed and running XSS payloads. Speaking of XSS payloads, many of them include exotic characters that mess with Web Application Firewall filters. What this also means is that they don’t do well with being output in the command line. The following code fixed this problem by changing to UTF-8:
def __init__(self): # Expect some weird characters from fuzz lists, make encoding UTF-8 reload(sys) sys.setdefaultencoding('utf8')
Another problem that I dealt with was that screenshots were not helpful when they could not be linked to the payload that generated them. To solve this, I added an index that would be included in the screenshot name and then removed line breaks in the log file. Then, I could just match the line numbers to the screenshot index to see which URL matched with which screenshot. This is sort of a hacky solution, so if anyone knows a more elegant method then I’d love to hear it!
Looking forward, I’d like to add the ability to test XSS payloads on POST requests (currently Shuriken can only test GET requests). In addition, I would be interested in making the tool faster and maybe add concurrency. If anyone is interested in contributing, feel free to fork away! I can be contacted directly at firstname.lastname@example.org.
Shuriken GitHub repo: https://github.com/shogunlab/shuriken