Ffuf
Introduction
Fuzzing is a testing technique that sends various types of user input to an interface to study how it reacts. For web fuzzing, we usually use predefined wordlists of commonly used terms to see if a web server accepts them. This is because web servers do not typically provide a directory of all available links and domains (unless very poorly configured), so we must try various links to see which ones return pages.
Wordlists
To determine which pages exist, you should have a wordlist containing commonly used words for web directories and pages. Although this method will not reveal all pages on a website (since some pages may be randomly or uniquely named), it generally returns the majority of pages.
Fortunately, you don't have to create these wordlists manually. Many efforts have already been made to search the web and compile the most commonly used words for each type of fuzzing. Some of the most popular wordlists can be found in the GitHub SecLists repository, which categorizes wordlists by fuzzing type.
In Kali Linux, the SecLists can be found in
/usr/share/seclists/
Directory/Page:
SecLists/Discovery/Web-Content/directory-list-2.3-small.txt
Extensions Wordlist:
SecLists/Discovery/Web-Content/web-extensions.txt
Domain Wordlist:
SecLists/Discovery/DNS/subdomains-top1million-5000.txt
Parameters Wordlist:
SecLists/Discovery/Web-Content/burp-parameter-names.txt
Note: Some wordlists include copyright comments at the beginning. These comments can be considered part of the wordlist and may clutter the results.
DNS Records
Some websites are not public and can only be accessed within a local network. Browsers understand how to connect to IP addresses; when you provide a URL, the browser tries to map it to an IP by looking into the local
/etc/hosts
file and then the public DNS Domain Name System. If the URL is not found in either, the browser will not know how to connect.To connect to an internal website (e.g.,
internal.academy.htb
), you need to add it to your/etc/hosts
file. (sudo sh -c 'echo "Server IP Address> <Domain Name>" >> /etc/hosts'
)
How to Install
To install Ffuf, you can either use "
apt install ffuf -y
" or download it from its GitHub Repo.
Basic Fuzzing
The main two options are,
-w
for wordlists and-u
for the URL.You can assign a wordlist to a keyword in your URL by appending
:FUZZ
to the wordlist path. This is useful if you want to use two wordlists and assign a unique keyword for each (by default, the keyword isFUZZ
).Example:
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://<Server-IP-Address>:<Port-Number>:/FUZZ
Fuzzing speed may vary based on your internet speed and ping. You can increase the number of threads (e.g., with
-t 200
) to make it faster, but this is not recommended on remote sites as it may disrupt service or even cause a denial of service.
Directory Fuzzing
For directory fuzzing, place the
FUZZ
keyword where the directory appears in your URL. Example:ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://<Server-IP-Address>:<Port-Number>/FUZZ
Extension Fuzzing
Before fuzzing pages for extensions, you need to determine what type of pages the website uses (e.g.,
.html
,.aspx
,.php
, etc.). One common method is to examine the HTTP response headers to guess the server type and its common file extensions.Once you know the likely extension, specify it at the end of your file. You can use two wordlists with unique keywords if needed. A common approach is to fuzz the file
index.*
to see which extensions are accepted.Example 1 (Fuzzing for extension on a file):
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://<Server-IP-Address>:<Port Number>/blog/indexFUZZ
Example 2 (Fuzzing a directory with a known extension):
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://<Server-IP-Address>:<Port Number>/blog/FUZZ.php
The wordlist might or might not contain a dot (.), It's important to know before fuzzing to determine if we need to add the dot (.) ourselves or not.
Recursive Fuzzing
Recursive fuzzing automatically starts a new scan within any newly discovered directories until the entire site and its subdirectories have been fuzzed. Note that some websites have deep directory trees (e.g.,
/login/user/content/uploads/...
), which may result in very long scans. It is advised to set a maximum recursion depth.In ffuf, enable recursive scanning with the
-recursion
flag and set the depth with the-recursion-depth
flag. You can also specify the file extension with-e
and use-v
to output full URLs for clarity.Example:
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://Server-IP-Address>:<Port-Number>/FUZZ -recursion -recursion-depth 1 -e .php -v
Domain Fuzzing
Subdomains Fuzzing
A subdomain is a domain that is part of a larger domain. For example,
https://photos.google.com
is the photos subdomain ofgoogle.com
.If a domain isn’t identifiable by public DNS, you need to add its subdomains to your
/etc/hosts
file. In these cases, use the virtual host (-vhost
) scanning option.In the SecLists repository, there is a specific section for subdomain wordlists, usually located in:
/opt/useful/SecLists/Discovery/DNS/
Example:
ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u https://FUZZ.<Domain-Name>/
Example:
ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://FUZZ.<Domain-Name>/
Vhost Fuzzing
When fuzzing subdomains that do not have a public DNS record or websites that are not public, use Vhost fuzzing. A VHost (virtual host) is essentially a subdomain served on the same server with the same IP address. A single IP can host multiple websites (VHosts), which may or may not have public DNS records.
To scan for VHosts without manually adding entries to your
/etc/hosts
file, you can fuzz HTTP headers—specifically theHost:
header—using the-H
flag with theFUZZ
keyword.
In Vhost fuzzing, many entries may return a 200 OK status because you are merely changing the header on the same IP. However, if a VHost exists, the response size may differ. You may need to filter your results accordingly.
Filtering Results
By default, ffuf filters results based on HTTP status codes, typically removing 404 NOT FOUND responses. You can also filter or match based on response size, line count, word count, or using regular expressions.
Filtering Options:
-fc
: Filter out specific HTTP status codes (comma-separated list of codes and ranges)-fl
: Filter by the number of lines in the response (comma-separated list of counts and ranges)-fr
: Filter by a regular expression-fs
: Filter by HTTP response size (comma-separated list of sizes and ranges)-fw
: Filter by the number of words in the response (comma-separated list of counts and ranges)
For example, to filter out responses with a size of 900 bytes:
ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://<Domain-Name>:<Port-Number>/ -H 'Host: FUZZ.<Domain-Name>' -fs 900
Parameter Fuzzing
Fuzzing parameters may reveal unpublished parameters that are publicly accessible. Such parameters are often less tested and less secure.
GET Request Fuzzing
In GET requests, parameters are usually appended to the URL. For example:
http://admin.academy.htb:PORT/admin/admin.php?param1=key
So, all we have to do is replace param1 in the example above with
FUZZ
and rerun our scan.Example:
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://<Domain-Name>:<Port-Number>/admin/admin.php?FUZZ=key
POST Request Fuzzing
Unlike GET requests, POST request parameters are sent in the data field of the HTTP request. To fuzz POST data with ffuf, use the
-d
flag and add-X POST
to specify the request method. Also, set the appropriateContent-Type
header (commonlyapplication/x-www-form-urlencoded
for PHP).Example:
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://admin.academy.htb:PORT/admin/admin.php -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded'
Value Fuzzing
After identifying a working parameter, you may need to fuzz its value to determine acceptable inputs. Often, a pre-made wordlist may not exist for specific parameters. For common parameters like usernames, you might find a suitable wordlist or create one based on expected values. The command will differ depending on whether the parameter is sent via GET or POST.
Example:
ffuf -w ids.txt:FUZZ -u http://admin.academy.htb:PORT/admin/admin.php -X POST -d 'id=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded'
Last updated