I'm working with a site that I believe has been hacked to collect customer credit card data, but I can't be certain.

I did not find any suspicious code in the common places I've seen suggested in several articles.

I did find a suspicious "broken" image file in:


I changed the file extension and opened her up, but it's just a wall of encrypted text with JPEG-1.1 scattered about.

How can I tell if the site is compromised?

I have confirmed the patch has been applied, but the hack could have occurred prior to the patch.

EDIT: Affected version is

4 Answers 4


For the specific answer to your question see, https://magento.stackexchange.com/a/72700/361


Firstly, there is no specific exploit - there are a series of articles doing the rounds at the moment that have misread and misunderstood the source article.

The original article merely said (and I'm paraphrasing),

If a hacker were able to get access to your Magento files, they could capture information from your customer

The key part being the hacker needing to actually access your server and modify files.

Don't panic ... this is nothing specific to Magento

In terms of information capture, there is nothing specific to Magento than any other website/platform. If a hacker gets access to your files, its effectively game over - they would be able to capture whatever information they wanted to.

The best you can do (and ultimately, the minimum you should be doing) is to maintain a good security policy that adheres to the payment processing industry's PCI Security Standards, you can find the list here, https://www.pcisecuritystandards.org/documents/Prioritized_Approach_for_PCI_DSS_v3_.pdf

Harden your store

You can really lock down facets of your store that greatly reduce the surface attack area for a hacker, or at the least, slow their progress if they do manage to get in/

Lock down permissions

You can restrict permissions on the document root to only allow writing to essential directories (/var and /media)

This is what we do by default on MageStack,

echo -n "Fixing ownership"
chown -R $SSH_USER:$WEB_GROUP $INSTALL_PATH && echo " ... OK" || echo " ... ERROR"
chmod 750 $INSTALL_PATH
find $INSTALL_PATH -type d ! -perm 750 -exec chmod 750 {} \; && echo " ... OK" || echo " ... ERROR"
echo -n "Fixing file permissions"
find $INSTALL_PATH -type f ! -perm 740 -exec chmod 740 {} \; && echo " ... OK" || echo " ... ERROR"
echo -n "Fixing cron permissions"
find $INSTALL_PATH/*/cron.sh -type f ! -perm 750 -exec chmod 750 {} \; && echo " ... OK" || echo " ... ERROR"
echo -n "Fixing media/var file permissions"
chmod -R 760 $INSTALL_PATH/*/media $INSTALL_PATH/*/var && echo " ... OK" || echo " ... ERROR"
echo -n "Fixing media/var directory permissions"
find $INSTALL_PATH/*/media $INSTALL_PATH/*/var -type d ! -perm 770 -exec chmod 770 {} \; && echo " ... OK" || echo " ... ERROR"

Adjust INSTALL_PATH,SSH_USER,WEB_GROUP to suit. What is important is that your SSH_USER is not the same user that PHP uses for the web server process, otherwise, you would essentially be providing full write access to the web server (mitigating any benefits).

Lock down your admin/downloader access

On MageStack, you would set this in ___general/x.conf

set $magestack_protect_admin true;
set $magestack_protect_downloader true;

On Nginx, you could use this,

location ~* ^/(index.php/)?admin{
  satisfy any;

  allow x.x.x.x;

  auth_basic "Login";
  auth_basic_user_file /microcloud/data/domains/x/domains/x/___general/.htpasswd;

  deny all;

  location ~* \.(php) {
    include fastcgi_params;
  try_files $uri $uri/ /admin/index.php ;

There's a bit more documentation on how to prepare a .htpasswd file here

Wrap the cron.sh process

I've come across other hosting providers using dedicated machines for cron/admin usage - which means that modifying the cron.sh file would allow for remote code execution on the cron/admin without ever needing to access to it. Wrapping up the process with the right user in a fakechroot can go that bit further to locking down the process.

There's far too much code for me to post, but there's a script here. Its specific to MageStack, but could be adjusted for use on less elegant server configurations :)

Audit, audit, audit

Linux is fantastic in terms of logging and tapping into that will give you a complete insight into what your server is doing.

A fantastic feature on MageStack is the auditing tool which logs all kinds of access and even file changes on a daily basis. You can find the logs here,


If you aren't using MageStack, you can replicate some of this with your own hosting provider quite easily, rsync being the simplest tool to do it.

Eg. If your backups are locally available, you could do the following. This will dry-run compare two directories and produce a diff patch list.

rsync -na /path/to/public_html/ /path/to/backup/public_html/ > change.log
grep -E '\.php$' change.log | while read FILE; do
  diff -wp /path/to/public_html/$FILE /path/to/backup/public_html/$FILE >> php-differential.log

PHP changes are so infrequent that you could schedule this to run daily (or multiple times daily) and notify you by email if there is a PHP file change.

In summary

  • Use version control, its easier to track changes
  • Just having an SSL certificate is not enough to make your site safe
  • Don't wait to get hacked to consider security
  • Just because you redirect to your payment gateway provider (vs. capturing information) - it does not mean you can avoid PCI compliance, you still need to comply
  • Be proactive, be safe and be thorough - check module code before you install it, check PHP files daily, review logs, check FTP/SSH access, change passwords regularly

Your customers are putting an enormous amount of trust in you when they pass over all their private information - and if you betray that trust by not operating a secure business, you'll lose their custom and all future custom.

PCI forensic investigations are incredibly expensive, time consuming and ultimately risk your ability of ever being able to take card payments again. Don't ever let yourself be put in that position!

Get patched

There were a series of patches released from Magento lately that fixed holes, including some that allowed for remote-code-execution. You can fetch them here, https://www.magentocommerce.com/products/downloads/magento/

But these new articles aren't referring to a new exploit, they are simply stating how hackers are leveraging historic exploits (or any other attack vector) to be able to capture cardholder information.


  • 4
    Thanks! This is amazing writeup and a lot of very useful information. Jun 30, 2015 at 18:10

I'm adding another answer just because my other one didn't actually answer the question - and it certainly doesn't need to be any longer!

How can I verify if an image contains CC information

Ultimately, you can't. There are sometimes indicators that make it stand out,


  • Large file size
  • Presence of plain text in file
  • Incorrect image headers

But it can be particularly difficult to digest the contents of binary files to determine the contents if the content isn't merely in plain text.

The most common exploit I've seen doesn't involve writing plain text data to a file with a .jpg|png|gif|etc extension, they usually involve some kind of encoding/encryption to obfuscate the data (eg. base64 or mcrypt etc.). Which means a simple grep won't work.

You could (and this is by no means exhaustive) ...

Find abnormally large files

find \
/path/to/public_html/skin \
/path/to/public_html/media \
-type f -size +20M 2>/dev/null

Find files matching CC regex

grep -lE '([0-9]+\-){3}[0-9]{4}|[0-9]{16}' \
/path/to/public_html/skin \
/path/to/public_html/media 2>/dev/null

Check if image files are valid

find \
/path/to/public_html/skin \
/path/to/public_html/media -type f \
-regextype posix-egrep -regex '.*\.(jpg|gif|png|jpeg)' |\
xargs identify 1>/dev/null


find \
/path/to/public_html/skin \
 -name '*' -exec file {} \; | grep -v -o -P '^.+: \w+ image'

How can I check the PHP files in my installation to see if it has been modified

The easiest way to compare your install files would be to diff the core against a clean copy. This won't account for your theme files, but goes a long way to checking a few thousand files in your installation.

The process is really easy,

Eg. For Magento version

wget sys.sonassi.com/mage-install.sh -O mage-install.sh
bash mage-install.sh -d -r
tar xvfz latest-magento.tar.gz
diff -w --brief -r magento-ce-*/app/code/core app/code/core
diff -w --brief -r magento-ce-*/lib lib

Bear in mind that older Magento releases are (annoyingly) not patched, so doing a core diff will result in changes being shown. To avoid this, apply the patches to the freshly downloaded clean source, then diff again after.

  • 2
    Given both your answers, this one seems to relate better to the question.
    – pspahn
    Jun 30, 2015 at 22:50
  • Ben, i hit enter before I could finish my justification for the edit I suggested...not a major thing, just that PCI is an industry standard and not a regulation or law passed by a governmental body, at least not in the US: en.wikipedia.org/wiki/… Jul 3, 2015 at 11:07
  • 1
    I was just using "regulation" in the context of being interchangeable with "rule" (not law) Jul 3, 2015 at 12:56
  • Appreciate the distinction and it may be more based on locale than I originally realized. According to my dad the lawyer and sister the law-school dean (i hate arguing with them as you might guess) here in the US even the word rule has a specific meaning when prefaced by a specific modifier, such as Industry Rule like in this case vs Agency Rule (where a government agency like the EPA can issue detailed requirements that are legally binding like a law but not passed as a regulation by our Senate or House of Representatives chambers of Congress). Don't mean to be pedantic, just sharing :) Aug 19, 2015 at 8:44

Great post, but unfortunately not all things are created equal.

File permissions

When shared hosting became popular, it was deemed more important that people were not allowed to view content of others on the same server. Until the advent of FreeBSD jails, this meant:

  • restricted shells
  • /home as root:root 700
  • User accounts with umask 007.
  • UID changing webserver software
  • And the UID it changed to, is the owner of that account.

This allowed modification of the (then) HTML files by the account owner while at the same time, both the webserver process and the account owner did not have access to others on the same machine.

This hasn't changed much and software packages that tailor towards shared hosting (CPanel, DirectAdmin, Plex) all use those principles. This means that the main point of entry (webserver and/or script interpreter) can write to any file in the account, making file permissions useless.

No CC to steal if you don't have it

Inform with your CC payment provider if the CC data actually gets sent to your server and if so, if it's sent unencrypted unencrypted. JavaScript is quite powerful these days and there are Payment Service Providers out there, that use your customer's JavScript engine to encrypt sensitive information before transmission to the server. While it may be possible for this information gatherer to obtain the session key as well as the encrypted data (and thus be able to decrypt it), it's less interesting to the gatherer as the collected data is bigger and the bot's AI a lot more complex.

Modification detection

Over 15 years of unix and it still puts a nostalgic smile on my face when I see reincarnations of TripWire. Git it s a good tool for this too. Comparing with a known good version, somewhat less, as it doesn't take additions into account and again git a good tool here, since site-local modifications are more frequent then pristine installs.

The Downloader

It's just as easy to move the downloeader outside the document root as it is to install some form of HTTP authentication. Then only put it back when you use it. If that is not practical, then I prefer to lock it down based on remote address rather then another user/password layer, especially ones that send passwords in plain text.

WAF and alternatives

A Web Application Firewall can prevent a lot issues, already in the scanning stage of an attack. Unfortunately, these are expensive black boxes, but some alternatives exist:

  1. The one that was tripwire's companion back in the day - Snort -is right up there with commercial WAF's. It's got a steep learning curve, but can detect anomalies and known bad patters quite well.
  2. Naxsi for nginx and mod_security for Apache deny requests that contain know attack signatures. Naxsi is a bit more generic and denies service for "things that shoudn't belong here", like obscured SQL - in contrast to part of a known bit of SQL.
  3. Fail2ban / sshguard sit in between the previous two. They can handle different types of logs and have customizable actions. The downside is that they work after the fact. Loglines typically hit the log after an action has been completed and on top of that the tools have a threshold to combat false positives. This can be enough for the attacker to gain access, if it obtained accurate information in earlier stages.

I think we covered a lot of stuff but let me end with my petpeeve:


There. I said it. And here ya go: https://wiki.filezilla-project.org/Howto


There is nothing certain about this new hack, Ben Marks yesterday posted they are investigating the issue and there is this article too.

The best approach you can try is to log in via SSH and do a search inside all the files you have for a certain string, something like

find . | xargs grep 'db-tab-bottom-right-bg_bg.gif' -sl

from your Magento root folder and if you get a match, manually heck the file to see what is going on. Same with other strings like "END PUBLIC KEY" for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.