4.7.1 Tester le système de management des sessions (OTG-SESS-001)

Summary
Pour éviter que l'utilisateur ait à se ré-authentifier sur chaque page d'un site web ou d'un service, les applications web implémentent des mécanismes pour stocker et valider les crédentiels, et ce, pour un temps donné. Ces mécanismes sont connus sous le nom de management ou gestion de sessions. Bien qu'ils soient important pour améliorer l'expérience utilisateur, ils peuvent être exploités par un testeur d'intrusion pour accéder à un compte utilisateur, sans avoir besoin de donner les crédentiels nécessaires.

Dans ce test, le testeur va vérifier que les cookies et autres jetons de session sont créés de manière sûre et aléatoire. Un attaquant qui est capable de prédire et de fabriquer un cookie faible peut aisément détourner les sessions des utilisateurs légitimes.

Les cookies, décrits en détail dans la RFC 2965, sont le plus souvent utilisés pour implémenter la gestion de sessions. En bref, lorsqu'un utilisateur accède à une application qui a besoin de gérer des sessions et l'identité des utilisateurs, le serveur génère un (ou plusieurs) cookie et l'envoit au client. Le client renverra ce (ou ces) cookie au serveur à chaque connexion jusqu'à ce que le cookie atteigne sa durée de vie ou soit détruit. Les données stockées dans le cookie indiqueront beacuou d'informations au serveur : qui est l'utilisateur, quelles actions a-t-il faites jusqu'ici, quelles sont ses préférences, etc. Ainsi un protocole comme HTTP n'est plus sans état.

Un panier de courses en ligne est un parfait exemple de cela. Tout au long de la session d'un utilisateur, l'application garde la trace de son identité, de son profil, des produits qu'il a mis dans son panier, des quantités, des prix, des remises, etc. Les cookies sont un moyen efficace d'échanger des informations entre client et serveur (d'autres méthodes existent : paramètres d'URL ou champs cachés).

Du fait de l'importance des données qu'ils contiennent, les cookies sont vitaux pour la sécurité générale d'une application. En falsifiant des cookies, on peut détourner les sessions d'utilisateurs légitimes, escalader en privilège dans une session existante, et de manière générale influencer le comportement de l'application de manière frauduleuse.

Dans ce cadre, le testeur va vérifier si les cookies envoyés aux clients peuvent résister à une large gamme d'attaques destinées à interférer avec les sessions des utilisateurs légitimes et avec l'application elle-même. Le principal but est de générer un cookie qui sera considéré comme valide par l'application et qui octroira des accès non autorisés (détournement de session, escalade de privilèges, ...).

Généralement les principales étapes du schéma d'attaque sont les suivantes :
 * collecte de cookies : collecte d'un échantillon de cookies suffisamment important ;
 * rétro-ingénierie de cookies : analyse de l'algorythme de génération des cookies ;
 * manipulation de cookies : construction d'un cookie valide pour mener l'attaque à bien. Ce dernier point peut demander un grand nombre d'essais, selon la façon dont sont générés les cookies (cookie brute-force attack).

Un autre mode d'attaque est possible : le débordement de cookie. C'est une attaque de nature différente, puisqu'ici on ne cherche pas à générer un cookie valide. Au lieu de cela, le but est de déborder une zone mémoire, et ainsi de déclencher un comportement non-prévu de l'application. Ainsi, il peut être possible d'injecter (et d'exécuter à distance) du code malicieux.

Exemples et tests en black box
Chaque interaction entre client et serveur doit être testée selon au moins un des critères suivants :
 * Est-ce que tous les cookies ont l'option Secure ?
 * Est-ce que le cookie peut être transporté en clair (non chiffré) ?
 * Est-ce que l'on peut forcer le transport non chiffré du cookie ?
 * Si oui, comment l'application assure-t-elle la sécurité ?
 * Est-ce que les cookies sont persistents ?
 * Quelle est la durée de persistence des cookies ? Est-elle raisonnable ?
 * Est-ce que les cookies prévus pour être transient sont définis comme tel ?
 * Quels paramètres Cache-Control sont utilisés pour protéger les cookies en HTTP/1.1 ?
 * Quels paramètres Cache-Control sont utilisés pour protéger les cookies en HTTP/1.0 ?

Collecte de cookies
La première étape pour manipuler un cookie est de comprendre comment l'application le génère et le gère. Pour cela, les testeurs doivent essayer de répondre aux questions suivantes :

Naviguez sur l'application. Notez quand les cookies sont créés. Faites une liste des cookies reçus, incluant la page qui les génère (directive set-cookie), le domaine pour lequel ils sont valides, et leurs caractéristiques. En navigant sur l'application, trouvez quels cookies restent constants, et lesquels sont modifiés. Quel événement modifie un cookie ? Trouvez quelles parties de l'application nécessite un cookie. Accédez à une page, et essayez encore sans le cookie, ou avec une version modifiée de celui-ci. Essayez de cartographier quels cookies sont utilisés où.
 * Combien de cookies sont utilisés par l'application ?
 * Quelle partie de l'application génère et/ou modifie le cookie ?
 * Quelles parties de l'application nécessite ce cookie pour être accessible et fonctionner ?

