LinkedIn Cookie Vuln.

linkedin-cracked

LinkedIn is a business-oriented social networking site. Founded in December 2002 and launched in May 2003, it is mainly used for professional networking. As of 22 March 2011, LinkedIn reports more than 100 million registered users, spanning more than 200 countries and territories worldwide.

There exists multiple vulnerabilities in LinkedIn in which it handles the cookies and transmits them over SSL. This vulnerability if exploited, can result in hijacking of user accounts, and/or modifying the user information without the consent of the profile owner.

 

Executive Summary

Name: LinkedIn SSL Cookie Vulnerability (SESSION and AUTH TOKEN)

SeverityHigh

Host(s): https://www.linkedin.com and http://www.linkedin.com

Author/Contact Person: Rishi Narang  ( Twitter: @rnarang | Mail: rishi[at]wtfuzz.com | LinkedIn: http://in.linkedin.com/in/rishinarang )

PS: I received some comments recently through different mediums & channels, so, if you need any details or clarifications please contact me through Twitter and/or Mail address as mentioned above.

Background Information

LinkedIn can be accessed over HTTPS and HTTP connections. The sign-in pageif accessed on HTTPS, redirects you to HTTP on successful authentication. By default the welcome page stores the following important cookies (highlighting only the SESSION and AUTH TOKEN in scope),

After successful login (over HTTPS or HTTP), the value of cookies should change, specifically, the JSESSIONID and AUTH_TOKEN. The SESSIONID remains the same no matter what or if the browser exits, the server sends a new SESSIONID. Now, lets see how leo_auth_token changes after successfully authentication and login …

linkedin_cookies1

JSESSIONID

Ideally this cookie is used for tracking session and thus it has an ID generated to track that session in the application and server logs. As per information available online, JSESSIONID cookie is created/sent when session is created. Session is created when your code calls request.getSession() or request.getSession(true) for the first time. If you just want get session, but not create it if it doesn’t exists, use request.getSession(false) — this will return you a session or null. In this case, new session is not created, and JSESSIONID cookie is not sent. This also means that session isn’t necessarily created on first request; you and your code is in control when the session is created.

Example: JSESSIONID="ajax:2960939797451683300" . And, the syntax for this session id is –> ajax:<19 digit code>

LEO_AUTH_TOKEN

There is not much information available on this cookie in my knowledge, but I could relate some sections as following.

Example: leo_auth_token="LIM:118607520:a:1305884679:b42ee51919add89581a0b49ebe1e420dbb93a468"  (Only highlighted key reference available below)

  1. 118607520: This is the User ID. It can also be verified when viewing someone’s profile. It traverses in the traffic unencrypted and is also available in GET requests.
  2. 1305884679: This is ‘perhaps’ (guess analysis) the user login counter (global). I am not sure if it resets or its just progressive but, surely with every login it increments by 1. Special thanks to Julio for clarification that this is a Unix Timestamp of the time user logs in. (Refer: http://www.onlineconversion.com/unix_time.htm). This Unix Timestamp will also decide the expiry date of the cookie. (1 year from this time which is too much for an attacker)
  3. b42ee51919add89581a0b49ebe1e420dbb93a468: This is a approx. 40 character long hexadecimal string. It can be smaller or larger and is not fixed in length. I am still working if this can be decrypted or can be related/tied to some part of the session.

In general these two (2) cookies are enough to verify a session, and both the cookies have to be defined in "quotes" and here is a sample POST request (used in LinkedIn status update) for reference,

POST http://www.linkedin.com/share?submitPost= HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: leo_auth_token="LIM:118607520:a:1305884679:b42ee51919add89581a0b49ebe1e420dbb93a468";JSESSIONID="ajax:2960939797451683300"

ajax=true&postText=TEST_STATUS&postVisibility=EVERYONE&csrfToken=ajax:2960939797451683300

This request results in changing the User Status on the profile page. So, what and where is the vulnerability here?

Vulnerability Information

There are two (2) vulnerabilities in reference to the cookies (communication channel and session lock) as explained below,

1. SSL cookie without secure flag set

It means that all the cookies including the JSESSIONID and LEO_AUTH_TOKEN are available in plain text over unencrypted channel of communication. These cookies appear to contain session tokens, which may increase the risk associated with the authentication procedure. One should review the contents of the cookies to determine their function and the need for encryption.If the secure flag is set on a cookie, then browsers will not submit the cookie in any requests that use an unencrypted HTTP connection, thereby preventing the cookie from being trivially intercepted by an attacker monitoring network traffic. If the secure flag is not set, then the cookie will be transmitted in clear-text if the user visits any HTTP URLs within the cookie’s scope.

Impact

An attacker may be able to perform an MITM attack, and thus capture these cookies from an established  LinkedIn session. Even if the domain which issued the cookie does not host any content that is accessed over HTTP, an attacker may be able to use links of the form https://www.linkedin.com to perform the same attack.

Workaround

The secure flag should be set on all cookies that are used for transmitting sensitive data when accessing content over HTTPS. If cookies are used to transmit session tokens, then areas of the application that are accessed over HTTPS should employ their own session handling mechanism, and the session tokens used should never be transmitted over unencrypted communications.

2. Cookie Expiration & Session Handling

It means that the cookie for an authenticated session is available even after the session has been terminated or way beyond the date of expiry (instead compared to session logout, it is valid for 1 year). There are examples where cookies are accessible to hijack authenticated sessions. And these cookies are months old (literally). As a result, in just 15 minutes, I was successfully able to access multiple active accounts that belong to individuals from different global locations. They would have login/logged out many a times in these months but their cookie was still valid.

Even though the cookie expiry date is mentioned still the cookies are valid. Why does LinkedIn keeps the cookie active even if the user has "logged out" and closed the session? Worse, when the same has been done a hundred times!

Impact

As a result of valid cookies, an attacker can sniff the cookies from clear-text session (explained above), and then use it to authenticate its own session. He can then compromise and modify the information available at the user profile page.

Workaround

The expiry date/time should be locked with either a fixed ‘period’, or user’s session logout or IP etc. In absence of a fixed and reasonable expiration time period (1 year is not reasonable/acceptable), a cookie is active even after months and year of its authentication. Define expiration as the end of session or till the JSESSIONID is valid.

Curious case of JSESSIONID

As I mentioned about the JSESSIONID above, ideally the session should be mapped with this ID, and if tampered with, should disconnect the session. At least, I would believe it to work this way! But now, even if you change the JSESSIONID to ajax:0000000000000000000 (ajax followed by 19 digits) the session is still valid and the server continues accepting requests with this JSESSIONID.

Even if it has nothing to do with session but only tracking, tinkering with SESSION id surely will dangle the tracking at the server end.

LinkedIn Status Update Bash Script (Download Here)

Here is a small script to update the status at the LinkedIn profile page through command-line. It takes the input as "LIM:XXXX" cookie value and new status update.

#!/bin/bash

clear
echo ""
echo " =================================================="
echo " #          LinkedIN Status Update Script         #"
echo " #          —————————–         #"
echo " #      Author: Rishi Narang (rishi@wtfuzz.com)   #"
echo " #               — WWW.WTFUZZ.COM –             #"
echo " #                                                #"
echo " =================================================="
echo ""

echo -en " – Auth Cookie (Format – LIM:XXXX): "
read LIM

echo -en " – New Status: "
read UPDATE

curl -s -b "leo_auth_token=\"${LIM}\";JSESSIONID=\"ajax:0000000000000000000\"" -d\
"ajax=true&postText=$UPDATE&postVisibility=EVERYONE&csrfToken=ajax%3A0000000000000000000"\
http://www.linkedin.com/share?submitPost= -o linKIN.tmp

echo ""
OUT=`cat linKIN.tmp | grep "SUCCESS" | wc -l`
DUP=`cat linKIN.tmp | grep "DUPLICATE" | wc -l`

if [ $OUT -eq 1 ]
then
        echo -e "MSG: Status updated successfully!\n"

elif [ $DUP -eq 1 ]
then
        echo -e "ERROR: Duplicate Status! Please enter a new status.\n"
        exit
else
        echo -e "ERROR: Please try again later.\n"
fi
rm -rf linKIN.tmp
echo ""

#EOD

bash
 
This is all from my side, and use this information responsibly till LinkedIn fixes the vulnerability!
 
REAL SCENERIO
You are connected in a network at office or home and someone captures the cookies in traffic or uses Firesheep and boom! your account is hijacked. You as a user will not come to know that the cookie is stolen or there have been any parallel login by the attacker. And, LinkedIn doesn’t maintain any list of IP addresses (for a user to view at his account) that are being used to access your account as does the Gmail etc.
After some recent developments and some miscommunication, I will make it clear that the password change and then login with new password will expire the old cookie. Only the password change, will keep the old cookie alive so you need minimum 1 time login to let the old cookie expire out. Here is a working video of the vulnerability and how the change of IP address, session logout etc. doesn’t expire the cookies.
 

 
On some requests here is a process to show how the cookie validity maintains even after the password is changed (but before a user authenticates with new credentials)
 
 
Disclaimer:
The author is not responsible for the misuse of the information presented in this blog or anywhere on the domain www.wtfuzz.com. The ideas discussed on this site are simply ideas and the site or the owner will not be held accountable for any losses or gains that one accrues, if any way linked to the ideas on the site. Examples and methods presented on this post or anywhere on www.wtfuzz.com pages are for educational purposes only.
Tweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+Pin on PinterestShare on TumblrShare on Reddit
May 21st, 2011 | Filed in: Hacking, Security | Trackback
Author: Rishi Narang
  1. Julio
    May 22nd, 2011 at 11:31 | #1

    Hi!

    This is a great article, bue let me comment you one thing.

    In the LEO_AUTH_TOKEN, the second part is a Unix timestamp of the time the user log in:

    1305884679 -> Fri, 20 May 2011 09:44:39 GMT

    You can see it here:
    http://www.onlineconversion.com/unix_time.htm

    Best regards!

  2. May 22nd, 2011 at 11:47 | #2

    Thanks a lot Julio. I appreciate your input and will correct it. That’s the reason it was being incremented :)
    Cheers!

  3. May 23rd, 2011 at 08:32 | #3

    just some input,

    this behaviour is not new per linkedin.

    also i didn’t tried updating a status however adding a friend or responding to message will always push you back to the authentication prompt not sure if it could als obe circumvated……..

  4. Cheryl
    May 23rd, 2011 at 13:09 | #4

    Hello, I just checked my cookies on Safari, and the Linkedin cookie in question Leo_auth_token expires June 11, 2011, however, there is one cookie “bcookie” a linkedin cookie that expires in 2078- perhaps you can tell me if that cookie is an issue. May 23, 2011 date comment date

    • May 23rd, 2011 at 13:26 | #5

      Hi Cheryl,

      Please login/logout from your linkedin session, and then check back the new cookies. May be you are checking the old session that is already available. Or do one thing .. Check the leo_auth_token and NOT the s_leo_auth_token. There you will find something like LIM:xxxx:a:xxxxxxxxxx:[long string of hex chars]. Take the italicized number (the long number perhaps 10 digits just after “a”) and verify it against http://www.onlineconversion.com/unix_time.htm. This is the time the cookie registered in your browser. Check it and see what time does it show.

      Cheers!

  5. Deepak
    May 23rd, 2011 at 14:53 | #6

    3rd String looks like MD5 to me

    • Deepak
      May 23rd, 2011 at 14:56 | #7

      Nevermind, I didn’t see string size.

  6. pouet
    May 23rd, 2011 at 14:57 | #8

    For the last argument, you may be interested in this link which gives a large sample of hashed values: http://www.insidepro.com/hashes.php

  7. praveen
    May 23rd, 2011 at 21:38 | #9

    you are so smart or you think so.

    everyone in this world knows about this kind of vulnerability in every possible social site.
    are you new to this world?

    ========

  8. May 24th, 2011 at 03:59 | #10

    Very good analysis and findings…..

  9. praveen
    May 24th, 2011 at 04:19 | #11

    ok now, y did u block my comment?

  10. May 24th, 2011 at 04:32 | #12

    Hi Rishi,
    nice observation. however besides updating status are you able to do anything else with the cookies….

  11. Gooner
    May 24th, 2011 at 05:28 | #13

    So what’s so special about this discovery ? Every cookie based web-app is vulnerable to this flaw. I can’t believe someone of your caliber didn’t get that the 10-digit string was timestamp in Unix format. Sucks !

  12. May 24th, 2011 at 05:28 | #14

    @Praveen – Glad someone from LinkedIn responded. Okay, so you are insecure because others are insecure. That’s a nice answer to say you are proactive for privacy and security. So, your point is to find a unique vulnerability which is not there in competitive portals. I never mentioned that your vulnerability is alienated. Its very much belonging to the social sites issues. Appreciate your comments but still don’t wanna flame anything here ..

    Still, for your reference, a small example is – your “other social site” is not redirecting me from my chosen “HTTPS” to “HTTP” without my consent. Maybe you should try fixing it before welcoming me to this world! When I start my session on HTTPS, authenticate it then why LinkedIn redirects me to HTTP when I click any menu-tabs.

    Then, “other social site” has usually set the auth cookie expiry to “End of Session” rather than “1 year”.

    I expected LinkedIn to lead the social networking competition rather than following the lame practices of “other social sites”. I personally have high hopes and expectations from LinkedIn like other Senior Execs, rather than teenagers oriented “other social sites”. Other sites are already in much of a trouble with privacy issues etc.

    Take it with a positive attitude for better security, or keep following others’ flaws on the foot prints of their software engineers …

  13. May 24th, 2011 at 05:39 | #15

    Thats really a good article and the explanation was very brief that even a fresher can understand what exactly happening over backend in LinkedIn. Thanks for the share – keep it up

  14. May 24th, 2011 at 09:22 | #16

    Hats off to Rishi Narang for the findings and big kick to Praveen.

    Not long back, image script vulnerability in orkut was discovered. Which was big security threat back then. Someone needs to discover the threats and deserves the appreciation.

  15. Jun 1st, 2011 at 15:50 | #17

    i think linkedin should hire him as a consultant

  16. Technologically challenged
    Mar 20th, 2012 at 20:23 | #18

    Hi Rishi –

    I’m overwhelmed by the LinkedIn security issues, but forced to address the issue because I’m sure someone has accessed my account. Could you once again repeat the simplest way for me to confirm my suspicions , and safeguard my account?

    Thank you for your help and patience! I am still learning about internet security and have a loooooong way to go.

  17. Jun 27th, 2012 at 21:11 | #19

    Hi Rishi, Thank you, it makes some sense. I had always suspected that some people know what I am doing on Linkedin, like what is sent in my inbox, and who I am trying to get connected. Even lately got connected with someone I never invited or accepted the invitation. I am an ordinary user of Linkedin and don’t have your kind of expertise. I had set the browser only to accept the cookies for the session, can this help?

  18. Kirtar
    Apr 9th, 2013 at 06:11 | #20

    I think this has been patched. Isnt’t it?

    Regards,

    Kirtar

Show Hide 56 trackbacks