BY PAMELA O’SHEA, POSHEA [AT] RANDOMKEYSTROKES.COM
When performing a penetration test of an application, tests against the authentication mechanism are always an important check. While a standard authentication mechanism may be used, it can often be implemented incorrectly or misunderstood. For example, some applications may rely on client side data without any sanity checking or tokens may be predictable. In this blog post, we are going to focus on four key areas which should be examined when testing authentication:
- Forced Browsing
- Parameter Modification
- Session Identifier Prediction
- SQL Injection within Login Forms
First, we will walk through the environments used to demonstrate these issues. All environments are freely available for download as pre-packaged virtual machines and ready to go:
- OWASP Broken Web Applications Project (owaspbwa) including:
- Google Gruyere
As we walk through the examples, the following IP addresses will be referenced:
- OWASP Broken Web Application vmware player server: 172.16.43.128
- Badstore.net virtualbox server: 192.168.56.101
- Attacker’s box: 172.16.43.1
Familiarity with the Burp application proxy tool is also required (for an introduction, please refer to Google or SecurityTube) and your browser should be configured to proxy traffic through Burp.
A test account named “bugcrowd_tester” with a password of “pass123” will be used throughout this article. In preparation, these accounts should be created for each application as shown below.
Google Gruyere Application:
Issue 1: Forced Browsing
To begin, we are going to investigate the issue of forced browsing. This issue arises when it is possible to request a URL without the appropriate permission.
We will start with the Mutillidae application and check that our browser is configured to use Burp. Now we are ready to spider the mutillidae directory structure using burp as shown. Browse to the local Mutillidae web site in your browser. Once the traffic appears in Burp, right click on the site and choose to spider the site.
Once spidering has completed, particular attention should be paid to any directories which do not appear to be part of the public website structure or appear to be unintentionally disclosed. In this example, it is worth exploring the documentation folder to see if any information disclosure is made.
When exploring a site for the first time, it is always worth accessing common directory names. Through observation of the Mutillidae application and file extensions, we know that Mutillidae runs on PHP which often has shared code stored within an include directory. Here we see that there is an information disclosure within the “includes” directory which reveals PHP code to unauthenticated users.
It should be noted that automated tools such as “wfuzz” can be of great benefit when trying to enumerate a site’s directory structure. Wfuzz will use pre-built files with common directory structure names and record any successfully returned responses. This can be particularly useful when attempting to find exposed administrator interfaces.
Next, we are going to exploit weak identifiers to gain access to files without having to pay for the WackoPicko application. Begin by logging in as the “bugcrowd_tester” user and adding an image to our cart as shown. This function is intended to allow us to purchase higher quality versions of the image.
Before we confirm our purchase, we can see that the image will be made available through a special URL as shown.
If we look closely at the “picid” variable within the parameter, we notice that this is an easily guessable value for individual pictures. With this knowledge, we can now enumerate all the URLs and obtain higher quality images without having to pay.
In the following example, we simply increment the “picid” value by one to gain access to other higher quality images for sale!
Issue 2: Parameter Modification
Parameters are often used to control access to certain functionality or to segregate users of different privilege levels. The problem arises when the server blindly trusts the values of the user controlled client side values. Client side values should never be trusted. These values can be easily modified using Burp as we will see.
For this example, we are going to use the Google Gruyere Application. After logging in as “bugcrowd_tester”, we see two functions available to us: “Profile” and “Sign out” as shown in the screenshot.
In order to compare the available functionality, we will now login as an administrator (note: see the data.py script which lists existing accounts, one of which is a default administrator account with a username of “administrator” and a password of “secret”). As an administrator, we now have an additional function named “Manage My Server”.
Next, let’s take a look at the Administrator’s version of the edit “Profile” page, where we will see some additional radio buttons at the bottom of the form labeled as: “Is admin” and “Is author”. Next, we will have a peek at these using Burp to see their parameter names. To do this, submit the form and examine the request within Burp. Notice there is a flag named “is_admin” which is set to true. This flag is definitely worth testing further, so let’s make a note of it for now.
After exploring the higher privileges available to the administration account, we are going to log back in with our “bugcrowd_tester” account. This time we will try editing the “Profile” page again but include the “is_admin=true” parameter this time.
In order for any account changes to take affect we should log out and back in again. This time there is a noticeable difference with our “bugcrowd_tester” account, we now have access to the additional administration function “Manage this server”!
We can also see the new flags in our profile which indicate we now have elevated administrator privileges on our “bugcrowd_tester” account. Good news for us!
When writing up a penetration test report, this issue would typically be reported as a vertical privilege escalation (rather than an authentication bypass) as we have moved from a low level user to a higher privileged user. We have included it here for completeness as these issues can often be discovered when testing for authentication issues.
Issue 3: Session Identifier Prediction
Session identifiers are used to keep state within an application and to uniquely identify an authenticated user. As a result, it is important for session identifiers to be unpredictable in order to protect a user’s session. If a session identifier is weak and easy to predict, it will be possible to create a session and bypass authentication as we will see here.
Let’s start by logging into the WackoPicko Application as the administrator (username “admin” and password “admin”). After logging in, we can see that we have been assigned a simple session identifier as highlighted in the cookie variable “session” in the server response.
Now we will use burp to re-send the login request to the Sequencer in order to analyse the session identifiers returned within the responses. This will allow us to analyse the randomness of the session identifiers.
In the case of WackoPicko, the session identifiers just simply increment. For more complex session identifiers, we need to ensure a large enough sample size is analysed within Burp’s Sequencer. Here we have let the Sequencer run 1000 times so we have 1000 returned session identifiers to analyse.
We can see that Burp reports the overall result as being “extremely poor” which indicates the weakness of the simple session identifier. In order to use this knowledge to our advantage, we are going to use Burp Intruder. To do this, simply take the next request after the session identifier has been set by the server and send this to Burp Intruder to automate our attack as shown.
Inside the intruder, we will choose a sniper attack. All the default positions can be cleared as we are only interested in a single variable: “session”. We also do not need the “PHPSESSID” variable value as the “session” variable is enough to represent a valid session within the WackoPicko application.
Next, we set the payload details for the “session” variable. We are going to choose simple numbers which increment in steps of one. After selecting “Intruder->Start Attack” from the menu, we notice that all the results are returning a successful status of 200 and a successful login.
We have now successfully used the weak session identifiers to login as an administrator!
Issue 4: SQL Injection within Login Forms
If SQL injection is found to be present within a login form, it can often be used to bypass authentication completely. As we will see here, if we know a valid username, which can often be learned through information gathering or guessing, it is possible to login without a password.
For this example we are going to use the Badstore.net application. We will begin by performing the most basic test for SQL injection, entering a single quote into the login form. As shown, this resulted in a SQL error being reported.
Now that we have confirmed the login form is vulnerable to SQL injection, we can start to attack the authentication query. A good list of test strings is available from the Penetration Testing Lab blog (http://pentestlab.wordpress.com/2012/12/24/sql-injection-authentication-bypass-cheat-sheet).
We will save this list as a text file and use Burp Intruder to iterate through each test string as an input to the login form (Loading from a file requires the professional version of burp. If the professional version is not available, it is possible to load each test string individually into burp or to script the requests programmatically e.g. using python and curl).
Before we can start, we need to tailor the test string file. If we read the manual for Badstore we know that a valid username is “firstname.lastname@example.org” (a username is typically provided during penetration testing unless an unauthenticated penetration test is explicitly requested).
Valid usernames could also have previously been gathered during the information gathering phase. For example, valid names could have been gathered and inferred from:
- Whois database
- Spidering using burp/dirbuster
- Code comments containing developer names
- Any email addresses found throughout the site/html source
- Document metadata
- Varying responses within the login form (error messages or error codes etc.)
We are going to tailor the Penetration Testing Lab list to use our known username here. The file just requires a find/replace for the “admin” user with the “email@example.com” user as shown.
Now, we are ready to launch Burp’s Intruder and iterate over these strings, passing them to the login form. Let’s begin by submitting a login request and intercepting it with Burp.
Once intercepted by Burp, we can right click on the request and choose the “Send to Intruder” option as shown.
Within the Intruder tab, go to the Positions tab as shown and clear all the pre-selected variables. We are just going to vary the “email” variable (username) using the “Sniper” attack type.
Next, on the “Payloads” tab, we will select “Simple list” and “Load” our customised list.
Now we are ready to select Intruder->Start Attack from the menu. Once this has completed, we can check each response to see if a valid login was obtained. Sometimes this can be an obvious welcome message, however, in the case of the Badstore.net application it is the setting of a SSOid flag within the cookie as shown.
We can manually check the resulting strings (more than one was found to respond with an SSOid). For this example, we will use the highlighted string “firstname.lastname@example.org‘#”. Once entered into the login form, this will allow us to bypass the password field (as # represents a MySQL comment) and no password is required to login! .
Finally, we can verify the authentication bypass when we see that we have successfully authenticated and logged in.
In summary, authentication bypass is an important area to focus on during a penetration test. Bypasses can come in many forms and often arise due to poor implementations such as placing trust in client side data, utilising weak tokens or being careless with database queries and not using prepared statements.
Having worked through the examples here, you should now be ready to start exploring forced browsing, parameter modifications, session identifier prediction and SQL injections within login forms in more detail during your next penetration tests. Happy bug hunting!