Attacking Tokens

This section describes common attacks against web application access/session tokens. There are three basic classes of access/session token attacks:

  • Prediction (manual and automated)

  • Capture/Replay

  • Fixation

Let's discuss each one in that order.

Manual Prediction

Access/session token prediction is one of the most straightforward attacks against web application authorization. It essentially involves manipulating the token in targeted ways in order to bypass access control. We'll first discuss manual prediction; in the next section, we'll describe automated analysis techniques that can accelerate prediction of seemingly indecipherable tokens.

Manual guessing is often effective in predicting the simplest access token/session ID values, such as those with human-readable syntax or formats. For example, in Chapter 1, we saw how simply changing the "account_type" value in Foundstone's sample Hacme Bank web application from "Silver" to "Platinum" implemented a privilege escalation attack. This section will describe manual tampering attacks against the following common mechanisms for tracking session state:

  • Query String

  • POST Data

  • HTTP Headers

  • Cookies

Query String

As discussed in Chapter 1, the query string contains additional client-provided parameters in the URI after the question mark (?) that are passed to server-side execution. The query string can contain multiple parameter values delimited by ampersand. Access/ session tokens are often carried in the query string. For example:

http://www.mail.com/mail.aspx?mailbox=joe&company=acme

The query string is mailbox=joe&company=acme, which are the parameters passed from the client to the mail.aspx script, which is located before the "?." Some obvious attacks using this example would be to change the query "mailbox" parameter to another username, for example, /mail.aspx?mailbox=jane&company=acme, in an attempt to view Jane's mailbox while authenticated as Joe. The query string is visible in the location bar on the browser and is easily changed without any special web hacking tools.

Use POST for Sensitive Data!

 Countermeasure    Carrying the session ID in the query string is discouraged because it's trivially alterable by anyone who pays attention to the address bar in their browser. Furthermore, unlike POST data, the URI and query string are recorded in the browser's history and the web server logs, presenting more opportunities for exposure. Query strings are also commonly shared indiscriminately when people e-mail around URIs. Finally, it's interesting to note that the query string is exposed in all of these scenarios even if SSL is used.

Because of these issues, many web application programmers prefer to use the POST method (which carries parameter values in the body of the HTTP request, obscured from trivial tampering), as opposed to the GET method (which carries the data in the query string, more open to attack in browser cache, logs, etc.).

Caution 

Don't be fooled into thinking that it's difficult to manipulate POST data, just because the client can't "see" it. As we illustrated clearly in Chapter 1, it's actually quite easy.

Of course, in any case, sensitive authorization data should be protected by other means than simple obscurity. However, as we've said elsewhere in this book, security plus obscurity never really hurts.

POST Data

