It’s that time of year again! While website owners always need to be on guard, the holidays season is when online scams and credit card theft are most rampant. Administrators of ecommerce websites need to be extra vigilant as this case will demonstrate. This story starts much the same as many others that we discuss on this blog: A client came to us noting that a number of their customers reported that unauthorised activity took place on their credit cards shortly after having made a purchase on their website. Our initial scans came up clean so it was time to do some investigating to find the source!
Hiding from Detection
Ecommerce credit card skimmers are notably different from most website infections that we deal with. The most common infections that we see are spam, malicious redirects, and phishing. These are typically very obvious and the attackers often don’t even really try to hide their malware. Infections involving credit card theft, on the other hand, tend to be well hidden and can take a great deal of investigation to find. The longer that the infection stays hidden the more credit card numbers that the attackers are able to pilfer, so it really pays off for them to take time to craft a well hidden injection. Sometimes these are only one line of code injected into the files or database:
Malicious javascript loading from known credit card skimmer domains
view-source:
The first thing to do during an investigation of this sort is to examine the source code of the website’s checkout page. As we have written about before, quite often the javascript injections are designed to only load on URLs that contain certain strings such as “checkout“, “onepage“, or similar. We went ahead and added an item to our shopping cart and navigated to the checkout page. We didn’t notice any strange content loading, and even manually inspected every single javascript file loading on the page and came up empty handed. This tends to suggest that the credit card swiper malware is operating on the backend through PHP, rather than in the client’s browser.
Logs logs logs
This case is an excellent example of the importance of file integrity monitoring. Luckily enough our client had our server side scanner installed on their website. This service will run once per day and keep an accessible log of all website files that have been added or modified within the environment. This is particularly useful if you have a rough time frame as to when reports of credit card theft started to occur. Our client informed us that these started in late October, so we had something to work with.
Log Analysis
It can take a bit of a keen eye and a bit of experience to read these logs properly, but once you know how to parse through the file changes due to plugin and theme updates you can begin to see the questionable file changes:
Questionable changes to file integrity
Plugin and theme updates will appear as fairly large batches, so these can usually be ignored. When only a single file or a couple of files from the file structure are modified by themselves, however, that is when we need to put our Sherlock caps on and take a look at the code.
Checking our client’s server side scanner logs revealed exactly that, so let’s take a look!
CC Skimmer Injected into Plugin Files
The attackers know that most security plugins for WordPress contain some way to monitor the file integrity of core files (that is, the files in wp-admin and wp-includes directories). This makes any malware injected into these files very easy to spot even by less experienced website administrators. The next logical step for them would be to target plugin and theme files. This is not the first time we have seen this, but what was quite fascinating about this particular infection was the way that the code was written to appear entirely benign. It wasn’t until we broke apart the code using some more advanced methods that the payload was uncovered.
Backdoor Injection
Before we take a look at the swiper itself, let’s take a quick look at the backdoor that was injected into the site files.
./wp-content/plugins/really-simple-ssl/rlrsssl-really-simple-ssl.php
This line in particular:
$u = get_users( array('role' => str_replace('c', '', 'cacdmcinisctractcocrc')));
At first glance looks like rubbish, but when the str_replace function is used and all instances of the letter c are removed, we get a simple:
"administrator"
Same goes for “fadmfifnisftrfatorf” except in that instance it uses the letter “f”.
The way it works is pretty straightforward: It grabs a list of administrator users, and if any are found it will set the authorisation cookie and current user login to one of those users. The way that this backdoor works is a great reminder of the importance of securing your wp-admin administrator panel: Even if this backdoor was injected, if the wp-admin area is restricted to only certain IP addresses, for example, it wouldn’t be able to do anything.
Wp-smush Plugin Abused to Add Skimmer
One of the files that showed up in the server side scanner logs was the following:
./wp-content/plugins/wp-smushit/wp-smush.php (old size: 16965; new size: 25398)
Some content was added to this file – why? This warranted inspection.
Please note that these affected plugins may not themselves be vulnerable! They were most likely simply picked by the attackers to inject their malware into.
In checking this file against the original from the WordPress repository we can see that quite a bit of code was added into it:
Differences in code between fresh copy of the legitimate plugin file and the modified file on the victim website.
At first glance it seems innocuous and did not contain any typical encoding or obfuscation techniques that we so frequently see with malware. In fact, nothing in here looks malicious at all! However, in checking the differences I noticed the following snippet:
Why is this plugin referencing WooCommerce?
Why would a plugin designed for image optimisation be referencing WooCommerce at all? Something didn’t add up here. In total there were well over 100 lines of code added to this file. There are a few variables that seem to not be defined anywhere, so there’s more to this code than meets the eye:
Let’s see if we can get these to produce anything interesting, shall we?
Using get_defined_vars() to obtain hidden variables
PHP has a function get_defined_vars() which will return an array of every defined variable in defined code. A useful trick when dealing with such code is to take advantage of this in conjunction with the print_r function in PHP.
DISCLAIMER: Caution should be used when dealing with any code suspected of being malicious. Be sure to use an isolated sandbox environment!
Once we isolate the code that doesn’t belong in the actual plugin file and adjust the code a little bit all we need to do is add the following to the bottom of the file and execute it in a sandbox:
Which results in the following:
The giveaway is the $stylesheet variable which references a questionable domain. Running a quick whois over that domain shows that it was registered very recently, probably with the express intent of exfiltrating stolen credit card details from the victim website:
$ whois array-slice.page Domain Name: array-slice.page Registry Domain ID: 47C791B75-PAGE Registrar WHOIS Server: whois.nic.google Registrar URL: http://www.tucows.com Updated Date: 2021-10-23T07:04:29Z Creation Date: 2021-10-06T16:36:52Z Registry Expiry Date: 2022-10-06T16:36:52Z
We can also see that it is hosted on an Alibaba server in Germany:
Which is certainly unrelated to our client’s website who conducts their business mostly in North America.
The fun doesn’t stop here, though, as there is another injection that we need to examine!
Swiper Injected into 404 Page Plugin
Another one of the files that warranted inspection was the following:
./wp-content/plugins/404page/inc/class-404page.php
The following server side scanner log was found the same day as the previous file we just looked at:
./wp-content/plugins/404page/inc/class-404page.php (old size: 52515; new size: 55688)
When we run a diff comparison between the original plugin file and the infected one you can see a bunch of code added starting on line 218. Reading it at first glance it seems completely normal though:
Most credit card skimmers that we come across are heavily encoded and use complicated obfuscation techniques and are usually fairly easy to spot once you see them. Not so in this case. All we see here is what appears to be normal plugin code referencing thumbnails and comments.
What do we get when we apply the same logic as the previous file and print out the variables for inspection?
print_r(get_defined_vars());
A number of different variables are returned here, but the most important giveaway that this another credit card swiper is the $thelist variable as you can see here:
This references a different URL on the same domain as the last file. The $message variable is also important here as it has the value of file_get_contents and is run in conjunction with the malicious domain variable, thereby grabbing whatever the attackers choose to serve from that domain.
Secure Your Website!
If you operate an ecommerce website be sure to be extra cautious during the holiday season. This is when we see attacks and compromises on ecommerce websites at their highest volume as attackers are poised to make handsome profits from stolen credit card details.
Make sure to follow best security practices, harden your administrator dashboard and ideally place your website behind a firewall service!