Thursday, September 26, 2013

Hacking Twitter for Fun - XSRF in Account Settings Change

Though for last few months i'm not much into web application security, But still I feel Web App Sec. is fun. For a special requirement I had to develop a web application security assessment tool ( I think it will be better if I call it Fuzzer) and it was time to give it a real life challenge. I named this tool Burpy. because this tool is totally dependent on very famous application security assessment tool Burp.

Using this tool you can easily write your own web application specific plugins to automate various test cases.  You have to feed this tool a Burp suite traffic log (XML dump of http request & response). And depending on the module you write, this tool performs various test cases on the raw http request present in burp suite log.

You can find the details of this tool on my Git Hub Page.

I decided to test it on twitter.com first and unexpectedly I found a very simple yet critical Cross Site request Forgery vulnerability in twitter application.

I started surfing twitter randomly and at the same time burp proxy was enabled and it was logging all request response(twitter traffic). If you've ever played with twitter application before, you may aware of this issue that, if you send any request without CSRF token, twitter application throws a generic error message. And csrf token parameter name is also fixed.

So after that I quickly wrote a tiny Burpy plugin which simply automate below points:


  1. Check if CSRF token present in raw request.
  2. If csrf token present , then it will simply remove the token from request and resend the crafted request.
  3. If the generic error message is present in response body, It means server side check of csrf token is properly implemented hence it will return FALSE else it will return positive response and burpy will write that crafted request and response to final HTML report.


After that I quickly exported the traffic from burp suite (Twitter traffic) and quickly ran the tool on the dump.



It took nearly 5-6 minutes to test all(~~140) request present in the burp log, When its over I opened up the HTML report generated by it and found total 7-8 suspicious/interesting server response. Out of those I found 2 request which was looking interesting. Most critical one is covered in this post .The vulnerability was present in account settings change module. If you've ever played with twitter application you should know that, all profile information changes are handled by this url at server side.

https://twitter.com//settings/accounts/update

Base Request found from Burpy report:


POST /settings/accounts/update HTTP/1.1
Host: twitter.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://twitter.com/settings/account
Cookie: <removed>
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 670

_method=PUT&authenticity_token=88ab8ef7388e544f1c8f22d58xxxxxxxxxxxxxx&user[screen_name]=debasishm89&user[email]=myemail@gmail.com&user[discoverable_by_email]=1&user[discoverable_by_email]=0&user[lang]=en&user[time_zone]=New+Delhi&user[geo_enabled]=1&user[geo_enabled]=0&user[nsfw_view]=1&user[nsfw_view]=0&user[nsfw_user]=0&user[protected]=0&user[use_cookie_personalization]=1&user[use_cookie_personalization]=0&asked_cookie_personalization_setting=1&user[allow_ads_personalization]=1&user[no_username_only_password_reset]=0&user[login_verification_type]=off&user[country]=xx&auth_password=



Crafted Request found from Burpy report:


POST /settings/accounts/update HTTP/1.1
Host: twitter.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://twitter.com/settings/account
Cookie: <removed>
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 670

_method=PUT&&user[screen_name]=debasishm89&user[email]=myemail@gmail.com&user[discoverable_by_email]=1&user[discoverable_by_email]=0&user[lang]=en&user[time_zone]=New+Delhi&user[geo_enabled]=1&user[geo_enabled]=0&user[nsfw_view]=1&user[nsfw_view]=0&user[nsfw_user]=0&user[protected]=0&user[use_cookie_personalization]=1&user[use_cookie_personalization]=0&asked_cookie_personalization_setting=1&user[allow_ads_personalization]=1&user[no_username_only_password_reset]=0&user[login_verification_type]=off&user[country]=xx&auth_password=


The BUG:

As you can see,an anti CSRF token is present in this base request which is "authenticity_token". At glance which was looking fine and quite secure. But the interesting part was, when Burpy removed the CSRF token from the http request and replayed the request, It did not get the generic error message in response body. After manually repeating the step I found that, the server side logic was actually getting failed to validate the token and it was accepting the request.

Now when I went back to my settings page I found all changes I have made are getting reflected. BINGO!!

Another interesting thing you many notices in twiiter that, to change any profile settings if you go to "https://twitter.com/settings/account" page and make any changes, you will find the twitter application will ask you to re-enter your password. In this case even it was not required.

Its time to reproduce the BUG from Twitter:


So from Burpy report I got the crafted request/response but I had really hard time to reproduce this issue because, it was clear that I had to remove csrf token from the POST request but I was unable to find out above mentioned POST parameter combination in any request that twitter sends. I went to settings page made some chnages and when I was clicking save I found that POST parameter combination was not same which were reported by burpy. Spend a whole day to solve that mystery. But finally I found that it was actually one regular expression bug in Burpy which was polluting few POST parameters. And the best part was without that this bad things wont workout.






I hope I don't have to explain much about the criticality of this bug.

Another similar issue I've found on twitter : Here

On 31st August I reported this & this issue to twitter security team using their online form.
Received response from one engineer at Twitter Security Team on 3rd September'2013 saying they have received the report and not to twit or blog about this issue as they are working on a fix.



Twitter fixed this issue pretty fast. On 4th of September I've received one email from Twitter Security Team saying, that the issue is fixed and they need confirmation from my side.



And the last but not the least - The Ultimate CV Builder :D

Twitter doesn't pay security researchers for bugs but they do have a Hall of Fame Page for White Hat Security Researches. So they have added me in that White Hat page. :)