Fuzzing is the smash and grab of the hacking community. It focuses around sending a large amount of invalid content to a page and recording the results. It is the reprobates version of SQL Injection and arguably the base form of penetration testing (though you LOIC users out there are probably the base form of life form).
We will create a script that will take values from the FuzzDB meta-characters file and send them to every parameter available and record all the results. This is most definitely a brute-force attempt to identify vulnerabilities and requires a sensible human being to go through the results.
For this, you will require the FuzzDB from Mozilla. At the time of printing, this is available from https://code.google.com/p/fuzzdb/. The file you specifically want for this script is /fuzzdb-1.09/attack-payloads/all-attacks/interesting-metacharacters.txt
within the fuzzdb
TAR file. I'm reusing the test PHP scripts from the XSS script for proof of concept, but you can use this against whatever you like. The aim is to trigger an error.
The script is as follows:
import requests import sys from bs4 import BeautifulSoup, SoupStrainer url = "http://127.0.0.1/xss/medium/guestbook2.php" url2 = "http://127.0.0.1/xss/medium/addguestbook2.php" url3 = "http://127.0.0.1/xss/medium/viewguestbook2.php" f = open("/home/cam/Downloads/fuzzdb-1.09/attack-payloads/all- attacks/interesting-metacharacters.txt") o = open("results.txt", 'a') print "Fuzzing begins!" initial = requests.get(url) for payload in f.readlines(): for field in BeautifulSoup(initial.text, parse_only=SoupStrainer('input')): d = {} if field.has_attr('name'): if field['name'].lower() == "submit": d[field['name']] = "submit" else: d[field['name']] = payload req = requests.post(url2, data=d) response = requests.get(url3) o.write("Payload: "+ payload +" ") o.write(response.text+" ") print "Fuzzing has ended"
The following is an example of the output produced when using this script:
Fuzzing has begun! Fuzzing has ended
We import our libraries. As this is a testing script again, we establish our URLs in the code:
url = "http://127.0.0.1/xss/medium/guestbook2.php" url2 = "http://127.0.0.1/xss/medium/addguestbook2.php" url3 = "http://127.0.0.1/xss/medium/viewguestbook2.php"
We then open two files. The first will be the FuzzDB meta-characters file. I've included my path, though it is acceptable to make a copy of the file in your working directory. The second file will be the file you write to:
f = open("/home/cam/Downloads/fuzzdb-1.09/attack-payloads/all-attacks/interesting-metacharacters.txt") o = open("results.txt", 'a')
We create an empty dictionary to be populated by our parameters and attack strings:
d = {}
As the script writes its output to a file, we need to provide some text to show that the script is working, so we write a nice and simple message:
print "Fuzzing begins!"
We read the original page that accepts input and assign to a variable:
initial = requests.get(url)
We split out the page with BeautifilSoup
and identify the only fields we want, being the input fields and the name fields from there:
for field in BeautifulSoup(initial.text, parse_only=SoupStrainer('input')): if field.has_attr('name')@~:
We need to check again that any fields named submit are provided with submit
as data, otherwise we apply our attack string:
if field['name'].lower() == "submit": d[field['name']] = "submit" else: d[field['name']] = payload
We submit first a POST
request sending out dictionary of attack strings mapped to input fields and then we request a GET
request from the page that shows output (some errors may occur before the third page so you should consider restricting accordingly):
req = requests.post(url2, data=d) response = requests.get(url3)
Because the output will be long and messy, we write the output to the file that we opened initially, so that it may be easily reviewed by a human being:
o.write("Payload: "+ payload +" ") o.write(response.text+" ")
We reset the dictionary for the next attack string and then provide the user with an end of script output for clarity:
d = {} print "Fuzzing has ended"
You can just keep adding stuff to this recipe. It's designed to be open for multiple types of input and attack. FuzzDB contains lots of different attack strings, so all of these can be applied. I encourage you to explore.