This project is for individuals.
One of the most helpful tools that a security-minded software developer can have is a fuzz-testing tool, or a fuzzer. A fuzzer is a type of exploratory testing tool used for finding weaknesses in a program by scanning its attack surface.
The best fuzzers are highly customizable, so generalized fuzzers are often quite complex to configure and use, and can become out-of-date quickly. Fortunately, we're software engineers, so we'll build a fuzzer that can be customized to a specific web application rapidly.
You have two choices of programming language: Ruby or Python. You may choose the specific packages to use - research them and find ones that fit your needs (there are many for both languages). For Ruby, successful projects have used Ruby with Mechanize, or Python with the Requests package or Mechanical Soup, or Scrapy. If you are using Python, past students strongly recommend Python3+ due to some inconsistencies in the 2.7 versions of packages (i.e. use "python3" and "pip3" to run).
Think of the above libraries like a GUI-less browser - it can simulate everything that a browser does, but programmatically. It does HTTP requests, parses HTML, and a lot more. In particular, they will:
Your code will be tested against a modified version of the DVWA we provided in the web application activity. We recommend you use DVWA as your test bed, but make sure your code is general enough to work on any website.
This example demonstrates a quick script for getting the links from our course web page using Ruby and the Mecahnize gem.
Your fuzzer must run from the command line. Depending on your language, your exact command might vary (e.g.
python fuzz.py or
ruby fuzz.rb), but the basic structure should follow this manpage:
fuzz [discover | test] url OPTIONS COMMANDS: discover Output a comprehensive, human-readable list of all discovered inputs to the system. Techniques include both crawling and guessing. test Discover all inputs, then attempt a list of exploit vectors on those inputs. Report potential vulnerabilities. OPTIONS: --custom-auth=string Signal that the fuzzer should use hard-coded authentication for a specific application (e.g. dvwa). Optional. Discover options: --common-words=file Newline-delimited file of common words to be used in page guessing. Required. Test options: --vectors=file Newline-delimited file of common exploits to vulnerabilities. Required. --sensitive=file Newline-delimited file data that should never be leaked. It's assumed that this data is in the application's database (e.g. test data), but is not reported in any response. Required. --random=[true|false] When off, try each input to each page systematically. When on, choose a random page, then a random input field and test all vectors. Default: false. --slow=500 Number of milliseconds considered when a response is considered "slow". Default is 500 milliseconds Examples: # Discover inputs fuzz discover http://localhost:8080 --common-words=mywords.txt # Discover inputs to DVWA using our hard-coded authentication fuzz discover http://localhost:8080 --common-words=mywords.txt # Discover and Test DVWA without randomness fuzz test http://localhost:8080 --custom-auth=dvwa --common-words=words.txt --vectors=vectors.txt --sensitive=creditcards.txt --random=false
Your output should be human readable. Think of it like a build report you might get in an email that you can review from time to time. It should be detailed enough that you can look into potential vulnerabilities, and it should also be readable enough that you're not parsing through HTTP outputs and log messages
An example of good output for
discovercan be found here. (You do not need to match this format exactly.) An example of good output from
test can be found here. Note that DVWA evolves over time, so these exact outputs may be slightly different than yours - these are just examples, not oracles.
You must use RIT's installation of GitLab for this project. By a pre-determined date (given by your instructor), please do the following:
You are required to push your code to this repository by the deadline. At each deadline, we will autmatically pull the code and grade that. You do not need a separate repository for each release - just keep working on the same repository for the entire fuzzer project. If you need a specific version to be graded (i.e. one that is not the most recent as of the deadline), contact your TA and they will make sure to check out the right one. We will assume the
master branch is your submission.
Please include a file called
.gitlab-ci.yml (note the dot at the beginning of the file name) in the root of your repository. Here is the base file you should use, but then adapt it to your configuration. Note that YML files don't like tabs as whitespace and are finicky about number of spaces for indentation.
image: andymeneely/swen331fuzzer before_script: # do not change any of the statements in this section - service apache2 start - mysql_install_db --user=mysql -ldata=/var/lib/mysql - service mysql start - /usr/bin/mysqladmin -u root password fuzzer - service mysql restart - /mysql-setup.sh # do not change any of the statements in this section fuzzrunner: script: # here is where you can write your commands to run your fuzzer or any custom setup commands - echo "hello class" # need some example files for vectors and words? These are on the image - cat /words.txt - cat /vectors.txt # An example fuzzer command. Note the url is DIFFERENT than XAMPP example (no /dvwa). - ruby fuzzer.rb discover http://localhost/ --custom-auth=dvwa stage: test
This is a continuous integration configuration file. Every commit you push to the repository, your fuzzzer will be run against DVWA installed in a clean environment. To see the output, go to GitLab and find your build in the "Pipelines" page. You are strongly encouraged to keep an eye on this output to make sure your code is working as expected as you work.
Your application should be easy to use from a customer's perspective. Some notes about your submision include:
pip install. If need be, you may modify your GitLab CI file to do any custom installs.
For this initial part, you will need to implement --custom-auth to log into DVWA.
For this product, DVWA is the main application you must authenticate to, but this fuzzer should work on any web application too. The code within the DVWA custom auth module of your program can be hardcoded. You are welcome to add other customizations for other products to test your fuzzer further (e.g. your senior project). With custom authentication turned off, the fuzzer should just crawl the exterior of the webapp (perhaps get lucky if the vector list had a password).
You cannotassume that DVWA will be installed on a specific server, in a specific folder, on a specific port. For example,
http://example.com:1234/foo/dvwa is a valid url we might try.
Be sure to document in your README any setup you need.
To demonstrate you are logged in, just print out the contents of the HTML of the DVWA home page, after loggin in, to stdout. (Remove this output for future rounds).
On the discovery side, your fuzzer will need to discover as many potential inputs to the system as possible. It will need to do the following:
http://localhost/index.jsp?something=ais the same page as
http://localhost/index.jsp?anotherthing=b, and there are two input that can be fuzzed (
anotherthing). Built-in APIs such as Java's
URLclass can help with this.
Once you're done with input discovery, it's time to test. Testing has two parts: trying vectors, and then determining if the outcome was out of the ordinary.
To conduct your test, you must use an external list of fuzz vectors. These are strings of common exploits to vulnerabilities. These lists can be found all over the internet. This list at OWASP is a fine place to start. TIP: when developing, keep this list short and targeted. You're fuzzing applications you know are vulnerable, so unnecessary vectors can slow your Edit-Compile-Test cycle.
Upon sending in the vector, you'll need examine the response to see if the page may have a vulnerability. Here are some reasons, and you may think of more.
foobar<foobarand the response should have
Submit your source code via GitLab. We will pull from the
master branch at the deadline. Write up a basic README on getting the code to run in other environments.