WFuzz is a web application bruteforcer that can be considered an alternative to Burp Intruder as they both have some common features. With both Wfuzz and Burp Intruder we can bruteforce different web applications elements, like GET/POST parameters, cookies, forms, directories, files, HTTP headers, etc.

This simple concept allows any input to be injected in any field of an HTTP request, allowing to perform complex web security attacks in different web application components such as: parameters, authentication, forms, directories/files, headers, etc.

Wfuzz uses the keyword FUZZ to test a word list

http://10.10.10.150/FUZZ

http://10.10.10.150/FUZZ/FUZZ

http://10.10.10.150/FUZZ/FUZZ/FUZZ

https://github.com/xmendez/wfuzz

https://wfuzz.readthedocs.io/en/latest/index.html

You can use wfuzz to find some vulnerabilities:

  • Predictable credentials
  • Predictable sessions identifier (session idʼs)
  • Predictable resource location (directories and files)
  • Injections
  • Path traversals
  • Overflows
  • Cross site scripting
  • Authentication flaws
  • Insecure direct object references
Features:
  • 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

Basics

1. Displaying help

  • wfuzz --help

2. Display the settings

  • wfuzz --version

How to use

1. wfuzz looking for common directories:

  • wfuzz -w /usr/share/wordlists/dirb/big.txt http://10.10.10.150/FUZZ

Using -z, this is for payloads

  • wfuzz -c -z file,/usr/share/wordlists/dirb/small.txt http://10.10.10.150/FUZZ.php

2. wfuzz looking for common files, eg “.php”, this technique can be used to find any file with the extension you specify.

  • wfuzz -w /usr/share/wordlists/dirb/big.txt http://10.10.10.150/FUZZ.

To make this faster use -t option (Specify the number of concurrent connections default=10)

  • wfuzz -t 500 --hc=404 -w /usr/share/wordlists/dirb/small.txt http://10.10.10.150/FUZZ.php

3. Filtering the results parameter, hc=code/hl=lines/hw=words/hh =chars

  • wfuzz --hc=404 -w /usr/share/wordlists/dirb/small.txt http://10.10.10.150/FUZZ.php
    • --hc (filter the response)
    • -c (output with colors)
    • -w (wordlist)
    • FUZZ (keyword to be replaced by the word in wordlist)

In this case we got responses that were not 404

  • wfuzz --hc=404 --hl=0 -w /usr/share/wordlists/dirb/small.txt http://10.10.10.150/FUZZ.php

In this scenario we excluded 404 responses (--hc=404) and files that had 0 lines (--hl=0)

  • wfuzz --hc 286 -w /usr/share/wordlists/dirb/big.txt http://10.10.10.150/FUZZ

As in the first scan we made we got one of these lines

000000002: 404 9 L 32 W 286 Ch "!_archives"

In this case we are filtering 286 ch (--hc 286), that is not showing in the screenshot above

4. Filtering using --sc/sl/sw/sh code/lines/words/chars . This ones print the matching response, instead

  • wfuzz --sw 32 -w /usr/share/wordlists/dirb/small.txt http://10.10.10.150/FUZZ

This one prints only word listed as 32 W

  • wfuzz --sc 200,301 -w /usr/share/wordlists/dirb/small.txt http://10.10.10.150/FUZZ.php

This one prints only 200 & 301 responses

5. Fuzzing Parameters In URLs

You often want to fuzz some sort of data in the URL's query string, this can be achieved by specifying the FUZZ keyword in the URL after a question mark

  • wfuzz -w /usr/share/wordlists/dirb/small.txt "http://10.10.10.150/index.php/component/users/?view=login&Itemid=FUZZ"

--hc/hl/hw/hh hide responses with specified code/lines/words/chars,print responses with different value

This way you can get patterns filter those off and then look for changes in the responses.

5. Writing to a file, wfuzz provides different file formats

  • wfuzz -e printers # to show types of format (csv, html, json, etc.)

  • wfuzz -f /tmp/outfile.html,html --hc=404 -w /usr/share/wordlists/dirb/small.txt http://10.10.10.150/FUZZ.php

6. Proxies

If you need to use a proxy, simply use the -p parameter:

  • wfuzz --sc 200 -w /usr/share/wordlists/dirb/small.txt -p 127.0.0.1:8080 http://10.10.10.150/FUZZ.php

This way we can analyze the requests & responses in detail

Multiple proxies can be used simultaneously by supplying various -p parameters:

  • wfuzz --sc 200 -w /usr/share/wordlists/dirb/small.txt -p 127.0.0.1:8080 -p 127.0.0.1:8081 http://10.10.10.150/FUZZ.php

7. Inject into header: -H “content”

  • wfuzz --sc 200 -H 'Vry4n: vk9-sec.com' -w /usr/share/wordlists/dirb/small.txt -p 127.0.0.1:8080 http://10.10.10.150/FUZZ.php

Replacing exiting fields “User-Agent”. Previously it was “User-Agent: Wfuzz/2.4”, now it shows in BurpSuite as “User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0”

  • wfuzz --sc 200 -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0' -w /usr/share/wordlists/dirb/small.txt -p 127.0.0.1:8080 http://10.10.10.150/FUZZ.php

