Howto Analyse a session ID


written by: flow@atstake.com scusi at snurn dot de
Date: 19.09.2002
Last Update: 20.12.2011
Version: 0.3

Index:

  1. About this document
  2. Download
  3. Requirements for session IDs and why
  4. What is a Differential Analysis (Phase Space Analysis)?
  5. Using Differential Analysis in attacking cryptographic ciphers
  6. Steps to perform
    1. - Data Collection
    2. - Data Reduction
    3. - Calculation
    4. - Visualization ans analysis
  7. Interpreting results
  8. Tools to use
    1. gather_cookies.sh
    2. gather_cookies-ssl.sh
    3. poststuff.txt
    4. seq.pl
  9. Credits
  10. Comments

About this Document:

This document should give a straight forward guidline in "how to analyse session-IDs" you find in Webaplications. This document was written by Florian Walther on the 19th of September 2002 and inspired by Michal Zalewski work on IP Sequenznumbers, that is availible at: There are also several code snipplets shameless stolen from "Hacking Exposed Webapplications".


Download

You can download this project in either zip or tar formats.

You can also clone the project with Git by running:

$ git clone git://github.com/scusi/SessionIDAnalysis


Requirements for session IDs and why

Web applications use session management to maintain context during client interaction. Once a user logs in, that user is associated with a particular session and the client is marked as authenticated. To prevent having to send authentication credentials with each request from the client, most session management systems use a session identifier. The session identifier is basically a token that associates incoming requests with the server's stored session. The goal of an attacker is to steal or guess a valid session ID for a user. Therefore a session ID must be secured during transmission, should be not predictable and it should be long enough to withstand brute force attacks.


What is a Differential Analysis (Phase Space Analysis)?

A differential analysis is a form of an attack in which the differences between values is used to gain additional knowledge about the system and maybe also about its implementation.


Using Differential Analysis in attacking cryptographic ciphers.

Phase Space is an n-dimensional space that fully describes the space of an n-variable system. An attractor is a shape that is specific to the given Pseudo-Random Number Generator (PRNG) function, and reveals the complex nature of dependencies between subsequent results generated by the implementation. We wanted to generate a clean, three-dimensional representation of the one-dimensional input data. The method used is known as "delayed coordinates", and is well known and widely used in the analysis of dynamic systems, especially nonlinear systems and deterministic chaos. This method assumes that we can reconstruct missing dimensions using previous, delayed function values as additional coordinates. Instead of using function values, we will calculate the first-order difference for the input data to generate more suggestive and useful results to show the function dynamics.So if "s" stands for the input set, and "x", "y" and "z" are the point coordinates we are looking for, the equations are:

x[n] = s[n-2] - s[n-3]
y[n] = s[n-1] - s[n-2]
z[n] = s[n] - s[n-1]
 

NOTE: This function does not predict values, it only hints at how difficult it would be to predict a value.


Steps to perform

The analysis can be described in four Steps:

  1. - Data Collection
  2. - Data Reduction
  3. - Calculation
  4. - Visualization ans analysis

Step 1 Data Collection:


The first thing we have to do is to collect data on which to base the analysis. Normally SessionIDs will be set via cookies at the loginpage to the webapplication uses that SessionID. We assume that you have a valid login to the application in order to login and collect those cookies contain the SessionID. To do this we can use the gather_cookie.sh Script is described in the "Tools to use" Section of this document. gather_cookies.sh will repeatedly login into the application to gather cookies that contain the SessionID.

 

Step 1 in detail:

We assume you have a valid login, let's say User="test" and Password="testpasswd" Start @stake WebProxy, configure your browser to use webproxy and point your browser to the loginpage of the target webapplication. After login succesfully to the application go into the requestcache of webproxy and look for the last request you send to the Server before the Server sends back the cookie contains the sessionID. The Request could look like:

------------------------------
01 POST /path-to/login HTTP/1.0						  
02 User-Agent: Mozilla/4.75 [en] (X11; U; OpenBSD 3.1 i386; Nav) 
03 Host: mytest.server.com:443 
04 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* 
05 Accept-Encoding: gzip 
06 Accept-Language: de, en 
07 Accept-Charset: iso-8859-1,*,utf-8 
08 Cookie: test=1; host=; folders=; HostName=test-domain 
09 Content-type: application/x-www-form-urlencoded 
10 Connection: close 
11 Content-length: 96 
12 
13 User=test&Password=testpasswd&RequestType=LoginRequest&Domain=test-domain 
-------------------------------

