Facebook HTTP Parameter Renaming (0day) (Unfixable?)
1:57 AM
x=1&y=2
Note: Blogger coudnt let me write nullbytes so i write them as %0,0 so take it without a comma.
This function also accepts associative arrays such as:
This function also accepts associative arrays such as:
x[0]=123&x[1]=456&[2]=456
When we specify only one bracket “[“ and don’t close it, it will get converted
into an underscore. This means that the two strings below ($s1 and $2) create
identical associative arrays when parsed.
$s1 = “user_id=123”;$s2 = “user[id=123”;
parse_str($s1, $o1); parse_str($s2, $o2);
Now both $o1 & $o2 contain:
array(1){
[“user_id”]=>
string(3) “123” }
You know what that means, we can re-write any parameter
names with underscores on them using a square bracket (in this case the
redirect_uri parameter);
We can also do a similar trick with null bytes (%0,0).
However, in this case anything after the null byte in a parameter name gets
removed so both the strings below are parsed into the same array:
$user = 123
$userpleaseignoreme=123
Furthermore, Facebook’s WAF was filtering the QUERY_STRING
parameter in an attempt to prevent HTTP parameter pollution, now we can turn
requests like (in HPP):
account_ id=123&account_ id=456
into:
account_id=123&account[id=456
{Since PHP by its nature pick the last one to execute, the
second Parameter (account[id=456 which is equivalent to account_ id=456 for
PHP) will be chosen. }
Or into:
account_id=123&account_id%0,0ignoreme=456
and that’s what happened in this case, the redirect_uri (or
any other redirection parameter Facebook hosts) is being checked not to
redirect outside of Facebook, but turns out we can using this technique since
only the first parameter is being checked with that name,
So providing names like “redirect[uri=” or “redirect_uribullshit”
which is equivalent for PHP to redirect_uri, it is possible to perform HTTP
parameter renaming,
https://m.facebook.com/stickers/removepack/?pack_id=618474161568703&size=small&redirect_uri=%2Fmessages%2Fsticker%2F%3Fthread+id%3Dmid.1401627834352%253A07f5813dc760cf0461&ext=1406492798&redirect[uriignoreme=http://google.com
That is not an open redirection issue. It however could be a
linkshim evade, not sure. I reported this issue to Facebook and I am very happy
with their response, they were happy I informed them, the thing is the bug
bounty program works if there is at least one exploitation scerio which in this
case isn’t; it’s just an interesting bug. But this can be exploited with XSS or
even Session Fixation (which I don’t have at the moment) (please feel free to re-submit
this bug if you have found exploitation technique that is exploitable, would be
happy to know if you inform me how too :-D )
Fix: the simplest fix I recommend is for your WAF to recheck
the {$parameter} names and block if they contain either [ or %0,0 because
without those there seems to be no parameter renaming. To be honest, I taught
the null byte trick would be noticed by a WAF but It didn’t. More precisely
while submitting parameters, using array based tricks would still might bypass
that since the $_GET, $_POST and even the $_COOKIE global vars take arrays and
concatenates them.
Ways to exploit this and re-write HttpOnly Cookies if/with
XSS,
//using [ to replace _
document.cookie = ‘session[id=EVIL;expires=Tue, 18 Apr 2024 13:32:42GMT’;
// or extending it with
document.cookie =
‘session_id%0,0ignoremebabe=EVIL;expires=Tue, 18 Apr
2024 13:32:42GMT’;
Let’s say the session_id cookie var is set for the current
session, however, session[id is valid for 10 years. As soon as session_id
destroyed by the browser (when it closes the session regenerates or when the
user logs out) we end up with the single session[id in the browser which now
becomes the first cookie in the list,
Set-Cookie: session[id=EVIL;
Which also means session_id=evil; for php since browsers
respond cookie values both session[id=evil and consider them both to be unique,
however php uses one of them to understand who that user is, J.
2 comments
this is leet hax. keep posting man
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteNote: Only a member of this blog may post a comment.