To fuzz user agent do the following https://developers.whatismybrowser.com/useragents/explore/

  • wfuzz --sc 200 -w user-agent.txt -H 'User-Agent: FUZZ' -w /usr/share/wordlists/dirb/small.txt -p 127.0.0.1:8080 http://10.10.10.150/FUZZ.php

User-Agent

For this one, I will use https://deviceatlas.com/blog/list-of-user-agent-strings which contains User-Agent demo for many device types.

I will use the following

Mac OS X-based computer using a Safari browser

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9

1. Run the -H option pointing to this user-agent.txt file and send output through proxy so you can capture responses and analyze them.

  • wfuzz --sc=200 -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9' -p 127.0.0.1:8080 -z range,149-151 http://10.10.10.FUZZ/index.php

Fuzzing the host info

  • wfuzz --sc 200 -w host_list.txt -H ‘Host: FUZZ.example.com' -w /usr/share/wordlists/dirb/small.txt -p 127.0.0.1:8080 http://10.10.10.150/index.php

8. Fuzzing HTTP Verb

HTTP verbs fuzzing can be specified using the -X switch, the -c is for fancy color view

  • wfuzz -c -w /usr/share/wordlists/dirb/small.txt -p 127.0.0.1:8080 -X POST http://10.10.10.150/FUZZ.php

Here you can see that the requests is via POST. The command below scans for a list of HTTP methods

  • wfuzz -z list,GET-HEAD-POST-TRACE-OPTIONS -X FUZZ http://10.10.10.150/

This one will use HEAD method

  • wfuzz -c -w /usr/share/wordlists/dirb/small.txt -p 127.0.0.1:8080 -X HEAD http://10.10.10.150/FUZZ.php

Here we can see HEAD method in use.

9. Using recursion

-R1 = enabling recursion depth 1, uses the same file, list over again

  • wfuzz --sc 200 -z file,/usr/share/wordlists/dirb/small.txt -R1 http://10.10.10.150/FUZZ

HTTP verbs:

  • POST
  • GET
  • PUT
  • PATCH
  • DELETE

Scaning using payloads

1. Using a range to scan for 200 OK

--sc 200 = only print 200 OK responses

-c = color the result response

-Z = ignore errors

-z range,1-254 = use payload range

  • wfuzz --sc 200 -c -Z -z range,1-254 http://10.10.10.FUZZ/index.php

  • wfuzz -e payloads

This prints the available payloads

2. Using multiple payloads, this time range and different file extensions

--sc 200 = only print 200 OK responses

-c = color the result response

-Z = ignore errors

-z range,1-254 = use payload range, first FUZZ

-z list,html-php-asp = use payload list, second FUZ2Z

  • wfuzz --sc 200 -c -Z -z range,1-254 -z list,html-php-asp http://10.10.10.FUZZ/index.FUZ2Z

Password Cracking

When the parameters are passed via URL which means GET method is in use. We can brute force those credentials.

Vertical scanning (different password for each user)

    • admin/test
    • guest/guest
    • user/1234x

Horizontal scanning (different usernames for common passwords)

  • wfuzz -z list,pass1-pass -z list,us1-us2 http://10.10.10.150/user=FUZ2Z&pass=FUZZ
    • admin/test
    • guest/test
    • user/test

Diagonal scanning (different username/password each round)

Three dimension (Horizontal, Vertical or Diagonal + Distributing source IP)

  • wfuzz -z list,pass1-pass -z list,us1-us2 -s 1 http://10.10.10.150/user=FUZ2Z&pass=FUZZ

Four dimensions (Horizontal, Vertical or Diagonal + Time Delay + Distributing Source IP)

  • wfuzz -z list,pass1-pass -z list,us1-us2 -s 1 -p ip:8080-ip2:8080-ip3:8088http://10.10.10.150/user=FUZ2Z&pass=FUZZ

https://www.owasp.org/index.php/Testing_for_Brute_Force_(OWASP-AT-004)

Using cookies

-b cookie=c0548020854924e0aecd05ed9f5b672b=mu4a0g5gjfnomflaugcinj5e98 = set value

  • wfuzz --sc 200 -p 127.0.0.1:8080 -b c0548020854924e0aecd05ed9f5b672b=mu4a0g5gjfnomflaugcinj5e98 -w /usr/share/wordlists/dirb/small.txt http://10.10.10.150/FUZZ

Bonus Trick

We will brute force a Joomla login page. We have captured the password (Curling2018!), but we don’t know the username.

1. Attempt to log in normally and capture that request

In this capture we can see the following

  • POST request
  • Cookie value
  • POST parameters (last line)

2. we will try to spoof that username with wfuzz

  • wfuzz --hc 200 -w userlist.txt -d 'username=FUZZ&passwd=Curling2018!&option=com_login&task=login&return=aW5kZXgucGhw&780f890e877f3d535b94247cbfc95939=1' -c -b 'c0548020854924e0aecd05ed9f5b672b=mu4a0g5gjfnomflaugcinj5e98; 99fb082d992a92668ce87e5540bd20fa=jnfqd4ip4cf940r24ugoour8dl' http://10.10.10.150/administrator/index.php

We omitted 200 OK responses, due to, all failed attempts responded with that. We got the username “Floris”, along with other responses we can test that out.

Username: Floris

Password: Curling2018!

We can see there the 303 response, a new cookie is set also.

Tip

When doing this, try to use the latest cookie, sometimes it can time out and the login is unsuccessful