Wfuzz is a python based tool built for bruteforcing Web Applications. The tool is commonly used to find resources that are not directly linked such as directories, servlets, or scripts. Also, Wfuzz can bruteforce GET and POST parameters to check for different kind of injections (e.g., SQL, XSS, LDAP), bruteforce Forms parameters (e.g., User/Password), or fuzzing.
Wfuzz is a very flexible tool with many options. The fundamental note you should rememeber when using wfuzz is that anywhere you place the keyword ‘FUZZ’ in your query, it will try and bruteforce that parameter. The basic architecture of the Wfuzz Bruteforce program is as follows. It contains the elements listed below:
– payloads: the generated list of data to be sent to the web server (e.g., file, list, stdin, range, hexrand, names, hexrange, permutation).
– encoders: used to encode the payload in several ways, which is useful if the value in some parameter needs to be URL encoded, base64 encoded, or if the value should hold Unicode data, etc. There are also hash functions like md5 and sha1, which can also be used to generate the hash representation of the payload. A useful feature is a multiple encoding of the same payload, which can be great if some data is the first base64 encoded and then only the md5 hash is needed or something like that.
– iterators: used to iterate over all payloads. The iteration process can be done in several ways, but Wfuzz supports the three iterators: product, zip and chain. We need to remember that in our request URI we need to include the words FUZZ, FUZ2Z, FUZ3Z, …, FUZNZ, which will be replaced by the selected payloads in each iteration. The payload for each FUZZ element is selected by each –z option we’re passing the wfuzz command. We can also use the -V option to fuzz all variables in a request, in which case we don’t need the FUZZ keyword.
– plugins: used to extend the features of the wfuzz program.w
– printers: used to output the results in certain formats. Supported formats are the magic tree, HTML.
Additional features include:
- Multiple Injection points capability with multiple dictionaries
- Recursion (When doing directory bruteforce)
- Post, headers and authentication data brute forcing
- Output to HTML
- Colored output
- Hide results by return code, word numbers, line numbers, regex.
- Cookies fuzzing
- Multi threading
- Proxy support
- SOCK support
- Time delays between requests
- Authentication support (NTLM, Basic)
- All parameters bruteforcing (POST and GET)
- Multiple encoders per payload
- Payload combinations with iterators
- Baseline request (to filter results against)
- Brute force HTTP methods
- Multiple proxy support (each request through a different proxy)
- HEAD scan (faster for resource discovery)
- Dictionaries tailored for known applications (Weblogic, Iplanet, Tomcat, Domino, Oracle 9i,
Vignette, Coldfusion and many more.i
(Many dictionaries are from Darkraver’s Dirb, www.open-labs.org)
Wfuzz Payloads Explained
Payloads are the generated list of data to be sent to the web server. Wfuzz is based on a simple concept: it replaces any reference (string) to the keyword ‘FUZZ’ by the value of a given payload. Essentially, a payload in Wfuzz is a source of input data. Wfuzz supports various payloads such as file, list, hexrand, range, names, and hexrange. The payload option is activated using the -z option.
- file: read entries from a file: an example is file, wordlist/general/commons.txt, which specifies all the entries that are contained in the chosen file.
- stdin: read entries from standard input
- list: generate entries from a list of objects: an example is a list,a-b-c, which specifies the three entries, the letters ‘a’, ‘b’ and ‘c’.
- hexrand: generate hexadecimal random objects
- range: generate a range of numbers: an example is a range,0-2, which specifies the three entries, the numbers 0,1,2.
- names: generates all possible combinations used in account naming patterns.
- hexrange: generate hexadecimal random objects
- permutation: performs a permutation of the given parameter
- To view all payloads that can be used, use “$ wfuzz -e payloads”
Wfuzz file Option
file: read entries from a file: an example is file, test_file.txt, which specifies all the entries that are contained in the chosen file. In the example below, we set ‘test_file.txt’ as the file source for wfuzz to use. The simple word lists contains only 9 strings and if you see below, one came back with status code 200, indicating the request was successful finding a directory with the ‘#’ string.
$ wfuzz -z file,test_file.txt http://192.168.1.1/FUZZ.php
Wfuzz stdin Option
stdin: reads the entries from standard input. The stdin payload could be used when using a external wordlist generator. In this example, we will be using the crunch command. Crunch is a wordlist generator where you can specify a standard character set or any set of characters to be used in generating the wordlists.
$ crunch 3 3 abc | wfuzz -z stdin http://192.168.1.1/FUZZ
Wfuzz list Option
list: generate entries from a list of objects: an example is a ‘list,a-b-c’, which specifies the three entries, the letters ‘a’, ‘b’ and ‘c’. In the example below, we know from the above file scan that the directory ‘#’ exist. For proof of theory with the list option, we will feed the command four words and one of them will include the ‘#’ character to show that the directory can also be found using the list option to verify. As you see in the example below, the words are separated using the dash ‘-‘ character.
$ wfuzz -z list,login-about-#-home http://192.168.1.1/FUZZ
Wfuzz hexrand Option
hexrand: generates a hexadecimal random object for each query. An example is hexrand,0-50, which query random hexadecimal random objects.
$ wfuzz -z hexrand,0-50 http://192.168.1.1/FUZZ
Wfuzz range Option
range: generate a range of numbers: an example is a range,0-5, which specifies the six entries, the numbers 0,1,2,3,4,5, and 6.
$ wfuzz -z range,0-5 http://192.168.1.1/FUZZ
Wfuzz Encoders Explained
Encoders are used to encode the payload in several ways, which is useful if the value in some parameter needs to be URL encoded, base64 encoded, or if the value should hold Unicode data, etc. Essentially, encoders convert information from one format to another. There are also hash functions like md5 and sha1, which can also be used to generate the hash representation of the payload. A useful feature is a multiple encoding of the same payload, which can be great if some data is the first base64 encoded and then only the md5 hash is needed or something like that.
To use an encoder, you need to place the selected encoder text in the third slot after the -z option in the query. The following example fuzzes the sha1 input, which accepts the sha1 of the user’s password in an insecure web application. We’re using the file passwords_file.txt as a payload, where the sha1 of each password (a password is specified in its own line) is computed and fed into the sha1 parameter.
$ wfuzz -z list,passwords_file.txt,sha1 <a href="http://192.168.1.1/index.php?d=FUZZ">http://192.168.1.1/index.php?sha1=FUZZ</a>
Wfuzz Available Encoders
|hashes||base64||Encodes the given string using base64.|
|url||doble_nibble_hex||Replaces ALL characters in string using the %%dd%dd escape.|
|url_safe, url||double_urlencode||Applies a double encode to special characters in string using the %25xx escape. Letters, digits, and the characters ‘_.-‘ are never quoted.|
|url||first_nibble_hex||Replaces ALL characters in string using the %%dd? escape.|
|default||hexlify||Every byte of data is converted into the corresponding 2-digit hex representation.|
|html||html_decimal||Replaces ALL characters in string using the &#dd; escape.|
|html||html_escape||Convert the characters &<>” in string to HTML-safe sequences.|
|html||html_hexadecimal||Replaces ALL characters in string using the &#xx; escape.|
|hashes||md5||Applies a md5 hash to the given string.|
|db||mssql_char||Converts ALL characters to MsSQL’s char(xx)|
|db||mysql_char||Converts ALL characters to MySQL’s char(xx)|
|default||none||Returns string without changes.|
|db||oracle_char||Converts ALL characters to Oracle’s char(xx)|
|default||random_upper||Replaces random characters in string with its capitals letters.|
|url||second_nibble_hex||Replaces ALL characters in string using the %?%dd escape.|
|hashes||sha1||Applies a sha1 hash to the given string.|
|hashes||sha256||Applies a sha256 hash to the given string.|
|hashes||sha512||Applies a sha512 hash to the given string.|
|url||uri_double_hex||Encodes ALL characters using the %25xx escape.|
|url||uri_hex||Encodes ALL characters using the %xx escape.|
|url||uri_triple_hex||Encodes ALL characters using the %25%xx%xx escape.|
|url||uri_unicode||Replaces ALL characters in string using the %u00xx escape.|
|url_safe, url||urlencode||Replaces special characters in string using the %xx escape. Letters, digits, and the characters ‘_.-‘ are never quoted.|
|url||utf8||Replaces ALL characters in string using the \u00xx escape.|
|url||utf8_binary||Replaces ALL characters in string using the \uxx escape.|
Wfuzz Iterators Explained
Wfuzz supports three iterator methods that can be used to iterate over payloads. To specify an iterator for combining payloads, you use the -m option in your command. The default for -m is product, which means if you do not specify zip or chain, it will automatically default to product.
product (default): combines the first and second payload lists to construct all possible combinations.
wfuzz -z list,a-b-c -z list,1-2-3 http://192.168.1.1/FUZZ/FUZ2Z
zip: takes the first value from the first payload list and combines it with a corresponding value in the second payload list.
wfuzz -z list,a-b-c -z list,1-2-3 -m zip http://192.168.1.1/FUZZ/FUZ2Z
chain: combines the first and second payload list to make a new bigger payload list.
wfuzz -z list,a-b-c -z list,1-2-3 -m chain http://192.168.1.1/FUZZ
Wfuzz Plugins Explained
Wfuzz’s web application vulnerability scanner is supported by various plugins. A list of scanning plugins can be obtained using the following command:
$ wfuzz -e scripts
There are categories of scripts which include:
- passive: Passive scripts analyze existing requests and responses without performing new requests.
- active: Active scripts perform new requests to the application to probe it for vulnerabilities.
- discovery: Discovery plugins help crawling a website by automatically enqueuing discovered content to wfuzz request’s pool.
|fuzzer, active||backups||Looks for known backup filenames.|
|info, passive, default||cookies||Looks for new cookies.|
|active, discovery||cvs_extractor||Parses CVS/Entries file.|
|default, passive, info||errors||Looks for error messages.|
|tools||grep||HTTP response grep.|
|info, passive, default||headers||Looks for HTTP headers.|
|active, discovery||links||Parses HTML looking for new content.|
|default, passive||listing||Looks for directory listing vulnerabilities.|
|info||npm_deps||Looks for npm dependencies definition in js code.|
|active, discovery||robots||Parses robots.txt looking for new content.|
|tools, active||screenshot||Performs a screen capture using linux cutycapt tool.|
|active, discovery||sitemap||Parses sitemap.xml file|
|active, discovery||svn_extractor||Parses .svn/entries file.|
|info, passivev||title||Parses HTML page title.|
|active, discovery||wc_extractor||Parses subversion’s wc.db file.|
Wfuzz Script Example
$ wfuzz --script=robots -z list,robots_list.txt http://192.168.1.1/FUZZ
Wfuzz Printers Explained
Wfuzz supports writing the results that it outputs to a file in a various format. This is performed by plugins called “printers”. To print the available printers, use:
$ wfuzz -e printers
Wfuzz Available Printers
|csv||CSV printer ftw.|
|field||Raw output format only showing the specified field expression. No header or footer.|
|html||Prints results in html format.|
|json||Results in json format.|
|magictree||Prints results in magictree format.|
|raw||Raw output format.|
If you want to show the results in a specific format, you have to use the -o option followed by one of the available printers as shown below:
$ wfuzz -o json list,common_passwords.txt http://192.168.1.1/FUZZ
Wfuzz Cheat Sheet
|–help||Help menu with all options.|
|–filter-help||Filter language specification.|
|–version||Displays version number installed.|
|-e <type>||List of the available encoders/payloads/iterators/printers/scripts|
|–recipe <filename>||Reads options from a recipe (pre-complied commands). Repeat for various recipes.|
|–dump-recipe <filename>||Prints current options as a recipe.|
|–oF <filename>||Saves fuzz results to a file. These can be consumed later using the wfuzz payload.|
|-c||Output with colors.|
|-f filename, printer||Store results in the output file using the specified printer (raw printer if omitted)|
|-o printer||Show results using the specified printer.|
|–interact||If selected, all key presses are captured. This allows you to interact with the program.|
|–dry-run||Print the results of applying the requests without actually making any HTTP requests.|
|–prev||Print the previous HTTP requests (only when using payloads generating fuzzresults).|
|efield <expr>||Show the specified language expression together with the current payload. Repeat for various fields.|
|field <expr>||Do not show the payload but only the specified language expression. Repeat for various fields.|
|-p addr||Use Proxy in format ip:port:type. Repeat option for using various proxies. Where type could be SOCKS4, SOCKS5 or HTTP if ommited.|
|-t N||Specify the number of concurrent connections (10 is default)|
|-s N||Specify time delay between requests (0 is default)|
|-R depth||Recursive path discovery being depth the maximum recursion level.|
|-D depth||Maximum link depth level.|
|-L, –follow||Follow HTTO redirections.|
|–ip host:port||Specify an IP to connect to instead of the URL’s host in the format ip:port.|
|-Z||Scan mode (connection errors will be ignored).|
|–req-delay N||Sets the maximum time in seconds the requests is allowed to allowed to take (CURLOPT_TIMEOUT). Default 90.|
|–conn-delay N||Sets the maximum time in seconds the connection phase to the server to take (CURLOPT_CONNECTTIMEOUT). DEFAULT 90.|
|-A, –AA, –AAA||Alias for -v -c and –script=default,verbose,discover respectively.|
|–no-cache||Disable plugins cache. Every request will be scanned.|
|–script=||Equivalent to –script=default|
|–script=<plugin>||Runs script’s scan. <plugin> is a comma separated list of plugin-files or plugin-categories.|
|–script-help=<plugins>||Show help about scripts.|
|–script-args n1=v1,…||Provides arguments to scripts. ie. –script-args grep.regex=”<A href=\”(.*?)\”>”|
|-u <url>||Specify a URL for the request.|
|-m <iterator>||Specify an iterator for combining payloads (product by default).|
|-z <payload>||Specify a payload for each FUZZ keyword used in the form of name[,parameter][,encoder]. A list of encoders can be used, ie. md5 or sha1. Encoders can be chained, ie. md5@sha1. Encoders category can be used. ie. url. Use help as a payload to show payload plugin’s details (you can filer using –slice)|
|–zP <params>||Arguments for the specified payload (it must be preceded by -z or -w).|
|–zD <default>||Default parameter for the specified payload (it must be proceeded by -z or -w).|
|–zE <encoder>||Encoder for the specified payload (it must be proceeded by -z or -w).|
|–slice <filter>||Filter payload’s elements using the specified expression. It must be preceded by -z.|
|-w wordlist||Specify a wordlist file (alias for -z file, wordlist.txt).|
|-V alltype||All parameters bruteforcing (allvars and allpost). No need for FUZZ keyword.|
|-X method||Specify an HTTP method for the request , ie. HEAD or FUZZ.|
|-b cookie||Specify a cookie for the requests. Repeat option for various cookies.|
|-d postdata||Use post data (ex: “id=FUZZ&catalogue=1”).|
|-H header||Use header (ex:”Cookie:id=12345&user=FUZZ”). Repeat option for various headers.|
|–basic/ntlm/digest auth||In format “user:pass” or “FUZZ:FUZZ” or “domain\FUZ2Z:FUZZ”|
|–hc/hl/hw/hh N[,N]+||Hide responses with the specified code/lines/words/chars (Use BBB for taking values from baseline).|
|–sc/sl/sw/sh N[,N]+||Show responses with the specified codes with the specified code/lines/words/chars (Use BBB for taking values from baseline).|
|–ss/hs regex||Show/hide responses with the specified regex within the content.|
|–filter <filter>||Show/hide reponses using the specified filter expression (Use BBB for taking values from baseline).|
|–prefilter <filter>||Filter items before fuzzing using the specified expression. Repeat for concatenating filters.|
The wfuzz help menu with all the advanced options can be found by using the –help option.
$ wfuzz --help
The wfuzz version number can be displayed with the –version option.
$ wfuzz --version
More command examples will be updated.
Wfuzz Pycurl is not compiled against Openssl?
UserWarning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
Pycurl comes preinstalled with the system but it is not preinstalled with OpenSSL.
Step 1: Uninstall python3-pycurl. (for Debian based systems)
sudo apt --purge remove python3-pycurl
Step 2: Install the required SSL dependencies for pycurl. If you are getting an error where the packages cannot be found, make sure you run sudo apt-get update first:
sudo apt-get update
sudo apt install libcurl4-openssl-dev libssl-dev
Step 3: Reinstall pycurl
sudo pip3 install pycurl wfuzz
Step 4: Reinstall wfuzz.
sudo apt install wfuzz