Understand the Concept of Authentication
Before we talk about vulnerabilities, let’s briefly recap what authentication is. You should not confuse authentication with authorization, which we’ll look at in the next chapter.
Authentication is the process of verifying that someone is who they say they are. We use the term “authentication” when a secret factor, such as a password, is involved. Otherwise, we use the term “identification” instead.
Authorization is the process of verifying that someone has permission to do what they’re asking to do.
Okay, now it’s time for us to get down to business and test the authentication mechanisms!
When we look at the problems that can have an impact on authentication mechanisms, we typically refer to three different types:
Authentication bypass, where an attacker gains access to a resource without needing to be authenticated.
Credential guessing, where an attacker guesses a valid username and password.
Session theft, where an attacker uses a particular user’s valid session to gain access and perform actions under that user’s identity.
Bypass Authentication
I’m not going to spend too much time on authentication bypass because we’ve basically already seen this with injections. That said, what do you think happens when the login screen we’re testing has a SQL injection vulnerability?
This can result in an authentication bypass. We may also be able to retrieve the database with the password hashes, which we can then attempt to crack to obtain the password in plaintext.
Find a Password With Credential Guessing
We’re going to look at this technique in a little more detail because it’s often where the problems lie.
At what point do we consider authentication to be vulnerable or not robust enough?
It all depends on what information needs to be protected in the system. In addition, standards are constantly evolving. Today, a system that does not require multifactor authentication (i.e., at least two authentication factors) is considered too weak in certain situations.
But let’s get back to your question about the vulnerability of authentication. For a typical application, we would consider authentication to be not secure enough if:
it allows us (theoretically) to test an unlimited number of combinations of login credentials.
the password policy currently in place is weak or nonexistent.
That’s the theory, but it’s even better if you can prove that authentication is weak. Finding valid login credentials is the ultimate prize, especially if they’re for an administrator account!
To attack a login screen effectively, we need to:
not be locked out after repeated failed login attempts, either at the account level or at the attack IP address level (although IP address blocking can be bypassed with a little effort).
know the current password policy.
have a list of valid or likely logins.
have a list of likely passwords.
be able to automate the attack, which means having a suitable tool (or else we’ll have to be able to type very quickly).
To put all this into practice, we’ll take a step-by-step approach:
Determine whether any lockout mechanisms are triggered as a result of multiple failed authentication attempts.
Check how robust the password policy is.
Determine whether any valid user accounts exist.
Try to obtain the password.
Step 1: Determine Whether Any Lockout Mechanisms Exist
This is the first thing we check. Does the system temporarily or permanently lock the account used or any other component used in the attack, such as the IP address?
If your account is locked, it will probably be difficult to continue testing until it is unlocked, and this can take time—sometimes several hours.
This is why, when conducting a penetration test, we usually ask for two accounts with the same privilege level, to give them access to the same things in the application. This allows us to test authentication and determine whether there are any lockout mechanisms in place without shooting ourselves in the foot.
The second thing to check is the password policy.
Step 2: Check How Robust the Password Policy Is
Is there a password policy that requires, for example, passwords to be a certain length, include numbers and special characters, and contain a mixture of uppercase and lowercase characters? If there is, how robust is it?
After all, there’s no point in testing weak passwords if the password policy requires complex passwords with a minimum length of 10 characters and a mixture of numbers, uppercase and lowercase letters, and special characters. To check this, you can try resetting the password for one of the accounts provided to you, entering only a short, simple string of characters.
The third thing to check is whether we can determine the existence of any valid user accounts.
Step 3: Determine Whether Any Valid User Accounts Exist
You know that feature for users who forget their login details, where the login screen responds differently depending on whether the account exists or not? This is the feature that allows us, as attackers, to compile a list of valid logins (email address, username, or similar). Once we have this, we already know one of the two elements needed for authentication.
The fourth thing we need is the hardest to obtain because it’s supposed to be secret: the password.
Step 4: Try to Obtain the Password
It’s important to leverage all the data sources and information available to us:
You’ll need to test the default or simple passwords for each valid login you’ve identified. Repositories such as SecLists provide sample lists that you can use.
If you’ve identified logins that are email addresses or linked to email addresses, search leaked databases to see whether they include these email addresses and whether you can retrieve the associated passwords. Make sure you test these passwords and, if you cansee a pattern in the password, similar variations of them.
Next, if you have information about a specific target, there are tools like cupp that you can use to profile a target and create a list of likely passwords.
Lastly, you can test lists of leaked passwords, such as the well-known rockyou wordlist, which is available on SecLists. Alternatively, you could try brute-force authentication, but this tends to be of little or no use, given the slowness of “online” attacks.
I’ve just mentioned “online” attacks, which are distinct from “offline” attacks.
Offline attacks are infinitely faster than online attacks, as they involve no network transport time and the hardware used is often specifically designed to crack passwords.
There are lots of tools available for online attacks. I personally use ffuf, and that’s what I’d encourage you to do in the next challenge.
But first, let me show you how in this video:
Over to You!
Challenge
Before we move on to our application, let’s practice how to test the robustness of authentication with a little challenge.
Can you solve the Weak Password challenge?
Solution
As I’m sure you’re getting used to by now, we’re not giving you the exact answer, but the video demonstration above should help.
So, there’s no clear-cut solution, but here’s a hint: You’ll need to remember that we need to include certain options so that Root Me doesn’t block our tools! For ffuf, these options are:
-t 7 -rate 70 -H "User-Agent: Firefox"
Hijack User Sessions and Cookies
Cookies are one way of keeping sessions open and remaining authenticated in web applications. If an attacker steals your session cookie, they don’t need to bother trying to find your password—they’ll have access to the application in the same way as if they’d found it themselves!
Broadly speaking, an attacker can:
forge a cookie.
steal a cookie.
use a cookie without your knowledge, as part of Cross-Site Request Forgery (CSRF) attacks.
A Forged Cookie
An attacker can forge a cookie if they manage to work out how the application creates the cookie. This rarely happens these days, as all development languages provide the session persistence layer, and it no longer needs to be implemented. This greatly reduces errors. But every now and then, you’ll come across a cookie that’s a little out of the ordinary, and you’ll want to take a closer look!
A Stolen Cookie
A cookie has attributes known as flags, including the secure and HttpOnly flags. Without these flags, an attacker may be able to steal a legitimate user’s cookie by using XSS if the HttpOnly flag is not set or by intercepting unencrypted data flows if the secure flag is not set.
A Cookie Used Without Your Knowledge
CSRF attacks take advantage of how cookies work. The way these attacks work is a little complicated, so I’ll try to explain them as clearly as possible:
First, these attacks only apply to requests that modify content or have an impact on the application.
Second, they are based on the “normal” way in which cookies work, which is important to keep in mind. So, let’s briefly review how cookies work.
Cookies allow a user’s session to persist and are stored in small text files on the user’s computer. The browser automatically sends them to the website when the user visits the website they belong to. This is how browsers normally handle cookies.
Now let’s get back to the principle of CSRF attacks. They involve:
“forging” a request (creating a valid request with all the relevant elements).
using this mechanism to trick a user into performing actions without their knowledge.
Let’s look at an example. The example.com application we’re testing allows a user to:
change their password.
make this password change without entering their old password or any other parameter that an attacker cannot predict.
The most important point here is that the attacker must be able to predict all the parameters required by the request. They can then forge the request and make the victim execute it.
If the application is not protected against CSRF attacks, all the attacker has to do is get the victim to send the forged request to the web server.
For example, the attacker may send a link containing all the necessary parameters to the victim, who then clicks on it to execute the request and trigger the attack! The attacker may also insert requests in <img>
tags so that they are automatically executed when the browser wants to display what it mistakenly thinks is an image. In this case, the inserted request would change the user’s password.
Let’s Recap!
Authentication is the process of ensuring that someone is who they say they are. On web applications, this means asking users for secret information that usually only they know, such as the username-password combination.
Authentication is essential for most web applications. Errors or omissions sometimes creep into these authentication processes. This may give an attacker access to the authenticated part of the application.
The login screen may, for example:
have a SQL injection vulnerability in the code, enabling attackers to bypass authentication.
not be protected against dictionary or brute-force attacks.
accept valid test or default login credentials.
Cookies, which allow a user’s session to persist (i.e., stay open), are another aspect of security to keep an eye on, especially their secure and HttpOnly flags.
In the next chapter, we’ll be tackling the problems associated with concepts that go hand in hand with authentication: authorization and access control!