The idea here is to determine your goals. Typically in our web app assessment engagements, our primary goal is to identify all the weaknesses in the application. While this isn't necessarily the goal of a malicious attacker, it is helpful to our clients. Attackers will typically stop at the first found vulnerability that they can exploit to achieve their goals. Remember that time, motivation and resources are determined by the attacker or the attacker's clients. I'll try to cover most of the interesting attack vectors, but the primary goal for a web app session attack is to gain control of that session and hopefully completely compromise the user's account.
The easiest way to test a web application is to have valid and legitimate credentials. This way you can log in, log out, and generally poke around to determine how everything works. On some sites this is easy as they may be a free and public service like gmail or amazon. On other sites valid credentials may still be obtained but there may be some startup costs. Any US citizen can open a Chase checking account and sign up for online banking, but it typically requires you to go to the bank and sign up. I think you see where I'm going here. Obtain some valid credentials to test how the site works from the inside. This will most often be provided by your client (after all we are talking about white-hat hacking here, not criminal behavior).
Once you have your credentials, the first quick test is to authenticate (log in) and note your session cookie value. There may be multiple cookies associated with the target site, so weed through them and identify which is the actual session cookie. Typically it will have the "session" cookie flag set. The best way I've found to narrow it down is by using the chrome plugin: edit this cookie. Here's how it goes down:
Now, we need to find out which cookies are actually identifying the session and telling amazon that indeed we are an authenticated user. We can do this by using the "flag cookie" option. This will delete the cookie and also prevent it from being set in the future (the list of flagged cookies can be edited by clicking on "options"). Below you will see that I have flagged all cookies except the ones we absolutely need to have a live session. This helps reduce complexity as well as the time it takes to attempt a session hijack and the amount of data we need to keep track of.
Now, time for our first real-test. We will open another browser or open a "private browsing" or "incognito" tab. Its best to open a seperate browser to ensure that we have complete seperation of browsing data. I'm going to go ahead and open Firefox. This will be used as the source for this example. Login to the web site on the source browser (for this excercise its firefox). Once logged in, I can grab the two session cookie data that I need to test for an account hijack.
Now, I take those two values, substitute them for the ones in my chrome window (which I logged out of) and "submit cookie changes" in the edit this cookie tool. The last step is to paste a known authenticated URL into the address bar and hit enter. If the site pulls up and you're looking at an authenticated page, it is vulnerable. If not, then the creators are doing some things right and you'll probably be redirected to the login page (the correct thing to do) or an error (possibly a 500). If you get an error, I would say that requires some attention. If possible, your web app should always fail gracefully. For this example, amazon is not vulnerable.
We talked in Part 2 about encoded cookie values. In this example it appears that amazon is using base64 encoding for the "session-token" value. If you notice in point 1 above the value ends in "=". This is the padding character that base64 encoding uses. When you see this you should always attempt to base64 decode the value and check for interesting information (burpsite decoder is great for this). In this case, it appears that they are using a binary or other proprietary data once decoded, but its base64 encoded while traversing the web. Remember, the session id is for server-side authentication and is sent with all web requests so it does not have to be readable by the browser or anything else client-side. It is merely a token. If our motivation and resources were adequate, at this point you could get into decoding the binary data. Most often the case is that it is some sort of standard library that is creating that data and time could be spent in reversing exactly what that is, but that beyond the scope of this post.
Pending the outcome of step 3, you have two paths to take:
If you are successful in step 3:
It is possible that they are using other factors to identify the correct authenticated user. This could be by their external IP address, which we haven't changed. Now re-test using another external IP (or some sort of proxy or tor) and note the results. If still successful try different browsers if you haven't already. The goal here is to identify all the unique identifiers in use if they are using more than just the session cookie value.
If you are unsuccessful in step 3:
This could be because they are using the user-agent as an additional unique identifier. To test for this, use the same browser to attempt the hijack. Also, attempt the same hijack while using the same browser (remember the OS also determines the user-agent string, not just the browser, so chrome on windows will be different than chrome on linux) on different external IPs.
This should get you a good step in the right direction when auditing the session handling for a web application. If nothing else, it presents some of the correct questions to obtain answers for.
Now, what would offense be without a good defense? Look for a future blog post about the defensive solutions to these potential vulnerabilities. Also upcoming is a step by step run-down on burpsuite, my favorite web application audit too.
Credit to JBStiles for testing procedures.