Une feuille de calcul listant la correspondance de chaque cookie avec les parties de l'application les utilisant, et les informations concernées peut être un résultat de grande valeur, lors de cette étape.

Analyse de session
The session tokens (Cookie, SessionID or Hidden Field) themselves should be examined to ensure their quality from a security perspective. They should be tested against criteria such as their randomness, uniqueness, resistance to statistical and cryptographic analysis and information leakage.

The first stage is to examine the structure and content of a Session ID provided by the application. A common mistake is to include specific data in the Token instead of issuing a generic value and referencing real data at the server side.
 * Token Structure & Information Leakage

If the Session ID is clear-text, the structure and pertinent data may be immediately obvious as the following: 192.168.100.1:owaspuser:password:15:58

If part or the entire token appears to be encoded or hashed, it should be compared to various techniques to check for obvious obfuscation. For example the string “192.168.100.1:owaspuser:password:15:58” is represented in Hex, Base64 and as an MD5 hash: Hex	3139322E3136382E3130302E313A6F77617370757365723A70617373776F72643A31353A3538 Base64	MTkyLjE2OC4xMDAuMTpvd2FzcHVzZXI6cGFzc3dvcmQ6MTU6NTg= MD5	01c2fc4f0a817afd8366689bd29dd40a

Having identified the type of obfuscation, it may be possible to decode back to the original data. In most cases, however, this is unlikely. Even so, it may be useful to enumerate the encoding in place from the format of the message. Furthermore, if both the format and obfuscation technique can be deduced, automated brute-force attacks could be devised.

Hybrid tokens may include information such as IP address or User ID together with an encoded portion, as the following: owaspuser:192.168.100.1: a7656fafe94dae72b1e1487670148412

Having analyzed a single session token, the representative sample should be examined. A simple analysis of the tokens should immediately reveal any obvious patterns. For example, a 32 bit token may include 16 bits of static data and 16 bits of variable data. This may indicate that the first 16 bits represent a fixed attribute of the user – e.g. the username or IP address. If the second 16 bit chunk is incrementing at a regular rate, it may indicate a sequential or even time-based element to the token generation. See examples.

If static elements to the Tokens are identified, further samples should be gathered, varying one potential input element at a time. For example, log in attempts through a different user account or from a different IP address may yield a variance in the previously static portion of the session token.

The following areas should be addressed during the single and multiple Session ID structure testing:
 * What parts of the Session ID are static?
 * What clear-text confidential information is stored in the Session ID? E.g. usernames/UID, IP addresses
 * What easily decoded confidential information is stored?
 * What information can be deduced from the structure of the Session ID?
 * What portions of the Session ID are static for the same log in conditions?
 * What obvious patterns are present in the Session ID as a whole, or individual portions?

Session ID Predictability and Randomness
Analysis of the variable areas (if any) of the Session ID should be undertaken to establish the existence of any recognizable or predictable patterns. These analyses may be performed manually and with bespoke or OTS statistical or cryptanalytic tools to deduce any patterns in the Session ID content. Manual checks should include comparisons of Session IDs issued for the same login conditions – e.g., the same username, password, and IP address.

Time is an important factor which must also be controlled. High numbers of simultaneous connections should be made in order to gather samples in the same time window and keep that variable constant. Even a quantization of 50ms or less may be too coarse and a sample taken in this way may reveal time-based components that would otherwise be missed.

Variable elements should be analyzed over time to determine whether they are incremental in nature. Where they are incremental, patterns relating to absolute or elapsed time should be investigated. Many systems use time as a seed for their pseudo-random elements. Where the patterns are seemingly random, one-way hashes of time or other environmental variations should be considered as a possibility. Typically, the result of a cryptographic hash is a decimal or hexadecimal number so should be identifiable.

In analyzing Session ID sequences, patterns or cycles, static elements and client dependencies should all be considered as possible contributing elements to the structure and function of the application.
 * Are the Session IDs provably random in nature? Can the resulting values be reproduced?
 * Do the same input conditions produce the same ID on a subsequent run?
 * Are the Session IDs provably resistant to statistical or cryptanalysis?
 * What elements of the Session IDs are time-linked?
 * What portions of the Session IDs are predictable?
 * Can the next ID be deduced, given full knowledge of the generation algorithm and previous IDs?

Cookie reverse engineering
Now that the tester has enumerated the cookies and has a general idea of their use, it is time to have a deeper look at cookies that seem interesting. Which cookies is the tester interested in? A cookie, in order to provide a secure method of session management, must combine several characteristics, each of which is aimed at protecting the cookie from a different class of attacks.

