How I Defeated LinkedIn’s 3rd-degree Profile Security
This issue is already patched by LinkedIn House Security and disclosed after a responsible disclosure.
It was an early morning and I was in the middle of a submission of an assignment at my college. I got an email from LinkedIn displaying the people who viewed my profile. This made me log into LinkedIn for a while to have a look what’s new. I saw a random profile who was a 3rd-degree relation. I really wanted to view the profile for some reason. At the very same time I was viewing Olivia Maree’s LinkedIn profile. Well, she is a manager at Bugcrowd and a good friend of mine. I always keep an eye on the URLs 😉 so after viewing both profiles and analyzing the web application carefully that morning I got some tricky ideas in my head. I will explain from the beginning so that you can understand the process well. Let’s start fuzzing 🙂
GET /profile/view?id=31594124&authType=name&authToken=HM8p&trk=prof-sb-browse_map-name HTTP/1.1
As she is already connected in my profile so after having a look at the GET request the “authType” parameter has a value of “name” and the token parameter is “authToken”, it has a value of “HM8p”. This is her profile.
LinkedIn has option to export the profiles as PDF files. Next let’s have a look at how the web application accepts the Export to PDF option.
GET /profile/pdf?id=31594124&locale=en_US&authType=name&authToken=HM8p&pdfFileName=OliviaMaree&
disablePdfCompression=true&trk=pdf_pro_full HTTP/1.1
After passing this GET request to the application we can download the profile in PDF format. But notice the “authType” and “authToken” parameters carefully. Their values are same in both GET requests we sent. The token “HM8p” is generated for the value “name” in the parameter “authType”.
I think now you can understand that the token is same for all the requests made to the application and this token should be valid for the “authType” parameter. This analysis is for the profiles that are already connected to my account. Now let’s have a look at the other profile whose position is at a 3rd-degree. As I am a free user I have no rights to view this profile, the full name and of course can’t connect to them. I need to upgrade my account for all of these to be done.
Let’s have a look at how the application handles the GET request.
GET /profile/view?id=270880908&authType=OUT_OF_NETWORK&authToken=MNn5&locale=en_US&srchid=2898459041388819694727&
srchindex=24&srchtotal=176605&trk=vsrp_people_res_name&trkInfo=VSRPsearchId%3A2898459041388819694727%2
CVSRPtargetId%3A15899350%2CVSRPcmpt%3Aprimary
HTTP/1.1
This time the parameter “authType” has a value of “OUT_OF_NETWORK” and token corresponding to that is “MNn5”.
I noticed that 3rd-degree profiles too had the option Export to PDF. But this will let us view an incomplete PDF with only the Summary. Too bad right? 😕 Let’s have a look at that GET request.
GET /profile/pdf?id=270880908&locale=en_US&authType=OUT_OF_NETWORK&authToken=MNn5&pdfFileName=LaurenS%2E&
disablePdfCompression=true&trk=pdf_pro_full HTTP/1.1
Yes my guessing is right. The token generated is same for the value in the “authType” in every request we make. This is the incomplete PDF for free users.
Now let’s fuzz the request and see. I did many tests based on the request on the Export PDF and with the original but finally this is what I came up with it. I thought of changing the “authType” parameter to the value “name , I know that this is incorrect as we don’t know the exact token for the value “name”, but let’s give it a try. 😉 I used “name” because it is the default value passed for profiles already connected in my account.
GET /profile/view?id=270880908&authType=name&authToken=MNn5&locale=en_US&srchid=2898459041388819694727&
srchindex=24&srchtotal=176605&trk=vsrp_people_res_name&trkInfo=VSRPsearchId%3A2898459041388819694727
%2CVSRPtargetId%3A15899350%2CVSRPcmpt%3Aprimary
HTTP/1.1
The page loaded fine no big change to be seen but to my surprise I saw that the token had changed in the Export-PDF request 😯 . Let’s have a closer look.
GET /profile/pdf?id=270880908&locale=en_US&authType=name&authToken=4ZoF&pdfFileName=LaurenS%2E&disablePdfCompression=true
&trk=pdf_pro_full HTTP/1.1
This is amazing! The web application generated us a valid token for the parameter “authType” for the value “name”. I forwarded the request and voilà?! I got the full profile in a PDF format 🙂
So the application generated us a valid token for authType=name right? Let’s apply it to the original request and see 😉
GET /profile/view?id=270880908&authType=name&authToken=4ZoF&locale=en_US&srchid=2898459041388819694727&srchindex=24&srchtotal=176605&
trk=vsrp_people_res_name&trkInfo=VSRPsearchId%3A2898459041388819694727%2CVSRPtargetId%3A15899350%2CVSRPcmpt%3Aprimary HTTP/1.1
As we got a valid token for “name” w00t! we have her full name, full profile and can connect to her 🙂
If you didn’t get anything so far for greater clarity watch this proof of concept video. I made it very simple excluding the fuzzing parts.
After researching this I reported this issue directly to LinkedIn Security using their PGP key. Got an awesome reply.
Now the issue is patched and I am getting a small token of appreciation 😉
Thank you very much guys. I am glad to responsibly report this to you. This is one of the best logical bugs ever researched in my life.
I thought of answering some of the questions that you guys frequently ask me since I started this blog.
What is the difference between security researching and penetration testing?
To explain in my own terms, penetration testing uses automated tools and the goal is to test the security by penetrating like an attacker and to find maximum number of loop holes by providing proof of concepts. For that you need higher permissions to scan, do vulnerability assessments and to exploit. But security researching is not firing up tools like kids and tools can find only the standard vulnerabilities which are very common. Researching is very beautiful, sometimes I end up bypassing things, finding logical issues, it is something like that. I just study the application well, how the application interacts with the end-user and come up with different ideas to fuzz. I don’t use any vulnerability scanning tools as the owners of these organizations can do it and we don’t need to bother about it. Sometimes in researching you may find different kind of vulnerabilities in which sometimes hard to find the root cause. From my experience I am telling this. Recently I found a XSS and a possible SQLi in a very famous CMS, even though it had very tight filters a small error led me to these vulnerabilities as a result of fuzzing. Likewise fuzzing can lead to many findings.
Do you need to be a professional in programming?
Well, you don’t need be a professional programmer as long as you can think differently and break things. But programming is indeed needed, knowing a language becomes handy in developing your own exploits, leveraging exploits, automating things and so on. Better to know many languages as possible at least from the scratch so you could survive at any given technology and it is useful when developing exploits for different platforms. Knowing the language makes you understand things broader and get to know what’s really going on. I myself am not a big programmer and I don’t like developing apps, but I really love to break things and to make things that break things.
For this month I can be glad that I have reported vulnerabilities, security issues in more than 40 organizations with responsible disclosure policies 🙂 I really respect those guys for having a responsible disclosure policy. Some people don’t care about security because they don’t like to admit their weaknesses. Anyhow a vulnerability is a vulnerability no matter size of the risk. Thank you all for humbly responding to my reports and fixing them in a timely manner. I am still young and got many things to explore and learn. I am happy to happy have achieved up to this at a age like this. In every bug I’ve found there is a story to share. Hope to escalate my knowledge further in the field of computer security. Finally I would really like dedicate this to my friends who was with me since the past my bud Hood3dRob1n, Gerardo Salazar, Billie Kei, Matt Andreko, Kasp3r, Alan Marecc, Tom, Guy Márquez and all my friends (some don’t like to mention their names) who’ve cared for me. Without you guys my life will be in darkness. Also I dedicate this to my recent friends Muhammed Gazzaly, Ajay Negi, Fraph Core, Yap AhmadAshraff, Jay Turla, Rishiraj Sharma. I wish that we can meet someday. Some things are hard to explain 😉
Signing out
Osanda~!
Update: Got posted as a guest post on Bugcrowd http://blog.bugcrowd.com/bypassed-3rd-degree-profiles-linkedin/
nice. keep on sharing 🙂
awesome bro.. hope you will teach me ..
Well explained and wonderful tutorial bro 😀 Thanks for taking the time to wrote this 😀
Thanks bro and congratulation ! Good work 🙂
Really.. Awesome 😀 !!! Something New got in Market of WebAppSec Research … 😀 Keep Going !!!
Cool and thanks for mentioning my name. I wish that I could also meet you someday 🙂
Good work bro (Y)
Awesome, Congrat bro!
my old friend <3 , wish you a great career in IT security
Nice post bro. Very well explained, a new lesson learned today and by the way, you could be a teacher. 🙂
Excellent article my brother, You keep improving by the day.
Keep up the awesome work and keep on exploring 😀
great research!
good work machooo keep going !!!
Thank you all for the feedback 🙂
gr8 bro…u do always the best…keep go on…
keep it up brotha! 🙂
You and all people in greetz are all my brothers, I’m happy to see all stay our friends (special greets to you, HR, Guy, Alan, HR, Kasper & Billie). I love you all.
Thanks mate 🙂
Way to go bro!!! I wish you all the very best for your future.
This is cool. All the best man!