Facebook: Another Linkshim Bypass
12:48 PM
I wasn't going to post about this
but it turns out, this 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 inital 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. later, this resulted some media attention
and now when I find another linkshim bypass, I taught why no one else actually
found this bypass, after the first got public. and that is one of the main
reasons I am posting this.
I am going to talk about a 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.
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 extermal 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 Facebook obviously have black listed
//
The next try should be \/evilzone.org, since most browsers render \ back to / this usually bypass the check and create //evilzone.org (you can read more about this from @homrkov’s Evolution of Open Redirection post)
So // and \/ got caught. At this
point I concluded the linkshim uses number of blacklist based checks from \\,
//, \/ and started fuzzing.
Thanks to @FransRosen, he told me about a
technique that could create this bypass. \%09/@site.com
This basically should be equivalent to
//@site.com and since the regex won’t find
\%09/ , \%0D/ or \%0A/ blacklisted, this will result // because the %09 should obviously
get ignored while parsing. And the complete linkshim bypass will look
something like:
Feb 1, 2015 6:33am - Inital 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! :-)
0 comments
Note: Only a member of this blog may post a comment.