Page 1 of 1

Making Session Jacking a Nightmare

Posted: Fri Aug 17, 2012 8:06 pm
by Luke111
Edit (8-18-12):
Some of you may be wondering what Session Jacking is. I will explain it semi-technically, and then as I would to my parents (who are for the most part, computer illiterate.)

Session Jacking is when you look through the network for the cookies that users are sending to a website, and then use those cookies to make it look like you are that user. Pretty much stealing their cookies, and then authenticating yourself as the other person.

Think of it like this: Your child sees your signature, and forges a letter to the teacher using what appears to be your signature.
That signature is the cookie, the letter is the request for the page, and the teacher responds as if you (the parent) really wrote the letter. The signature looks real!

The real problem here is that it will happen, even if your users have the strongest password in the world, and the best salting algorithm on the planet.

Here is how this method works (it is actually multiple methods in one):
1. This checks that the user is coming from the same IP address and user agent. If someone steals your session, and logs in using chrome while your using IE, the authentication will fail.
2. This regenerates the session key every page request. The hacker will have to be pretty fast to steal it, as page requests happen a lot.
3. This uses a method that (I think) will stop Firesheep (a commonly used session jacking plugin for firefox): It has a randomly generated cookie name. The only real way to get the name of that cookie would be to use a regular expression, which I don't think it supported by firesheep. Anyways, you can clutter with a few different fake cookies to make it harder if this method starts failing.

End Edit
Hi everyone!
I thought I would show you a way to protect against one of the most common website hacking methods, session jacking. There is a couple of things you should do first, though:
1. Make sure that the change password page asks for your old password first. Even if session jacking gets through, the hacker can't change the password.
2. Please, Please use a salt.
3. Get the code I (Luke111) posted here: http://indie-resource.com/forums/viewto ... 8&start=10 for the easy and quick database access (mysqli_tgb).
4. Make a user table with at least these fields: ID, Status, FakeID

Okay, now on to the code.

some constants to make life easier:

Code: Select all


//the fields we can extract from the getuserlevelid_ function
define("FIELD_USERLEVEL",1);
define("FIELD_USERID",2);

define("USERSTATUS_NL",0);
define("USERSTATUS_REGULAR",1);
//add more here for higher user levels than the regular logged in user. maybe admin, or moderator, or something
 
this is the code to verify the user is logged in.

Code: Select all


session_start();
session_regenerate_id(false);

function getuserlevelid_($field = FIELD_USERLEVEL) {
       //make sure the user's variables are set, and are valid. This includes the user agent, the ip address, and the session & cookie variables we will be using
        if (isset($_SESSION['PTR'],$_SESSION['HTUA'],$_SESSION['HTIP'],$_COOKIE[$_SESSION['PTR']]) == false || $_SESSION['HTUA'] != $_SERVER['HTTP_USER_AGENT'] || $_SESSION['HTIP'] != $_SERVER['REMOTE_ADDR']) {
            return ($field == FIELD_USERLEVEL ? USERSTATUS_NL : 0);
        }
        //extract the user id and fake id from the cookie.
        $q_uid = intval(substr($_COOKIE[$_SESSION['PTR']],strrpos($_COOKIE[$_SESSION['PTR']],",")+1));
        $q_fid = intval(substr($_COOKIE[$_SESSION['PTR']],0,strrpos($_COOKIE[$_SESSION['PTR']],",")));
        //get the user's status from the user table.
        $sql_row = $GLOBALS['con']->s("SELECT `Status` FROM `usertb` WHERE `ID`=? AND `FakeID`=? LIMIT 1",$q_uid,$q_fid);
        if (count($sql_row) > 0) {
            return ($field == FIELD_USERLEVEL ? $sql_row[0]['Status'] : $q_uid);
        } else {
            return 0;
        }
    }
 
Okay, so the FakeID is just a field to (help) make sure the cookie is valid. This is kindof like another lock on the door.

Now for the login code:

Code: Select all

//use your code to get the user's id, status, and other required things from the database
//use your code to make sure the hashed/salted entered password is the same as the hashed/salted database password.
//now, use this code to log in:

//set the session pointer to a random value that is to be the cookie's name
$_SESSION['PTR'] = strval(mt_rand(1000000,9999999));
//set up the fake id to be a random value
$fid = strval(mt_rand(1000000,9999999));
//update the user table to reflect the new fakeid
$con->iud("UPDATE `usertb` SET `FakeID`=? WHERE `ID`=? LIMIT 1",$fid,$userid);
//set the new cookie
setcookie($_SESSION['PTR'],$fid . "," . strval($userid),time()+400000,"/");
//set the other session variables to reflect the user agent/ip address
$_SESSION['HTUA'] = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['HTIP'] = $_SERVER['REMOTE_ADDR'];
 
Now for the logout code:

Code: Select all

//do all your pre-logout stuff here...