The Server Response (the Cookie) could look like:

------------------------------- 
01 HTTP/1.1 302 Found 
02 Date:  
03 Server: Apache/1.3.26 (Unix) mod_ssl/2.8.10 OpenSSL/0.96 
04 Set-Cookie: SESSIONID=51917721 
05 Location: /path-to/login 
06 Connection: close 
07 Content-type: text/html; charset=iso-8859-1 
------------------------------- 

if you found both, take the browser-Request and put it in a text file (poststuff.txt). This text file we will use as input data for our cookie collecting script (gather_cookies.sh) in order to login. Basically "gather_cooies.sh" just posts the input (our request is now in poststuff.txt) to the given webserver and logs the respons in another log file. In order to have enough data to base our analysis on, we should collect at least 10.000 Cookies.

NOTE: repeatendly logins to a webserver can cause kind of a dinial of service condition if the webserver is not performant enough to handle all the requests we generate in addition to the "normal" traffic.


Step 2 Data Reduction:

The data we collected by the shell script in step 1 contains much more information than needed for the specific analysis. We have to extract and condens the data down to what is relevant for us.

Step 2 in detail:

Step 1 produced a logfile with all the responses from the Webserver. The only thing we are interested in is the value of the SESSIONID Cookie (which is 51917721 in the example above). I leave it up to you how to cut away all the other data, i did it with the subtract command in vi, but you can also do it in Perl or with sed and gawk or what ever you want to use. (Just by Hand is a bit boring ;-)) After you cut out all the stuff we don't need you should have a file looks like:

               -------------------------------
               51917721
               52792087
               53667222
               00511487
               01386398
               02495651
               03386901
               04245317
               05120733
               05979877
               06839779
               07698167
               -------------------------------
       

Save the values to a file. Now we are ready for step 3.


Step 3: Calculation:

In order to be able to do phase space analysis, the delayed coordinates are calculated with the existing cookie values. we will use a custom-developed Perl script (seq.pl) to accomplish this step.

Step 3 in detail:

What we do now is we use seq.pl (which is in the Tools Section of this document) to calculate our delayed coordinates from the inputdata (the cookie values we extracted in Step 2). In order to do this we just have to run seq.pl with the input data as argument. You have to call seq.pl with a comand line like this:

cat step2-output.txt | ./seq.pl > 3d.dat

The above command line will print the cookie values we extracted in step 2 and pipe them to seq.pl (which is doing the actual calculations). The output will be written to 3d.dat. The Script will produce a *.dat file (3d.dat) with the delayed coordinates. The .dat file could look like:

	            -------------------------------
	            891250 1109253 874911
	            858416 891250 1109253
	            875416 858416 891250
	            859144 875416 858416
	            859902 859144 875416
	            858388 859902 859144
	            860174 858388 859902
	            858751 860174 858388
	            859330 858751 860174
	            874704 859330 858751
	            875725 874704 859330
	            859341 875725 874704
	            859364 859341 875725
	            -------------------------------
	    

If you have the datfile you are ready for Step 4.


Step 4: Visualization and Analysis:

The data gathered in Step 3 was put into a mathematical plot program to generate the display graph (Fig.1). we will use 'GNUplot' to achieve this effort.

Step 4 in detail:

What we do now is we feed the delayed coordinates into GNUplot to visualize the data, in order to be able to analise the results. We need to have GNUplot instaled and running. GNUplot can be downloaded at:
http://www.gnuplot.info/
An introduction to GNUplot you can find here:
http://www.cs.uni.edu/Help/gnuplot/
 
Start GNUplot with gnuplot. U will get a gnuplot command line looks like:

-------------------------------
gnuplot>
-------------------------------

In the following table you will find the commands you really need.

GNUplot Command: Description:
gnuplot> splot "step3output.dat" Will load and plot the data we got out of step 3.
gnuplot> set output "output.ps" redirects the output to a file with the filename output.ps
gnuplot> set terminal postscript Sets the terminal mode to postscript, will produce postscript output.
gnuplot> set terminal postscript color produces also Postscript, but in color.
gnuplot> replot replots the whole stuff. If you changed the terminal and output this will be used now.