POST data frequently contains authorization/session information, since many applications need to associate any data provided by the client with the session that provided it. The following example shows the curl tool making a POST to a bank account application containing some interesting fields called "authmask" (not sure what this might be, but the fragment "auth" sure looks interesting), "uid" (wanna bet that stands for user ID?), and a parameter simply called "a" that has a value of "viewacct" (wanna make another bet that this is some sort of administrative function related to viewing other users' account data?).

 $ curl v d 'authmask=8195' d 'uid=213987755' d 'a=viewacct' \ > --url https://www.victim.com/ * Connected to www.victim.com (192.168.12.93) > POST / HTTP/1.1 User-Agent: curl/7.9.5 (i686-pc-cygwin) libcurl 7.9.5 (OpenSSL 0.9.6c) Host: www.victim.com Pragma: no-cache Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* Content-Length: 38 Content-Type: application/x-www-form-urlencoded     authmask=8195&uid=213987755&a=viewacct 

One interesting thing to note in this example is how curl automatically calculates the Content-Length HTTP header, which must match the number of characters in the POST data. This field has to be recalculated if the POST payload is tampered with.

"Hidden" Form Fields   Another classic security-through-obscurity technique is the use of so-called "hidden" values within HTML forms to pass sensitive data such as session ID, product pricing, or sales tax. Although these fields are hidden from the user viewing a web site through a browser, they are of course still visible in the HTML source of the web page. Attackers will often examine the actual form field tags, since the field name or HTML comments may provide additional clues to the field's function.

Tip 

The WebScarab tool discussed in Chapter 1 provides a nifty "reveal hidden fields" feature that makes them just appear in the normal browser session.

Let's take a look at part of a HTML form extracted from an application's login page to see how they might be exploited in an authorization attack.

 <FORM name=login_form action= https://login.victim.com/config/login?4rfr0naidr6d3 method=post > <INPUT name=Tries type=hidden> <INPUT value=us name=I8N type=hidden> <INPUT name=Bypass type=hidden> <INPUT value=64mbvjoubpd06 name=U type=hidden> <INPUT value=pVjsXMKjKD8rlggZTYDLWwNY_Wlt name=Challenge type=hidden> User Name:<INPUT name=Login> Password:<INPUT type=password maxLength=32 value="" name=Passwd> 

When the user submits her username and password, she is actually submitting seven pieces of information to the server even though only two were visible on the web page. Table 5-6 summarizes these values.

Table 5-6: Examples of Hidden Form Field Values

Value

Description

Potential Vulnerability

Tries

Probably represents the number of times the user has tried to log in to the application. It's NULL right now since we haven't submitted a password yet. The server might lock the account if this value passes a certain threshold.

Since the lockout variable is carried on the client side, it can be trivially modified to prevent lockout during a password-guessing attack (say, by holding it at 0), or to lock out arbitrary users, creating a DoS condition.

I8N

The value for this field is set to "us". Since it appears to handle the language for the site, changing this value might not have any security implications for a session.

The field could still be vulnerable to input validation attacks. Check out Chapter 6 for more information.

Bypass

Here's a field name that sounds exciting. Does bypass require a specific string? Or could it be a Boolean value that lets a user log in without requiring a password?

This bypasses the login page as an authorization attack.

U

An unknown field. This could contain a session identifier or application information.

May contain sensitive session data that has been encoded (easy to break) or encrypted (usually difficult to break).

Challenge

This string could be part of a challenge-response authentication mechanism.

Tampering will probably invalidate authentication, but you never know. Also may be vulnerable to input validation attack.

Login

The user's login name.

SQL injection attacks might be interesting here (see Chapter 7).

Passwd

The user's password.

SQL injection attacks might be interesting here as well.

From this example, it appears that the "U" hidden field may be tracking session state information, but at this point it's not clear whether a vulnerability exists. Check out our discussion of automated session ID prediction later in this chapter for ideas on how to analyze unknown values.

HTTP Headers

HTTP headers are passed as part of the HTTP protocol itself, and are sometimes used to pass authorization/session data. Cookies are perhaps the most well-known HTTP headers and they are commonly used for authorization/state-tracking, but authorization schemes can also be based on the Location: and Referer: headers (and don't worry, we'll deal with the misspelling of Referer momentarily).

Note 

The application might also rely on custom headers to track a particular attribute of the user.

User-Agent   One of the simplest authorization tests to overcome is client browser make/ model verification, which is typically implemented via the User-Agent HTTP header. Many tools, curl included, enable the user to specify an arbitrary User-Agent header, so this check is really meaningless as an authorization mechanism. For example, if an application requires Internet Explorer for political reasons as opposed to technical ones (such as requiring a particular ActiveX component), you can change the User-Agent header to impersonate IE.

 $ curl -user-agent "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" \ > --url www.victim.com 

Cookies   Cookie values may be the most common location for storing authorization/ state information. They are set using the HTTP Set-Cookie header, as shown in the following example:

 Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure 

Once set, the client simply replays the cookie back to the server using the Cookie header, which looks almost exactly like the Set-Cookie header.

Since cookies are so commonly used for authorization, we'll discuss them on their own in an upcoming section of this chapter.

Referer   A common mistake web application developers often make is to trust information included as part of the Referer header and utilize that as a form of authentication. Well, what does the Referer header do? Why is it a security mistake? And for that matter, why is it misspelled ?

The Referer header is very simple. Basically, it tells the server the URI of the resource from which the URI in the request was obtained (i.e., "where I'm coming from"). They are automatically added by your browser when you click links, but not included if you type in the URI yourself. For example, if you were on Site A, and clicked a link to go to Site B, the Referer header would contain the URI of Site A as part of the HTTP request header, like so:

 Referer: http://www.siteA.com/index.html 

Why is it a mistake to rely on Referer headers for authorization? As it is commonly implemented in web applications, each time a new area is accessed by following a link, a piece of custom code on the server checks the Referer header. If the URL included in the Referer header is "expected," then the request is granted. If it is not, then the request is denied , and the user is shunted to some other area, normally an error page or something similar.

We can see how this process works in the following code sample. It's a simple Referer header authentication protocol included as part of an .asp page.

 strReferer = Request.ServerVariables("HTTP_REFERER") If strReferer = "http://www.victim.com/login.html" Then     ' this page is called from login..htm!     ' Run functionality here End If 

In this case, the code only looks for an expected URL, http://www.victim.com/login.html. If that is present, the request is granted. Otherwise , it is denied. Any authentication scheme that relies on the Referer header will work in a similar fashion to Basic authentication. The main difference between this method and Basic authentication is that web browsers will automatically generate a Referer header based on the parent URL, while Basic authentication will depend upon a specific user action, such as clicking a login button, to generate its authentication information.

Why would a developer use a URL included as part of a Referer header for authentication? Primarily, it's a shortcut. It relies on the assumption that if a user followed this specific path, he's coming from a trusted domain. That has some obvious, negative real-world implications. Say, for instance, that a site contains an Administrative area that relied on Referer header authentication. Once the user has accessed a specific page, such as the menu page, then each additional page in that area is accessible.

The important thing to recognize is that the client sets the Referer information, not the server. And if a piece of information is set by the client, it can be changed. The Referer information can easily be spoofed, as in the following PERL code sample.

 use HTTP::Request::Common qw(POST GET); use LWP::UserAgent;     $ua = LWP::UserAgent->new(); $req = POST ' http://www.victim.com/doadminmenu.html '; $req->header(Referer => ' http://www.victim.com/adminmenu.html '); $res = $ua->request($req); 

In this example, the code makes it appear the request came from adminmenu.html, but in actuality it can originate from anywhere . Remember, HTTP headers are very easy to spoof. All it took in this instance was a snippet of code. As the old security adage states, it is never a good idea to base security on the name of something, as that information can easily be impersonated, replayed, or even guessed. A related security adage is also pertinent here: never trust client input.

And the misspelling? It harkens back to the early days of the Internet when there was an "anything goes" mentality , and the misspelling fell through the cracks long enough to become standardized. It's just been carried forward until now. That should tell you everything you need to know about utilizing HTTP Referer headers for authentication!

Cookies

As we noted earlier, cookies remain the most popular form of authorization/session management within web applications despite a somewhat checkered security history (because of their central role, malicious hackers have devised numerous ways to capture, hijack , steal, manipulate, or otherwise abuse cookies over the years ). However, these attacks are not demonstrative of flaws with cookies per se, but rather the extensive attack surface of the modern client and server software through which they flow, and to some extent, the HTTP protocol itself. Cookies are described in RFC 2109 (see the "References and Further Reading" section at the end of this chapter for links to this and other references on cookies). As we noted in the earlier section in this chapter on HTTP headers, cookies are managed using the Set-Cookie and Cookie headers that are not generally displayed by common Internet clients .

Cookies are commonly used to store almost any data, and all of the fields can be easily modified using HTTP analysis tools like those outlined in Chapter 1. For a cookie-specific analysis tool, we like CookieSpy, a plug-in for Internet Explorer that opens a pane in the browser to display all of a site's cookies and even allows you to manipulate and replay them. Figure 5-3 shows a report from CookieSpy for an application. Figure 5-4 shows how to use CookieSpy to change a cookie's value (click the "x" to the left of a name to edit its value).


Figure 5-3: A CookieSpy report

Figure 5-4: Editing a cookie value with CookieSpy

How are cookies commonly abused to defeat authorization? Here's an example of an application that uses a cookie to implement "remember me"type functionality for authorization/state-tracking:

 Set-Cookie: autolog=bWlrZTpteXMzY3IzdA%3D%3D; expires=Sat, 01-Jan-2037 00:00:00 GMT; path=/; domain=victim.com 

Despite the somewhat cryptic content of this cookie, even an unsophisticated attacker could simply copy the cookie value and replay it from their own machine, potentially "becoming" the person identified by this value. Upon a bit deeper analysis, the autolog value that appears to contain random letters is merely the Base 64encoded string "mike:mys3cr3t"looks like the username and password are being stored on the system. Finally, the RFC 2109defined "secure" keyword is not present in this cookie. This means that the browser will permit the cookie to be sent over cleartext HTTP.

Bypassing Cookie Expire Times   When you log out of an application that uses cookies, the usual behavior is to set the cookie value to NULL (i.e., "Set-Cookie: ") with an expire time in the past. This erases the cookie. An application might also use the expire time to force users to reauthenticate every 20 minutes. The cookie would only have a valid period of 20 minutes from when the user first authenticated. When the cookie has expired , the browser deletes it. The application notices the cookie has disappeared and asks the user for new credentials. This sounds like an effective method of timing out unused sessions, but only if it is done correctly.

For example, if the application sets a "has password" value that expires in 20 minutes,

 Set-Cookie: HasPwd=45lfhj28fmnw; expires=Tue, 17-Apr-2006 12:20:00 GMT; path=/; domain=victim.com 

then an attacker might attempt to extend the expire time and see if the server still honors the cookie (note the bolded text, where we've changed the date one year into the future):

 Set-Cookie: HasPwd=45lfhj28fmnw; expires=Tue, 17-Apr-  2007  12:20:00 GMT; path=/; domain=victim.com 

From this, the attacker might determine if there are any server-side controls on session times. If this new cookie, valid for 20 minutes plus one year, lasts for an hour , then the attacker knows that the 20-minute window is arbitrarythe server is enforcing a hard timeout of 60 minutes.

Automated Prediction

If an access token/session ID doesn't yield to human intuition, it's likely that some form of automated analysis will have to be conducted . This section covers techniques for automated analysis of predictable session IDs and cryptographically protected values.

Collecting Samples

Collecting a large enough sample of session ID values is a necessary step towards determining how "random" a session ID really is. You'll want to do this with a script, since collecting 10,000 values manually quickly becomes monotonous! Here are three example Perl scripts to help you get started. You'll need to customize each one to collect a particular variable (we've grep'ed for some COTS session IDs in these examples just for illustration purposes).

The following script, gather.sh, collects ASPSESSIONID values from an HTTP server using netcat:

 #!/bin/sh # gather.sh while [ 1 ] do echo -e "GET / HTTP/1.0\n\n"  \ nc -vv  80  \ grep ASPSESSIONID done 

The next script, gather_ssl.sh, collects JSESSIONID values from an HTTPS server using the openssl client:

 #!/bin/sh # gather_ssl.sh while [ 1 ] do echo -e "GET / HTTP/1.0\n\n"  \ openssl s_client -quiet -no_tls1 -connect :443 2>/dev/null  \ grep JSESSIONID done 

Finally, the gather_nudge.sh script collects JSESSIONID values from an HTTPS server using the openssl client, but also POSTs a specific login request that the server requires before setting a cookie:

 #!/bin/sh # gather_nudge.sh while [ 1 ] do cat nudge \ openssl s_client -quiet -no_tls1 -connect :443 2>/dev/null  \ grep JSESSIONID done 

The contents of the "nudge" file referenced in this script are as follows :

 POST /secure/client.asp?id=9898 HTTP/1.1 Accept: */* Content-Type: text/xml Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Q312461) Host: www.victim.com Content-Length: 102 Connection: Keep-Alive Cache-Control: no-cache     <LoginRequest><User><SignInName>latour</SignInName><Password>Eiffel </Password></User></LoginRequest> 

Each one of the scripts runs in an infinite loop. Make sure to redirect the output to a file so you can save the work. For example:

 $ ./gather.sh www.victim.com  tee cookies.txt $ ./gather_ssl.sh www.victim.com  tee cookies.txt $ ./gather_nudge.sh www.victim.com  tee cookies.txt 
Tip 

Use the GNU cut command along with grep to parse the actual value from the cookies.txt.

Nonlinear Analysis

How can you test that actual randomness of a collection of session IDs? In April 2001, Michal Zalewski of the Bindview team applied nonlinear analysis techniques to the initial sequence numbers (ISN) of TCP connections and made some interesting observations on the "randomness" of the values. The most illustrative part of the paper was the graphical representation of the analysis. Figures 5-5 and 5-6 show the visual difference in the relative random nature of two sources.


Figure 5-5: Decently randomized ISN values

Figure 5-6: Poorly randomized ISN values

The ISN is supposed to be a random number used for every new TCP connection, much like the session ID generated by a web server. The functions used to generate the graphs do not require any complicated algorithm. Each coordinate is defined by:

 x[t] = seq[t]   - seq[t-1] y[t] = seq[t-1] - seq[t-2] z[t] = seq[t-2] - seq[t-3] 

The random values selected from the dataset are the "seq" array; "t" is the index of the array. Try applying this technique to session values you collect from an application. It is actually trivial to generate the data set. The following Perl script accepts a sequence of numbers, calculates each point, and (for our purposes) outputs x, y, and z:

 #!/usr/bin/perl # seq.pl @seq = (); @x = @y = @z = (); while(<>) {     chomp($val = $_);     push(@seq, $val); } for ($i = 3; $i < $#seq; $i++) {     push(@x, $seq[$i]     - $seq[$i - 1]);     push(@y, $seq[$i - 1] - $seq[$i - 2]);     push(@z, $seq[$i - 2] - $seq[$i - 3]); } for ($i = 0; $i < $#seq; $i++) {     print $x[$i] . " " . $y[$i] . " " . $z[$i] . "\n"; } 
Note 

This function does not predict values; it only hints at how difficult it would be to predict a value. Poor session generators have significant trends that can be exploited.

To use this script, we would collect session numbers in a file called session.raw, and then pipe the numbers through the Perl script and output the results to a data file called 3d.dat:

 $ cat session.raw  ./seq.pl > 3d.dat 

The 3d.dat file contains an X, Y, and Z coordinate on each line. Use a tool such as Gnuplot to graph the results. Remember, this does not predict session ID values, but it can be useful for determining how hard it would be to predict values.

Brute-force/Dictionary Attacks

In the earlier section on fingerprinting, we noted some key characteristics of MD5 hashes. If you are sure that you've found an MD5 hash, you could use classic brute-force guessing to determine the original cleartext value. For example, the following Perl commands using the Digest::MD5 module take different combinations of the login credentials and generate the corresponding MD5 hash:

 $ perl -e 'use Digest::MD5; \ > print Digest::MD5::md5_base64("userpasswd")' ZBzxQ5hVyDnyCZPUM89n+g $ perl -e 'use Digest::MD5; \ > print Digest::MD5::md5_base64("passwduser")' seV1fBcI3Zz2rORI1wiHkQ $ perl -e 'use Digest::MD5; \ > print Digest::MD5::md5_base64("passwdsalt")' PGXfdI2wvL2fNopFweHnyA 

If the session token matches any of these values, then you've figured out how it's generated.

Sites that use MD5 often insert random data or some dynamic value in order to defeat brute-force guessing attacks like this. For example, a more secure way of generating the token, especially if it is based on the password, involves secret data and a timestamp:

 MD5(epoch time + secret + password) 

Placing the most dynamic data at the beginning causes MD5 to "avalanche" more quickly. The avalanche effect means that two seed values that only differ by a few bits will produce two hash values that differ greatly. The advantage is that a malicious user only has one of the three pieces of the seed value. It wouldn't be too hard to find the right value for the epoch time (it may only be one of 100 possible values), but the server's secret would be difficult to guess. A brute-force attack could be launched, but success would be difficult. The disadvantage is that it will be difficult for the server to re-create the hash. The server must track the time it was generated so it can make the proper seed.

A "less" secure ("more" and "less" are ill-defined terms in cryptography) but equally viable method would only use the server's secret and the user's password:

 MD5(secret + password) 

In this case, the user needs to guess one value, the server's secret. If the secret value is less than eight characters, then a successful attack by a single malicious user is conceivable.

This same approach could be applied to encrypted values as well.

Bit Flipping

The attacker may be able to gain a leg up by noticing trends across a collection of encrypted values. For example, you might collect a series of session tokens that only differ in certain parts :

 46Vw8VtZCAvfqpSY3FOtMGbhI 4mHDFHDtyAvfqpSY3FOtMGbjV 4tqnoriSDAvfqpSY3FOtMGbgV  4  zD8AEYhc  AvfqpSY3FOtMGb  m3 

Did you notice the trend? Each value begins with the number four. If this is an encrypted string, this segment probably isn't part of it. There are eight random bytes after the four, then fourteen bytes which do not change, followed by a final two random bytes. If this is an encrypted string, then we could make some educated guesses about its content. We'll assume it's encrypted with Triple-DES, since DES is known to be weak:

 String = digit + 3DES(nonce  + username (+ flags) + counter)            4           8 bytes   14 bytes            2 bytes 

Here's why we make the assumption:

  • The field of eight characters always changes. The values are encrypted, so we have no way of knowing if they increment, decrement, or are truly random. Anyway, the source must be changing so we'll refer to it as a nonce.

  • The fourteen bytes remain constant. This means the encrypted data come from a static source, perhaps the username, or first name, or a flag set for "e-mail me a reminder." It could also imply that it's an entirely different encrypted string and merely concatenated to the previous eight bytes. As you can see, we're starting to get pretty vague.

  • The final two bytes are unknown. The data is short, so we could guess that it's only a counter or some similar value that changes but does not represent a lot of information. It could also be a checksum for the previous data, added to ensure no one tampers with the cookie.

Using this information, an attacker could perform "bit flipping" attacks: blindly change portions of the encrypted string and monitor changes in the application's performance. Let's take a look at an example cookie and three modifications:

 Original:       4zD8AEYhcAvfqpSY3FOtMGbm3 Modification 1: 4zD8AEYhc  AAAAAAAAAAAAAA  m3 Modification 2: 4zD8AEYhc  B  vfqpSY3FOtMGbm3 Modification 3: 4zD8AEYhcAvfqpSY  AvfqpSY  m3 

We're focusing the attack on the static, 14-byte field. First, we try all similar characters. If the cookie is accepted on a login page, for example, then we know that the server does not inspect that portion of the data for authentication credentials. If the cookie is rejected on the page for viewing the user's profile, then we can guess that portion contains some user information.

In the second case, we change one letter. Now we'll have to submit the cookie to different portions of the application to see where it is accepted and where it is rejected. Maybe it represents a flag for users and superusers? You never know. (But you'd be extremely lucky!)

In the third case, we repeated the first half of the string. Maybe the format is username:password. If we make this change, guessing that the outcome is username:username, and the login page rejects it, maybe we're on the right track. This can quickly become long, unending guesswork.

For tools to help with encryption and decryption, try the UNIX crypt() function, Perl's Crypt::DES module, and the mcrypt library (http:// mcrypt .hellug.gr/).

Capture/Replay

As you can see, prediction attacks are usually all-or-none propositions : either the application developer has made some error, and the token easily falls prey to intuitive guessing and/or moderate automated analysis, or it remains indecipherable to the attacker and they have to move on to different attack methods .

One way for the attacker to bypass all of the complexity of analyzing tokens is to simply replay another user's token to the application. If successful, the attacker effectively becomes that user.

Such capture/replay attacks differ from prediction in one key way: rather than guessing or reverse engineering a legitimate token, the attacker must acquire one through some other means. There are a few classic ways to do this, including eavesdropping, man-in-the-middle, and social trickery attacks. Let's discuss some examples.

Eavesdropping is an omnipresent threat to any network-based application. Popular, free network monitoring tools like Ethereal and Ettercap can easily sniff a web application session off the wire, exposing any authorization data to disclosure and replay.

The same effect can be achieved by placing a "man-in-the-middle" between the legitimate client and the application. For example, if an attacker compromises a proxy server at some large ISP, they'd have access to session IDs for all of the customers who used the proxy. And if the proxy performs SSL, not even that will protect the data.

Finally, a simple but effective method to get session tokens is by simply asking a prospective victim for it. As we noted in our earlier discussion of sensitive data in the query string, unwitting users can be convinced to send URIs via e-mail containing such datayet another reminder of the dangers of storing sensitive data in the query string!

Session Fixation

In December 2002, ACROS Security published a paper on session fixation , the name they gave to a class of attacks where the attacker chooses the session ID for the victim, rather than having to guess or capture it by other means (see "References and Further Reading" for a link).

Session fixation works as follows:

  • The attacker logs into a vulnerable application, establishing a valid session ID that will be used to "trap" the victim.

  • He then convinces his victim to log into the same application, using the same session ID (the ACROS paper discuses numerous ways to accomplish this, but the simplest scenario is to simply e-mail the victim a link to the application with the trap session ID in the query string).

  • Once the victim logs into the application, the attacker then replays the same session ID, effectively hijacking the victim's session (one could say that the victim logged onto the attacker's session).

One variation on this attack doesn't necessarily involve a separate victim session. In this variation, the attacker simply resets their own session expiration to some point far in the future, potentially well past the point that they remain authorized users of the application. The "fixed" access token effectively becomes a permanent back door into the application. In scenarios where web-based applications are used to provide administrative access to IT systems, for example, this could be a Very Bad Thing.

Session fixation seems like an attacker's dream come true, but there are a couple of aspects to this attack that make it much less appealing than initially advertised:

  • The attacker must convince the victim to launch a URI that logs them into the application using the "trap" session ID. If you can trick someone into loading a URI, there are probably many worse things you could do to them than fix a session ID.

  • The attacker must then simultaneously log into the application using the same trap session ID, before the victim logs out or the session expires (of course, if the web app is brain-dead and doesn't handle stale sessions appropriately, this could be an open-ended window).

There's also a really easy countermeasure to session fixation attacks: generate new session IDs for each successful login (i.e., after authentication), and don't let your login facility accept client-provided session IDs. Finally, ensure that sessions are timed out using server-side logic and that absolute session expiry limits are set. This will prevent users from coming back to haunt your application years after their account has expired.

Note 

Each of these countermeasures is purely application-level; the web platform is not going to protect you from session fixation.



Hacking Exposed Web Applications
HACKING EXPOSED WEB APPLICATIONS, 3rd Edition
ISBN: 0071740643
EAN: 2147483647
Year: 2006
Pages: 127

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net