http://www.perlmonks.org?node_id=658937
Category: Web Stuff
Author/Contact Info davidov0009 <http://perlmonks.org/?node_id=574522>
Description: A program that races a given Facebook account 10 times using the petrolhead racing application. (to gain you points) See POD for more details.
#!/usr/bin/perl

use LWP;
use HTTP::Cookies;
use strict;

####
#
# petrolhead.pl - written by davidov0009 <http://perlmonks.org/?node_i
+d=574522>
#
####

# check argument
if ( !defined( $ARGV[0] && $ARGV[1] ) ) {
    die("\n Usage: perl petrolhead.pl email\@domain.com password \n Re
+quires a Facebook login email and password as arguments \n");
}

if ( $ARGV[0] !~ m/^[\_]*([a-z0-9]+(\.|\_*)?)+@([a-z][a-z0-9\-]+(\.|\-
+*\.))+[a-z]{2,6}$/) {
    die("\n Please enter a valid email \n");
}

# assing account values
my $login = $ARGV[0];
my $password = $ARGV[1];

# UserAgent attributes
my $user_agent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1
+.8.0.6) Gecko/20060728 Firefox/1.5.0.6";

my @header = (  'Referer' => 'http://www.facebook.com/', 
                'User-Agent' => $user_agent);

my $cookie_jar = HTTP::Cookies->new(
                file => 'cookie_file.dat',
                autosave => 1,
                ignore_discard => 1);

my $browser = LWP::UserAgent->new;

# set 302 redirection for POST
push @{ $browser->requests_redirectable }, 'POST';

$browser->cookie_jar($cookie_jar);

# get challenge code from index
my $response = $browser->get('http://www.facebook.com', @header);
$cookie_jar->extract_cookies( $response );

# Strip challenge code from the returned HTML
my @names = qw( challenge );
my %form  = strip( $response->content, 'login', @names );

# post login info
$response = $browser->post('https://login.facebook.com/login.php', \%f
+orm, @header);

$cookie_jar->extract_cookies( $response );

# check response, print info
if ($response->is_success) {
    print "Login $login: ok \n";
}

# since we are logged in, display the account homepage
@header = ( 'Host' => 'facebook.com',
            'User-Agent' => $user_agent,
            'Connection' => 'keep-alive');

$response = $browser->get('http://www.facebook.com/home.php', @header)
+;

if ($response->is_success) {
        print "Fetch home.php: ok \n";
}

$cookie_jar->extract_cookies( $response );
$cookie_jar->save;

my $race_num = 0;

# race 10 times
while ($race_num < 10) {

# go to petrolhead race page
@header = ( 'Referer' => 'http://hs.facebook.com/home.php?',
            'User-Agent' => $user_agent,
            'Connection' => 'keep-alive');

$response = $browser->get('http://apps.facebook.com/petrolhead/friends
+.php', @header);

#get form inputs for POST (intial race page)
@names = qw( fb_sig_time fb_sig_user fb_sig_profile_update_time 
            fb_sig_session_key fb_sig_api_key fb_sig fid src );
%form = strip ( $response->content, 'race1', @names );

fakewait();

# POST variables to racing.php (1st time)
@header = ( 'Referer' => 'http://apps.facebook.com/petrolhead/friends.
+php',
            'User-Agent' => $user_agent,
            'Connection' => 'keep-alive');

$response = $browser->post( 'http://apps.facebook.com/petrolhead/racin
+g.php', \%form, @header);


#get form inputs for POST (race validation page)
@names = qw( fb_sig_time fb_sig_user fb_sig_profile_update_time 
            fb_sig_session_key fb_sig_api_key fb_sig fid src );
%form = strip ( $response->content, 'race2', @names );

# POST variables to racing.php (2nd time)
fakewait();

@header = ( 'Referer' => 'http://apps.facebook.com/petrolhead/racing.p
+hp',
            'User-Agent' => $user_agent,
            'Connection' => 'keep-alive');

$response = $browser->post('http://apps.facebook.com/petrolhead/racing
+.php', \%form, @header);

# increment the race number
    $race_num++;
    print "Race number: $race_num \n";
}


#subroutines below

#strips hidden form values from html source, adds other values, return
+s a hash
sub strip {
    
    my ($html, $token, @fields) = @_;
    my %post;
    
    foreach my $element (@fields) {
        if ($html =~ m/name="$element" value="(.*?)"/) {
            $post{$element} = $1;
        }
        else {
            die("\n Match not found in subroutine strip \n Might have 
+been an unsuccessful login (check email and password) \n");
        }
    }
    
    if ( $token eq 'login' ) {
        $post{'md5pass'}             = '';
        $post{'noerror'}             = '1';
        $post{'email'}               = $login;
        $post{'pass'}                = $password;
        $post{'doquicklogin'}       = 'Login'; 
    }

    elsif ( $token eq 'race1' ) {
        $post{'fb_sig_added'}        = 1;
        $post{'fb_sig_expires'}        = 0;
        $post{'submit'}                = 'Race!';
    }

    elsif ( $token eq 'race2' ) {
        $post{'fb_sig_added'}        = 1;
        $post{'fb_sig_expires'}        = 0;
        $post{'confirm'}            = 'Yes! Let&#039;s Go Racing!';
        $post{'verified'}            = 'YES';
    }
    
    elsif ( $token eq '' ) { return %post }

    else { die("No token for adding other form variables specified: $!
+") }
    
    
    return %post;
}

# waits a random amount before continuing (to avoid detection)
sub fakewait {

    use constant {
        RANGE => 5,
        MIN   => 2
    };
    
    sleep(int(rand(RANGE)) + MIN);
}

__END__ 

=head1 NAME

petrolhead.pl - automatically races Facebook Petrolhead application

=head1 SYNOPSIS

From the command-line:

    $ perl petrolhead.pl email@domain.com password

=head1 DESCRIPTION

Warning: You may have your facebook account removed for using this pro
+gram. Use at your own risk.

This program was made to automate the Facebook (http://www.facebook.co
+m) application Petrolhead.  Given the login email of
a Facebook account and its password as arguments on the command-line t
+his program will login and race that particular account 10 times
against the first race link found on the "Race My Friends" page.  

The typical setup is done with a fake account whose only petrolhead fr
+iend is your main petrolhead account. This allows you
to have your main petrolhead account raced without you reaching your r
+ace limit. It also gives you a lot of points.  This program
can be made to work with an external program that supplies several acc
+ounts to be raced.

The program features random wait times before form submission to avoid
+ detection but if you use it with multiple accounts
and within rapid succession you will increase your chances of being ca
+ught.  If you choose to build an external program to race
multiple accounts you should randomize the order in which the accounts
+ are raced and add random wait times
of several minutes or more between logins.

=head2 Functions

=over 12

=item C<strip>

strip( $html_source, $form_phase, @field_names )

Returns hidden form fields in supplied html source as a hash.
$html_source is typically $response->content. $form_phase adds form sp
+ecific values.
Valid form_phases are 'login', 'race1', 'race2' and '' (blank returns 
+original hash)

=item C<fakewait>

fakewait()

Causes program to sleep for a random amount of time between 2 and 7 se
+conds.

=back

=head1 AUTHOR

davidov0009 - <http://perlmonks.org/?node_id=574522>

=cut