Authentication Vulnerability

Dictionary Attack

The very obvious method of attacking any login form is just to brute force the credentials. But in this kind of brute force, we don't simply try numbers or simple alphabets. What we do is take an existing dictionary of commonly used username/passwords and use those to see if we can find the right combination. This is known as Dictionary Attack.

To perform a dictionary attack we can use a lot of tools like Hydra or Medusa but the issue with these CLI tools is that we need to provide a lot of arguments to them started and that could be confusing. That is why when trying a dictionary attack on a web application/form it's better to use Burp Suite. In Burp we can capture the login request and then use intruder to perform the attack.


Re-Registration

A lot of times what happens is that developer forgets to sanitize the input(username & password) given by the user in the code of their application which can make them vulnerable to things like SQL injection but SQLi could be a bit difficult to exploit. So we are going to focus on a vulnerability that happens because of a developer's mistake but is very easy to exploit i.e re-registration of an existing user.

say there is an existing user with the name admin and now we want to get access to their account so what we can do is try to re-register that username but with slight modification. We are going to enter " admin"(notice the space in the starting). Now when you enter that in the username field and enter other required information like email id or password and submit that data. It will actually register a new user but that user will have the same right as normal admin. And that new user will also be able to see all the content present under the user admin.


JSON Web Tokens

JSON Web Token(JWT) is one of the commonly used methods for authorization. This is a kind of cookie that is generated using HMAC hashing or public/private keys. So unlike any other kind of cookie, it lets the website know what kind of access the currently logged in user has. The only special thing about JWT is that they are in JSON format(after decoding).

JWT can be divided into 3 parts separated by a dot(.)

  1. Header: This consists of the algorithm used and the type of the token.

    • { "alg": "HS256", "typ": "JWT"}

    • alg could be HMAC, RSA, SHA256 or can even contain None value.

  2. Payload: This is part that contains the access given to the certain user etc. This can vary from website to website, some can just have a simple username and some ID and others could have a lot of other details.

  3. Signature: This is the part that is used to make sure that the integrity of the data was maintained while transferring it from a user's computer to the server and back. This is encrypted with whatever algorithm or alg that was passed in the header's value. And this can only be decrypted with a predefined secret(which should be difficult to)

Now to put all the 3 part together we base64 encode all of them separated by a dot(.) so it would look something like:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

More Info Here jwt.io Payloads Here

None Manual Exploitation

The None algorithm is used when you still want to use JWT, however there is other security in place to stop people from spoofing data.

If you remember, in the Header section I said that the alg can be whatever the algorithm is used and also it can be None if no encryption is to be used. Now, this should not be used when the application is in production but again the problem of misconfiguration comes in and make the application vulnerable to this kind of attack. The attack is that an attacker can log in as low privilege user says guest and then get the JWT token for that user and then decode the token and edit the headers to use set alg value to None. This would mean that no encryption has to be used therefore the attacker wouldn't need to the secret used for encryption.

None Automatic Exploitation

There is no tool that can check the library, get the token, and make sure this is vulnerable. Therefore, you're gonna have to do this manually. The header for each JWT none vuln though is the same, which can help you out. Here's the header eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0 Which decodes to {"type": "JWT", "alg": "none"}

HHS256 Manual Exploitation

  1. We start off with a basic application

  2. We find and decode its JWT

    • use jwt.io

  3. Decoding the JWT gives us our header, payload, and a bunch of garbage which is the secret.

  4. It seems the algorithm is RS256, which doesn't have any vulnerabilities. Fortunately for us though, this server leaves its public key lying around, which means we can change the algorithm and sign a new secret! The first step is to change the algorithm in the header to HS256, and then re encode it in base64 hence generating our new JWT.

    • use jwt.io

  5. The next step is to convert the public key to hex so openssl will use it.

    • cat publickey | xxd -p | tr -d "\\n"

    • publickey is the file with the public key

    • xxd -p turns the contents of a file to hex

    • tr is there to get rid of any newlines

  6. The next step is to use openssl to sign that as a valid HS256 key.

    • echo -n "file" | openssl dgst -sha256 -mac HMAC -macopt hexkey:

    • where -n text is the rencoded file header plus previous payload without the signature part

    • where value of hexkey is the one generated above

  7. The final step is to decode that hex to binary data, and reencode it in base64, luckily python makes this really easy for us.

    • python -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('hexval')).replace('=','')\")"

    • where hexval is the value we go from step 6

  8. That's our final secret, now we just put that where the secret should go, and the server should accept it.

  9. Hence our final JWT will be calculated

HHS256 Automatic Exploitation

Due to the fact that JWT tokens often expire, there's no real way to guarantee that finding the public key is possible, and that there is no way to keep the data portion of the JWT consistent, there aren't tools avaliable that automatically exploit JWT vulnerabilities. JWT vulns have to be exploited on a case by case basis.

Now that doesn't mean you can't write a script that does everything automatically for a specific website that you know is vulnerable, it's just that by the time you succeed in doing that, you could have already exploited the vulnerability.

Bruteforce JWT

Recall that JWT HS256 is calculated using a secret.The exact format of the calculation is HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) Therefore, it stands to reason that, since we have the full jwt token, and the header and payload, the secret can be brute forced to obtain the full JWT token. If the secret can be brute forced then the attacker could sign his own JWT tokens.

To brute force these secrets we'll be using a tool called jwt-cracker. The syntax of jwt-cracker is jwt-cracker <token> [alphabet] [max-length] where alphabet and max-length are optional parameters.

Explanation of Paramaters:

  1. Token : The HS256 JWT token

  2. Alphabet : The alphabet that the cracker will use to check passwords(default: "abcdefghijklmnopqrstuvwxyz")

  3. max-length : The max expected length of the secret(12 by default)


No Auth

A lot of time on websites we see that when we register a user and login with our credentials we are given a certain id which either is completely a number or ends with a number. Most of the time developers secures their application but sometime in some places, it could happen that just by changing that number we are able to see some hidden or private data.

For instance,

As you can see in the image above the URL have /users/1. Try to change that value to 2 and we will get access to another user account

The chance of finding this kind of vulnerability is very low but it could be a very serious bug if you get lucky and found something like this.


Last updated