HTB Academy: Attacking Web Applications With ffuf Skills Assessment Walkthrough

Hack The Box’s ffuf skills assessment tests your ability to take what you’ve learned so far in this module and apply it to a final exercise. This blog post walks you through the steps to completing the final exercise and assumes that you have already completed the previous sections of this module.

Tools and Techniques

  • HTB Pwnbox (Parrot OS)
  • ffuf
  • SecLists


Start off by spawning your target instance and inputting its corresponding domain in /etc/hosts. Add the following line to /etc/hosts and change IP_ADDR to the IP address of your target. Do not include the port number.

IP_ADDR academy.htb

First Question

“Run a sub-domain/vhost fuzzing scan on ‘*.academy.htb’ for the IP shown above. What are all the sub-domains you can identify? (Only write the sub-domain name, separated by spaces in alphabetical order ‘subdomain1 subdomain2 subdomain3’)”

To solve the first question, you need to understand the two commands for subdomain fuzzing and vhost fuzzing.

The command for subdomain scanning in this case is as follows:

ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u

Subdomain fuzz returns all errors

Note that if you run just a subdomain scan, ffuf may return errors. If you’ve confirmed that your command does not have any typos, then the next step is to try to run a vhost scan. Subdomains on a particular host may not be accessible publicly, at which point a vhost scan becomes necessary to sniff out domains that are not registered publicly.

The command for a vhost scan is as follows:

ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:PORT/ -H 'Host:'

Clutter due to lack of filter

It is not enough to just run the vhost fuzz alone, as it will inevitably result in a lot of clutter in the output. To clean up the output, filter out the results which are decidedly not needed. In this case, it is all of the requests that returned a response of size 985. To filter these, add -fs 985 to the end of the previous command, which can be read as “filter size 985”:

ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:PORT/ -H 'Host:' -fs 985

Results for first question

Now that you have discovered other vhosts under this IP address, add them to /etc/hosts to easily reference them in the next questions.

Second question

“Before you run your page fuzzing scan, you should first run an extension fuzzing scan. What are the different extensions accepted by the domains? (Write the extensions as ‘.ext’, in alphabetical order separated by spaces ‘.ext1 .ext2 .ext3’)”

To discover which extensions the target accepts, run the following command for extension fuzzing:

ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://academy.htb:PORT/indexFUZZ

Which returns the following result:

Partial second solution

You will notice that just inputting those two extensions as the answer will not work. So far, an extension fuzz was only performed on the original target academy.htb. Now, try it on the other ones which were uncovered while answering the first question:

ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u

In the end, you should get three distinct PHP extensions.

Third Question

“One of the pages you will identify should say ‘You don’t have access!’. What is the full page URL?”

When you are trying to find out if a particular page has a certain string of text, but you do not know the location of the page, it could be pretty much anywhere on the target. A search this complex requires a recursive page fuzz. It’s a recursive fuzz because the exact location of the page is unknown, and it is a page fuzz because the question is asking about a particular “page”.

For this particular step, find something to do in the mean time for at least 5 minutes, as recursive scans can be time-consuming, even with increased threads. Furthermore, to find the exact location of the page, you will need to perform a recursive scan on each subdomain you discovered, and with each of the extensions you’ve found.

The format of the command for a recursive fuzz is as follows:

ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://academy.htb:PORT/FUZZ -recursion -recursion-depth 1 -e .php -v -t 80

Do the same with the other extensions and the other subdomains, and you should eventually get an interesting result with During the subdomain’s recursive fuzz, was discovered, so ffuf added a job to the queue to search for pages within the courses/ subdirectory.

New job added to queue as a result of courses/ discovery

Later, as it searches within that subdirectory, it stumbles upon a page:

ffuf discovers linux-security.php while fuzzing the courses subdirectory

The index.php7 page can be ignored since it is size 0, meaning there is no text there. The linux-security.php7 page, on the other hand, looks interesting. It is of size 774 and so far is the only non-zero size page discovered in the fuzz aside from the target’s homepage. Running a curl of the page from the Terminal returns the following text:

‘You don’t have access!’

Fourth Question

You may have noticed at this point that each subsequent question is a progression of the previous one. This is particularly true of this one, which expects you to find out which parameters the php7 page from the previous question accepts.

To accomplish this, perform a parameter fuzz on the page:

ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded'

Next, add a filter at the end of the command. In this particular case, the filter size is 774:

ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs 774

This command results in the output of the parameters user and username.

Final Question

The final question requires a value fuzz. Since the two parameters discovered in the previous two questions are related to user credentials, this question requires a little creativity. Essentially, you must find a wordlist that may be useful for bruteforcing usernames. SecLists provides a handful of good ones in its Usernames subdirectory. For academic exercises like this, start off with a short wordlist to avoid unnecessary time consumption. If that does not work, progress to a larger wordlist. You should be able to crack this one via the following two commands in sequence:

ffuf -w /opt/useful/SecLists/Usernames/xato-net-10-million-usernames.txt:FUZZ -u -X POST -d 'username=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded'

…which shows that the content length to filter by is 781, hence:

ffuf -w /opt/useful/SecLists/Usernames/xato-net-10-million-usernames.txt:FUZZ -u -X POST -d 'username=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 781
Charles Varga
Charles Varga
Cybersecurity Analyst at Florida Department of Financial Services

I am a cybersecurity professional working for the State of Florida and attending Pace University. My career interests include incident response, cybersecurity automation, pen testing, red teaming, and malware analysis.