Ffuf
Introduction
The term fuzzing refers to a testing technique that sends various types of user input to a certain interface to study how it would react.
We usually utilize pre-defined wordlists of commonly used terms for each type of test for web fuzzing to see if the webserver would accept them.
This is done because web servers do not usually provide a directory of all available links and domains (unless terribly configured), and so we would have to check for various links and see which ones return pages.
Wordlists
To determine which pages exist, we should have a wordlist containing commonly used words for web directories and pages.
Though this will not reveal all pages under a specific website, as some pages are randomly named or use unique names, in general, this returns the majority of pages.
We will not have to reinvent the wheel by manually creating these wordlists, as great efforts have been made to search the web and determine the most commonly used words for each type of fuzzing.
Some of the most commonly used wordlists can be found under the GitHub SecLists repository, which categorizes wordlists under various types of fuzzing.
In Kali Linux, the SecLists can be found in
/usr/share/seclists/
Taking a look at these wordlists we will notice that it contains copyright comments at the beginning, which can be considered as part of the wordlist and clutter the results.
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
DNS Records
Some websites are not public websites that can be accessed by anyone but local websites within the network.
Browsers only understand how to go to IPs, and if we provide them with a URL, they try to map the URL to an IP by looking into the local /etc/hosts file and the public DNS Domain Name System.
If the URL is not in either, it would not know how to connect to it.
So, to connect to an internal website (i.e.
academy.htb
), we would have to add it to our/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 and use it from its GitHub Repo.
Basic Fuzzing
The main two options are
-w
for wordlists and-u
for the URL.We can assign a wordlist to a keyword to refer to it where we want to fuzz. For example, we can pick our wordlist and assign the keyword
FUZZ
to it by adding:FUZZ
after it. This can be useful when we want to use two wordlists and have a unique keyword for each (By default, the keyword is FUZZ).Example:
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ
Fuzzing speed may vary depending on your internet speed and ping, but it should still be extremely fast.
We can even make it go faster if we are in a hurry by increasing the number of threads to 200, for example, with
-t 200
, but this is not recommended, especially when used on a remote site, as it may disrupt it, and cause a Denial of Service, or bring down your internet connection in severe cases.
Directory Fuzzing
If we want to be fuzzing for web directories, we can place the FUZZ keyword where the directory would be within our URL. (
http://<Server IP Address>:<Port Number>/FUZZ)
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 we start fuzzing the pages, we must find out what types of pages the website uses, like
.html
,.aspx
,.php
, or something else.One common way to identify that is by finding the server type through the HTTP response headers and guessing the extension. For example, if the server is apache, then it may be
.php
, or if it was IIS, then it could be.asp
or.aspx
, and so on.Before we start fuzzing, we must specify which file that extension would be at the end of! We can always use two wordlists and have a unique keyword for each, and then do
FUZZ_1.FUZZ_2
to fuzz for both. However, there is one file we can always find in most websites, which isindex.*
, so we will use it as our file and fuzz extensions on it.
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.
Example:
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://<Server IP Address>:<Port Number>/blog/indexFUZZ
After we know what extension the website uses, we are going to start fuzzing the pages of the website using this extension.
Example:
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
Recursive Fuzzing
When we scan recursively, it automatically starts another scan under any newly identified directories that may have on their pages until it has fuzzed the main website and all of its subdirectories.
Some websites may have a big tree of sub-directories, like
/login/user/content/uploads/...etc
, and this will expand the scanning tree and may take a very long time to scan them all. This is why it is always advised to specify a depth to our recursive scan, such that it will not scan directories that are deeper than that depth.In ffuf, we can enable recursive scanning with the
-recursion
flag, and we can specify the depth with the-recursion-depth
flag.When using recursion in ffuf, we can specify our extension with
-e <.File Extension>
Finally, we will also add the flag
-v
to output the full URLs. Otherwise, it may be difficult to tell which file lies under which directory.Example:
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://SERVER_IP:PORT/FUZZ -recursion -recursion-depth 1 -e .php -v
Domain Fuzzing
Subdomains Fuzzing
A sub-domain is any website underlying another domain. For example,
https://photos.google.com
is thephotos
sub-domain ofgoogle.com
.Remember that if a domain isn't identifiable by the DNS then we also need to add its subdomains to the
/etc/hosts/
file for them to be identifiable in this case we use the-vhost
scanning option.In the SecLists repo, there is a specific section for sub-domain wordlists, consisting of common words usually used for sub-domains. We can find it in
/opt/useful/SecLists/Discovery/DNS/
Example:
ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u https://FUZZ.inlanefreight.com/
Example:
ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://FUZZ.academy.htb/
Vhost Fuzzing
When it came to fuzzing sub-domains that do not have a public DNS record or sub-domains under websites that are not public, we could not use the same method used for normal subdomains scanning. We have use Vhost fuzzing.
Vhosts vs. Sub-domains
The key difference between VHosts and sub-domains is that a VHost is basically a 'sub-domain' served on the same server and has the same IP, such that a single IP could be serving two or more different websites.
VHosts may or may not have public DNS records.
This is where we utilize VHosts Fuzzing on an IP we already have. We will run a scan and test for scans on the same IP, and then we will be able to identify both public and non-public sub-domains and VHosts.
To scan for VHosts, without manually adding the entire wordlist to our
/etc/hosts
, we will be fuzzing HTTP headers, specifically theHost:
header. To do that, we can use the-H
flag to specify a header and will use theFUZZ
keyword within it.Example:
ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:PORT/ -H 'Host: FUZZ.academy.htb'
Note that all words in the wordlist are returning
200 OK
! This is expected, as we are simply changing the header while visitinghttp://academy.htb:PORT/
. So, we know that we will always get200 OK
. However, if the VHost does exist and we send a correct one in the header, we should get a different response size, as in that case, we would be getting the page from that VHosts, which is likely to show a different page. This is where we might need to filter our results.
Filtering Results
The results are automatically filtered by default by their HTTP code, which filters out code
404 NOT FOUND
, and keeps the rest.Ffuf provides the option to match or filter out a specific HTTP code, response size, or amount of words.
Filtering Options:
-fc
Filter HTTP status codes from response. Comma separated list of codes and ranges-fl
Filter by amount of lines in response. Comma separated list of line counts and ranges-fr
Filter regexp -fs Filter HTTP response size. Comma separated list of sizes and ranges-fw
Filter by amount of words in response. Comma separated list of word counts and ranges
Let's take the VHost example where all the results are
200 OK
but the difference should be noticed in the response size in this case we can use:ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:PORT/ -H 'Host: FUZZ.academy.htb' -fs 900
Parameter Fuzzing
Fuzzing parameters may expose unpublished parameters that are publicly accessible. Such parameters tend to be less tested and less secured.
GET Request Fuzzing
In
GET
requests, the parameter is usually added to the end of 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://admin.academy.htb:PORT/admin/admin.php?FUZZ=key
POST Request Fuzzing
The main difference between
POST
requests andGET
requests is that POST requests are not passed with the URL and cannot simply be appended after a?
symbol.POST requests are passed in the data field within the HTTP request.
To fuzz the data field with ffuf, we can use the
-d
flag. We also have to add-X POST
to sendPOST
requests.We also have to consider the
content-type
. For example, in PHP, "POST
" data "content-type
" can only accept "application/x-www-form-urlencoded
". So, we can set that in "ffuf" with "-H 'Content-Type: application/x-www-form-urlencoded'
"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 fuzzing a working parameter, we now have to fuzz the correct value.
When it comes to fuzzing parameter values, we may not always find a pre-made wordlist that would work for us, as each parameter would expect a certain type of value.
For some parameters, like usernames, we can find a pre-made wordlist for potential usernames, or we may create our own based on users that may potentially be using the website. In other cases, like custom parameters, we may have to develop our own wordlist.
Depending on whether the it's a GET or POST parameter, the command will change.
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