These characteristics are summarized below:
 * 1) Unpredictability: a cookie must contain some amount of hard-to-guess data. The harder it is to forge a valid cookie, the harder is to break into legitimate user's session. If an attacker can guess the cookie used in an active session of a legitimate user, they will be able to fully impersonate that user (session hijacking). In order to make a cookie unpredictable, random values and/or cryptography can be used.
 * 2) Tamper resistance: a cookie must resist malicious attempts of modification. If the tester receives a cookie like IsAdmin=No, it is trivial to modify it to get administrative rights, unless the application performs a double check (for instance, appending to the cookie an encrypted hash of its value)
 * 3) Expiration: a critical cookie must be valid only for an appropriate period of time and must be deleted from the disk or memory afterwards to avoid the risk of being replayed. This does not apply to cookies that store non-critical data that needs to be remembered across sessions (e.g., site look-and-feel).
 * 4) “Secure” flag: a cookie whose value is critical for the integrity of the session should have this flag enabled in order to allow its transmission only in an encrypted channel to deter eavesdropping.

The approach here is to collect a sufficient number of instances of a cookie and start looking for patterns in their value. The exact meaning of “sufficient” can vary from a handful of samples, if the cookie generation method is very easy to break, to several thousands, if the tester needs to proceed with some mathematical analysis (e.g., chi-squares, attractors. See later for more information).

It is important to pay particular attention to the workflow of the application, as the state of a session can have a heavy impact on collected cookies. A cookie collected before being authenticated can be very different from a cookie obtained after the authentication.

Another aspect to keep into consideration is time. Always record the exact time when a cookie has been obtained, when there is the possibility that time plays a role in the value of the cookie (the server could use a time stamp as part of the cookie value). The time recorded could be the local time or the server's time stamp included in the HTTP response (or both).

When analyzing the collected values, the tester should try to figure out all variables that could have influenced the cookie value and try to vary them one at the time. Passing to the server modified versions of the same cookie can be very helpful in understanding how the application reads and processes the cookie.

Examples of checks to be performed at this stage include:
 * What character set is used in the cookie? Has the cookie a numeric value? alphanumeric? hexadecimal? What happens if the tester inserts in a cookie characters that do not belong to the expected charset?
 * Is the cookie composed of different sub-parts carrying different pieces of information? How are the different parts separated? With which delimiters? Some parts of the cookie could have a higher variance, others might be constant, others could assume only a limited set of values. Breaking down the cookie to its base components is the first and fundamental step.

An example of an easy-to-spot structured cookie is the following:

ID=5a0acfc7ffeb919:CR=1:TM=1120514521:LM=1120514521:S=j3am5KzC4v01ba3q

This example shows 5 different fields, carrying different types of data:

ID – hexadecimal CR – small integer TM and LM – large integer. (And curiously they hold the same value. Worth to see what happens modifying one of them) S – alphanumeric

Even when no delimiters are used, having enough samples can help. As an example, let's look at the following series:

0123456789abcdef

Brute Force Attacks
Brute force attacks inevitably lead on from questions relating to predictability and randomness. The variance within the Session IDs must be considered together with application session duration and timeouts. If the variation within the Session IDs is relatively small, and Session ID validity is long, the likelihood of a successful brute-force attack is much higher.

A long Session ID (or rather one with a great deal of variance) and a shorter validity period would make it far harder to succeed in a brute force attack.
 * How long would a brute-force attack on all possible Session IDs take?
 * Is the Session ID space large enough to prevent brute forcing? For example, is the length of the key sufficient when compared to the valid life-span?
 * Do delays between connection attempts with different Session IDs mitigate the risk of this attack?

Gray Box testing and example
If the tester has access to the session management schema implementation, they can check for the following: The Session ID or Cookie issued to the client should not be easily predictable (don't use linear algorithms based on predictable variables such as the client IP address). The use of cryptographic algorithms with key length of 256 bits is encouraged (like AES). Session ID will be at least 50 characters length. Session token should have a defined time-out (it depends on the criticality of the application managed data)
 * Random Session Token
 * Token length
 * Session Time-out
 * Cookie configuration:
 * non-persistent: only RAM memory
 * secure (set only on HTTPS channel): Set Cookie: cookie=data; path=/; domain=.aaa.it; secure
 * HTTPOnly (not readable by a script): Set Cookie: cookie=data; path=/; domain=.aaa.it; HTTPOnly

More information here: Testing for cookies attributes

Tools

 * OWASP Zed Attack Proxy Project (ZAP) - https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project - features a session token analysis mechanism.
 * Burp Sequencer - http://www.portswigger.net/suite/sequencer.html
 * Foundstone CookieDigger - http://www.mcafee.com/us/downloads/free-tools/cookiedigger.aspx
 * YEHG's JHijack - https://www.owasp.org/index.php/JHijack

Description of Session Management Vulnerabilities
See the OWASP articles on Session Management Vulnerabilities.

Description of Session Management Countermeasures
See the OWASP articles on Session Management Countermeasures.

How to Avoid Session Management Vulnerabilities
See the OWASP Development Guide article on how to Avoid Session Management Vulnerabilities.

How to Review Code for Session Management| Vulnerabilities
See the OWASP Code Review Guide article on how to Review Code for Session Management Vulnerabilities.