//reset the fakeid in the database
$con->iud("UPDATE `usertb` SET `FakeID`=? WHERE `ID`=?",strval(mt_rand(1000000,9999999)),$uid);
//unset the session variables
unset($_SESSION['HTUA']);
unset($_SESSION['HTIP']);
//unset the cookie
setcookie($_SESSION['PTR'],"",time()-3600,"/");
//destroy the session variable that stores the cookie name
unset($_SESSION['PTR']);
//destroy the session
session_destroy();
 
There is a lot more that you can do with this, but I posted with just a little bit of meat on the bones.

Have fun stopping hackers!
-Luke

Re: Making Session Jacking a Nightmare

Posted: Sat Aug 18, 2012 12:37 pm
by OldRod
Thanks for posting such well-documented code. Even if someone can't use this as is, it will be easy to change.

Very nice post :)

Re: Making Session Jacking a Nightmare

Posted: Sat Aug 18, 2012 9:48 pm
by Jackolantern
Very nice! As this is a site mostly aimed at beginners, do you think you could add a quick blurb about what session hijacking is at the beginning? I have a feeling many users are unaware of it or its dangers (and the fact that, as you touched on, this is one of the first hacking methods beginning hackers master). Again, great stuff! :)

Re: Making Session Jacking a Nightmare

Posted: Sat Aug 18, 2012 10:48 pm
by OldRod
Jackolantern wrote:Very nice! As this is a site mostly aimed at beginners, do you think you could add a quick blurb about what session hijacking is at the beginning? I have a feeling many users are unaware of it or its dangers (and the fact that, as you touched on, this is one of the first hacking methods beginning hackers master). Again, great stuff! :)
Great point, Jack! I hear that this is a danger you have to guard against all the time, but I've never really heard a good description of what it is.

Re: Making Session Jacking a Nightmare

Posted: Mon Aug 20, 2012 2:52 am
by Jackolantern
The problem with sessions is that they have to exist somewhere, and no matter where they are, there are problems. One of my complains for a while now is that PHP tricks you into thinking it is on the server, but it isn't. This is what is sometimes called a "magic cookie". The problem with having it on the server is that IP addresses change, and you could never tie it back into the user over time. So it has to be on the user's end. Session hijacking references a ton of hacking tricks that involve either stealing (often through packet sniffing along the line) the cookie that controls sessions, or, more often, tricking the user into giving it to you, generally without their knowledge.

Sessions security is namely about hardening the cookies that relate to session management to make them harder to steal. This can take many shapes, but the code posted here by Luke looks like a great start. A common complaint of PHP is that the base installation does absolutely nothing to prevent hijacking, and that fact is rapidly being exploited to make session hijacking one of the most common website attacks out there today.

EDIT: Oops! Just saw that Luke added an explanation as well about hijacking. Oh well, the more the merrier :lol:

Re: Making Session Jacking a Nightmare

Posted: Tue Aug 21, 2012 11:22 pm
by Callan S.
I don't understand how cookie sending can be tracked, in atleast things like 'remember me' functions? That seems to be client side only - in such a case your sending the same kind of data the client sends. Is this another type of cookie?

Re: Making Session Jacking a Nightmare

Posted: Wed Aug 22, 2012 11:09 pm
by Jackolantern
If someone can get the session ID out of the session management cookie, it is simply a matter of typing it into the URL with some simple Javascript, or using one of the many plugins available that allow you to easily change all cookie values (swap your session ID for the stolen one). Now how someone gets your session ID is the varied part. Of course the easiest way is to be "on the line" somewhere. If you have access to a router that the data crosses through, you can sniff the data transferred (and since the cookies are sent with every request, it isn't like you only have one chance to get it). This is where SSL comes in, to protect you from malicious hardware owners or other people with this access.

Beyond being on the line, the other techniques are as varied as the targets they are aimed at. However, there is one mistake amateurs often make, and that is allowing PHP to fall-back to GET-based session management if the user is rejecting cookies. I don't think I have to tell anyone that appending session IDs into the URL in a GET style is disastrous. The user will usually be completely unaware that this has happened, and can share the URL with their session ID intact.

Another way to exploit GET-based session ID management that is extremely common, particularly when combined with phishing techniques and social engineering, revolves around getting the target to use your own session ID. An official-looking email is sent to the target and the URL for the site has the hacker's own session ID appended to the end of it. The email tries to get the user to login as fast as possible using that link. With online games, the threat is usually a banning of the account if they don't act. Once the target logs in, the hacker then has the target's session stored in their own session ID! Session regeneration is typically the way to keep this kind of hijacking from happening.

Re: Making Session Jacking a Nightmare

Posted: Thu Aug 23, 2012 12:18 am
by Callan S.
Interesting! Thanks, Jack :)

Re: Making Session Jacking a Nightmare

Posted: Thu Aug 23, 2012 12:39 am
by Luke111
Yes, Jack! You are absolutely correct!
This line of code is probably the most important in that whole tutorial I wrote:

Code: Select all

session_regenerate_id(false);
 
That is the one that regenerates the session ID.

Re: Making Session Jacking a Nightmare

Posted: Thu Aug 23, 2012 12:52 am
by Jackolantern
Most definitely! That simple line of code can kill about 50% of session fixation/hijacking attempts. Why it isn't the default in PHP, I will never understand :P