This Postscript file you can also convert into .jpg or a .gif picture, which you can put into your report. The result could look like the examples in Interpreting results


Interpreting results:

good randomness

A high degree of randomness in the session ID would generate a wide distribution cloud with evenly spread values and no patterns. The following figure shows a good randomness. It was produced by this script.
Click on the image to Zoom in.

img/Truly_Random_Values.jpg

poor randomness

A poor degree of randomness in the session ID would generate a clear concentration of values along the three vectors. The folowing graph shows a poor randomness.
Click on the image to Zoom in.

img/not-really-random.jpg  

time based "randomness"

In the following figure you can see how a SessionID which is based on seconds and microseconds since the epoch is shown in a phase-space analysis.
Click on the image to Zoom in.

img/non-random-0.0.3.jpg

The Script i wrote to generate these values is availible here
The relevant parts of the script looks like:

              #!/usr/bin/perl -w
              # [...]
              use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
              use Math::Random;
              
              for ($i=0; $i<$count;$i++)
              {
                      $random = random_uniform();
                      $randsub = substr($random, 2, 6);
                      ($seconds, $microseconds) = gettimeofday;
                      $s = substr($seconds, 8, 2);
                      uslgather_cookies.sheep $randsub;
                      $time = $s . $microseconds;
                      print ("$time\n");
              }
              exit;
       
 

Tools to use:

In this Section you will learn about the Tools you need to do all this.

gather_cookies.sh

To collect the cookies we have gather_cookies.sh and gather_cookies-ssl.sh.
gather_cookies.sh is a Sellscript for colecting cookies from normal webservers (http).
gather_goocies-ssl.sh is a script to collect cookies from https Servers.
The Syntax of the script is:
./gather_cookies.sh www.victim.com | tee cookies.txt
The Code looks like:

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

gather_cookies-ssl.sh

The Syntax for gather_cookies-ssl.sh is the same as for gather_cookies.sh.
The Code for gather_cookies-ssl.sh looks like this:

     gather_cookies.sh:
     ==================
     01	#!/bin/sh
     02	#
     03	# gather_cookies-ssl.sh
     04	# written by <flow@atstake.com>
     05	#
     06	# Shell script to gather Cookies from a Server to analyze them.
     07	#
     08	##########################################################
     09	while [ 1 ]
     10	do
     11	cat poststuff.txt|  \
     12	openssl s_client -quiet -no_tls1 -connect $1:443 2>/dev/null | \
     13	grep 1
     14	done
     

poststuff.txt

poststuff.txt is the request we post to the server in order to login and getting a cookie with the SessionID.

poststuff.txt
==============
POST /path-to/login HTTP/1.0
User-Agent: Mozilla/4.75 [en] (X11; U; OpenBSD 3.1 i386; Nav)
Host: mytest.server.com:443
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: de, en
Accept-Charset: iso-8859-1,*,utf-8
Cookie: test=1; host=; folders=; HostName=test-domain
Content-type: application/x-www-form-urlencoded
Connection: close
Content-length: 96

User=test&Password=testpasswd&RequestType=LoginRequest&u=&STD=lm%3D1%26&Domain=test-domain

seq.pl

seq.pl is the Perlscript which calculates the delayed coordinates for the Cookie Values you collected.

seq.pl:
=======
01	############################################
02	#!/usr/bin/perl -w
03	#
04	# seq.pl
05	# Script to calculate "delayed coordinates".
06	############################################
07
08	@seq = ();
09	@x = @y = @z = ();
10	while(<>) {
11	        chomp($val = $_);
12	        push(@seq, $val);
13
14	}
15	for ($i = 3; $i < $#seq; $i++) {
16      	push(@x, $seq[$i]       - $seq[$i - 1]);
17        	push(@y, $seq[$i - 1]   - $seq[$i - 2]);
18	        push(@z, $seq[$i - 2]   - $seq[$i - 3]);
19	}
20	for ($i = 0; $i < $#seq; $i++) {
21	        print $x[$i] . " " . $y[$i] . " " . $z[$i] . "\n";
22	}
23	############################################

Credits:

Thanks to:


Comments:

If you have any constructive comment on the above please drop a mail to: scusi@snurn.de. I will try to add your stuff to the current version of the document and/or correct the stuff you found that is not right or not clear.


© by Florian 'scusi' Walther September 2002
[ back to top ]