Facebook: Another Linkshim Bypass

12:48 PM


I wasn't going to post about it then I thought it could be an interesting article to post because this is the 3rd vulnerability that got fixed in the same parameter 6 months later.

You can find my initial linkshim bypass to this exact position which later turns out to be XSS if you click here. In the first bug I found in the continue parameter, it is possible to bypass linkshim and force a redirection to a site before being checked but then, XSS. 

First I am going to talk about the relevant and great technique I learned from the prompt.ml XSS Challenge(s) 4, you can find the DOM XSS challenge here. consider the code:

function escape(input) {
    // make sure the script belongs to own site
    // sample script: http://prompt.ml/js/test.js
    if (/^(?:https?:)?\/\/prompt\.ml\//i.test(decodeURIComponent(input))) {
        var script = document.createElement('script');
        script.src = input;
        return script.outerHTML;
    } else {
        return 'Invalid resource.';
    }
}

This is the JS source code of challenge 4. they basically want you to bypass a regex to get an external redirection. And the main problem here is that it uses decodeURIComponent(), a function that decodes supplied input from URL encoding. In this case, we can trick the browser believe the prompt.ml domain (allowed by the regex) belongs to our URL. This should be very simple using HTTP auth, like http://prompt.ml@attacker.com the above URL redirects to attacker.com and should bypass the regex because having the prompt.ml.

To bypass decodeURIComponent(), we simply have to use %2f which is a URL encoded representation for the /. And our bypass is: 
//prompt.ml%2f@.ws/

The trick to solve the level with 17 characters only lies hidden in a transformation behavior some browsers apply when converting Unicode characters to URLs. A certain range of characters resolves to three other characters of which one is a dot - the dot we need for the URL. The following vectors uses the domain 14.rs that can be expressed by two characters only.”

A url that starts with two forward slashes is treated as absolute by browsers. Something similar seems to cause this issue (server-side), when given the continue parameter,

This successfully will send example.com for a check to a linkshim before external redirection which means https://m.facebook.com/feed_menu/?story_fbid=808015282566492&id=100000740832129&confirm=h&continue=http://evilzone.org should be malicious.

Now a stupid enough URL validator will consider //evilzone.org a relative location and won’t allow us create a hyperlink like <a href=”//evilzone.org”> and FB did blacklisted //. The next try should be \/evilzone.org, since most browsers render \ back to / this usually bypass the check and create //evilzone.org

But both // and \/ got caught. At this point I concluded the linkshim uses number of blacklist based checks from \\, //, \/ and attempted fuzzing.

I then was talking to @FransRosen and he mentioned about a technique that could still cause another bypass. \%09/@site.com

This basically should be equivalent to //@site.com and since their regex didn't contain \%09/ , \%0D/ or \%0A/ in its banlist, this results in // being back because the %09 will obviously get ignored while parsing.  We can keep adding as many of these in between. And the complete linkshim bypass will look something like:




Feb 1, 2015 6:33am - Initial Report
Feb 1, 2015 6:47am - More Clarification sent
Feb 2, 2015 6:11am - More Classfication asked 
Feb 3, 2015 1:04pm - Some more clarifications sent
Feb 4, 2015 11:25am - Escalation of bug    
Feb 23, 2015 11:00am - Bug Fixed
  
Thanks you for reading! :-)


You Might Also Like

0 comments

Note: Only a member of this blog may post a comment.