#!/usr/bin/perl use LWP; use HTTP::Cookies; use strict; #### # # petrolhead.pl - written by davidov0009 # #### # check argument if ( !defined( $ARGV[0] && $ARGV[1] ) ) { die("\n Usage: perl petrolhead.pl email\@domain.com password \n Requires 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', \%form, @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/racing.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.php', '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, returns 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'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 program. Use at your own risk. This program was made to automate the Facebook (http://www.facebook.com) application Petrolhead. Given the login email of a Facebook account and its password as arguments on the command-line this 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 friend is your main petrolhead account. This allows you to have your main petrolhead account raced without you reaching your race limit. It also gives you a lot of points. This program can be made to work with an external program that supplies several accounts 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 caught. 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( $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 specific values. Valid form_phases are 'login', 'race1', 'race2' and '' (blank returns original hash) =item C fakewait() Causes program to sleep for a random amount of time between 2 and 7 seconds. =back =head1 AUTHOR davidov0009 - =cut