Сайты клиентов Аспро под угрозой взлома: уязвимость затрагивает пользователей, не обновивших систему
Недавно стало известно о серии взломов сайтов, работающих на популярном решении Аспро для сайтов под управлением «1С-Битрикс». Эксперты по кибербезопасности выявили, что атаки связаны с уязвимостью в системе, которая затрагивает пользователей, не обновивших модули Аспро до последних версий. Злоумышленники используют уязвимости в устаревших версиях для получения доступа к данным и внедрения вредоносного кода.
По данным специалистов, атаки носят целенаправленный характер и могут привести к утечке конфиденциальной информации, а также к повреждению функциональности сайтов. В группе риска находятся компании, которые не уделяют должного внимания своевременному обновлению программного обеспечения.
Эксперты настоятельно рекомендуют всем пользователям «1С-Битрикс» проверить актуальность версии своей платформы, установленных сторонних решений и при необходимости установить последние обновления. Это поможет минимизировать риски взлома и защитить данные.
Для получения более подробной информации вы можете ознакомиться с оригинальной статьей по .
UPD 06.02.2025: Разработчики решения Аспро выпустили официальные патчи для устранения уязвимости
-
Обнаружение уязвимости:
-
В статье сообщается о цепочке взломов сайтов, использующих модуль электронной коммерции Aspro на платформе 1С-Битрикс. Проблема актуальна для пользователей, не обновивших софт до версии Aspro: Next 1.9.9.
-
-
Точка входа для атак:
-
Злоумышленники использовали уязвимые скрипты:
reload_basket_fly.php,show_basket_fly.php,show_basket_popup.php, расположенные в директории/ajax/корневой папки сайта. Эти скрипты недостаточно проверяют пользовательский ввод и используют небезопасную функциюunserializeв PHP, что позволяет внедрять вредоносный код через POST-запросы. -
Если у Вас отсутствует возможность обновить Аспро, в таком случаи замените код
$arParams = unserialize(urldecode($_REQUEST["PARAMS"]));в файлах:- /ajax/reload_basket_fly.php
- /ajax/show_basket_fly.php
- /ajax/show_basket_popup.php
- /bitrix/wizards/aspro/max/site/public/ru/ajax/reload_basket_fly.php
- /bitrix/wizards/aspro/max/site/public/ru/ajax/show_basket_fly.php
- /bitrix/wizards/aspro/max/site/public/ru/ajax/show_basket_popup.php
Вместо
$arParams = unserialize(urldecode($_REQUEST["PARAMS"]))используйте выражение$arParams = json_decode($_REQUEST["PARAMS"]); - UPD: 05.02.2025 так же уязвимым явялется файлы:
- /include/mainpage/comp_catalog_ajax.php
- /bitrix/wizards/aspro/max/site/public/ru/include/mainpage/comp_catalog_ajax.php
В этих файлах нужно заменить код:
$arIncludeParams = ($bAjaxMode ? $_POST["AJAX_PARAMS"] : $arParamsTmp); $arGlobalFilter = ($bAjaxMode ? unserialize(urldecode($_POST["GLOBAL_FILTER"])) : ($_GET['GLOBAL_FILTER'] ? unserialize(urldecode($_GET['GLOBAL_FILTER'])) : array())); $arComponentParams = unserialize(urldecode($arIncludeParams));на вот этот код:
if ($_POST["AJAX_PARAMS"] && !is_array(unserialize(urldecode($_POST["AJAX_PARAMS"]), ["allowed_classes" => false]))) { header('HTTP/1.1 403 Forbidden'); $APPLICATION->SetTitle('Error 403: Forbidden'); echo 'Error 403: Forbidden_1'; require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php'); die(); } $arIncludeParams = ($bAjaxMode ? $_POST["AJAX_PARAMS"] : $arParamsTmp); $arGlobalFilter = ($bAjaxMode ? unserialize(urldecode($_POST["GLOBAL_FILTER"]), ["allowed_classes" => false]) : array()); $arComponentParams = unserialize(urldecode($arIncludeParams), ["allowed_classes" => false]); -
UPD 06.02.2025 Подготовлен скрипт для автоматической очистки заражённых файлов и внесения исправления в уязвимые файлы.
-
UPD 12.03.2025 Так же угрозе подвержен файл /bitrix/components/aspro/oneclickbuy.max/script.php в нём нужно заменить код ( ориентировочно в строке 797 )
$res = CSaleOrderProps::GetList(array(), array('@CODE' => unserialize($_POST["PROPERTIES"]), 'PERSON_TYPE_ID' =>$personType));на код
$res = CSaleOrderProps::GetList(array(), array('@CODE' => unserialize($_POST["PROPERTIES"], ['allowed_classes' => false]), 'PERSON_TYPE_ID' =>$personType));
-
-
Механизм атаки:
-
Через уязвимость злоумышленники загружали веб-шеллы, которые, в свою очередь, подгружали майнеры для скрытого майнинга криптовалюты. Это позволяло им выполнять произвольные команды на сервере, например, получать доступ к системным файлам (например,
/etc/passwd).
-
-
Индикаторы компрометации:
-
В ходе расследования были выявлены вредоносные файлы, такие как
3.phpи4.php, а также IP-адреса злоумышленников, включая185.125.219.93. Эти файлы использовались для управления сервером и запуска майнера XMRig.Эти файлы имеют md5 HASH:
- 07a3fe9875d3a8b7c57874c4cc509929
- 50b7604d856f36983b9bb3066f894f3f
-
Для выявления вредоносных файлов воспользуйтесь поиском файлов по hash используя команду:
find /home/bitrix/www -type f -exec md5sum {} + | grep '^07a3fe9875d3a8b7c57874c4cc509929'или
find /home/bitrix/www -type f -exec md5sum {} + | grep '^50b7604d856f36983b9bb3066f894f3f'Если файлы будут найдены - удалите их!
Кроме того, нужно почистить уже созданные вредоносные файл. В первую очередь вирус создаёт "зараженные файлы" в директории "/ajax/". Проверте дирректорию на наличе файлов c расширением *.php имеющих название состоящие их цифр и букв: содержимое таких файлов
Чтобы проверить все файлы сайта на содержимое, можно воспользоваться командой:
grep -rn "eval(base64" /home/bitrix/wwwКоманда выведет список файлов и их содержимое в случаи совпадения. Проанализируйте полученные файлы - и обязательно удалите все, которые попадают под подозрение.
-
-
Рекомендации по устранению уязвимости:
-
Владельцам сайтов рекомендуется:
-
Остановить все вредоносные процессы.
-
Сменить пароли всех учетных записей 1С-Битрикс.
-
Обновить CMS и модули до последних версий.
-
Внести изменения в уязвимые скрипты, заменив
unserializeнаjson_decodeдля предотвращения атак.
-
-
-
Цели злоумышленников:
-
Основной целью атак был заработок через майнинг криптовалюты. Однако отсутствие быстрого реагирования могло привести к утечкам конфиденциальной информации или персональных данных.
-
-
Реакция разработчиков:
-
Разработчики Aspro оперативно выпустили обновление для устранения уязвимости. Владельцы атакованных ресурсов были уведомлены, и уязвимость была закрыта.
-
UPD: 06.02.2025 Скрипт для автоматического исправления уязвимости и удаления заражённых файлов.
Чтобы автоматически очистить сайта от известных вредоносных файлов и внести исправления в уязвимые участки кода, воспользуйтесь решением от Вячеслава Вяткина. Ссылка на github
/**
* Скрипт для автоматической чистки сайта от известных вредоносных файлов
* и исправления уязвимых участков кода.
*
* Рекомендуется сделать резервную копию файлов перед запуском.
* By Vyacheslav Vyatkin 2025 https://vk.com/vyachesiav
*/
// Настройте корневой путь к сайту (обычно DOCUMENT_ROOT)
$documentRoot = '.';
// --- 1. Обновление уязвимых файлов через замену кода ---
// Файлы с уязвимым кодом, где необходимо заменить вызов unserialize
$replacements = [
'/ajax/reload_basket_fly.php' => [
'search' => '$arParams = unserialize(urldecode($_REQUEST["PARAMS"]));',
'replace' => '$arParams = json_decode($_REQUEST["PARAMS"]);'
],
'/ajax/show_basket_fly.php' => [
'search' => '$arParams = unserialize(urldecode($_REQUEST["PARAMS"]));',
'replace' => '$arParams = json_decode($_REQUEST["PARAMS"]);'
],
'/ajax/show_basket_popup.php' => [
'search' => '$arParams = unserialize(urldecode($_REQUEST["PARAMS"]));',
'replace' => '$arParams = json_decode($_REQUEST["PARAMS"]);'
],
'/bitrix/wizards/aspro/max/site/public/ru/ajax/reload_basket_fly.php' => [
'search' => '$arParams = unserialize(urldecode($_REQUEST["PARAMS"]));',
'replace' => '$arParams = json_decode($_REQUEST["PARAMS"]);'
],
'/bitrix/wizards/aspro/max/site/public/ru/ajax/show_basket_fly.php' => [
'search' => '$arParams = unserialize(urldecode($_REQUEST["PARAMS"]));',
'replace' => '$arParams = json_decode($_REQUEST["PARAMS"]);'
],
'/bitrix/wizards/aspro/max/site/public/ru/ajax/show_basket_popup.php' => [
'search' => '$arParams = unserialize(urldecode($_REQUEST["PARAMS"]));',
'replace' => '$arParams = json_decode($_REQUEST["PARAMS"]);'
],
];
// Файлы компонента, где требуется заменить блок кода
$replacementsBlock = [
'/include/mainpage/comp_catalog_ajax.php' => [
'search' => '$arIncludeParams = ($bAjaxMode ? $_POST["AJAX_PARAMS"] : $arParamsTmp);
$arGlobalFilter = ($bAjaxMode ? unserialize(urldecode($_POST["GLOBAL_FILTER"])) : ($_GET[\'GLOBAL_FILTER\'] ? unserialize(urldecode($_GET[\'GLOBAL_FILTER\'])) : array()));
$arComponentParams = unserialize(urldecode($arIncludeParams));',
'replace' => 'if ($_POST["AJAX_PARAMS"] && !is_array(unserialize(urldecode($_POST["AJAX_PARAMS"]), ["allowed_classes" => false]))) {
header(\'HTTP/1.1 403 Forbidden\');
$APPLICATION->SetTitle(\'Error 403: Forbidden\');
echo \'Error 403: Forbidden_1\';
require_once($_SERVER[\'DOCUMENT_ROOT\'] . \'/bitrix/modules/main/include/epilog_after.php\');
die();
}
$arIncludeParams = ($bAjaxMode ? $_POST["AJAX_PARAMS"] : $arParamsTmp);
$arGlobalFilter = ($bAjaxMode ? unserialize(urldecode($_POST["GLOBAL_FILTER"]), ["allowed_classes" => false]) : array());
$arComponentParams = unserialize(urldecode($arIncludeParams), ["allowed_classes" => false]);'
],
'/bitrix/wizards/aspro/max/site/public/ru/include/mainpage/comp_catalog_ajax.php' => [
'search' => '$arIncludeParams = ($bAjaxMode ? $_POST["AJAX_PARAMS"] : $arParamsTmp);
$arGlobalFilter = ($bAjaxMode ? unserialize(urldecode($_POST["GLOBAL_FILTER"])) : ($_GET[\'GLOBAL_FILTER\'] ? unserialize(urldecode($_GET[\'GLOBAL_FILTER\'])) : array()));
$arComponentParams = unserialize(urldecode($arIncludeParams));',
'replace' => 'if ($_POST["AJAX_PARAMS"] && !is_array(unserialize(urldecode($_POST["AJAX_PARAMS"]), ["allowed_classes" => false]))) {
header(\'HTTP/1.1 403 Forbidden\');
$APPLICATION->SetTitle(\'Error 403: Forbidden\');
echo \'Error 403: Forbidden_1\';
require_once($_SERVER[\'DOCUMENT_ROOT\'] . \'/bitrix/modules/main/include/epilog_after.php\');
die();
}
$arIncludeParams = ($bAjaxMode ? $_POST["AJAX_PARAMS"] : $arParamsTmp);
$arGlobalFilter = ($bAjaxMode ? unserialize(urldecode($_POST["GLOBAL_FILTER"]), ["allowed_classes" => false]) : array());
$arComponentParams = unserialize(urldecode($arIncludeParams), ["allowed_classes" => false]);'
]
];
/**
* Функция для обновления файла: поиск и замена строки.
*
* @param string $filePath Полный путь к файлу.
* @param string $search Строка, которую нужно найти.
* @param string $replace Строка-замена.
*/
function updateFile($filePath, $search, $replace) {
if (file_exists($filePath)) {
$content = file_get_contents($filePath);
if (strpos($content, $search) !== false) {
$newContent = str_replace($search, $replace, $content);
if (file_put_contents($filePath, $newContent) !== false) {
echo "Обновлён: $filePath\n";
} else {
echo "Не удалось записать изменения в: $filePath\n";
}
} else {
echo "Не найден искомый фрагмент в: $filePath\n";
}
} else {
echo "Файл не найден: $filePath\n";
}
}
// Обрабатываем файлы с одиночной заменой
foreach ($replacements as $relativePath => $data) {
$filePath = $documentRoot . $relativePath;
updateFile($filePath, $data['search'], $data['replace']);
}
// Обрабатываем файлы с заменой блоков кода
foreach ($replacementsBlock as $relativePath => $data) {
$filePath = $documentRoot . $relativePath;
updateFile($filePath, $data['search'], $data['replace']);
}
// --- 2. Удаление вредоносных файлов по MD5-хэшам ---
// Известные MD5-хэши вредоносных файлов
$maliciousHashes = [
"07a3fe9875d3a8b7c57874c4cc509929",
"50b7604d856f36983b9bb3066f894f3f"
];
/**
* Рекурсивно сканирует директорию и удаляет файлы с указанными MD5-хэшами.
*
* @param string $dir Корневая директория для сканирования.
* @param array $maliciousHashes Массив с известными вредоносными хэшами.
*/
function scanAndRemoveMaliciousFiles($dir, $maliciousHashes) {
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
foreach ($iterator as $file) {
if ($file->isFile()) {
$filePath = $file->getPathname();
$hash = md5_file($filePath);
if (in_array($hash, $maliciousHashes)) {
if (unlink($filePath)) {
echo "Удалён вредоносный файл: $filePath\n";
} else {
echo "Не удалось удалить файл: $filePath\n";
}
}
}
}
}
echo "Поиск хешей...\n";
scanAndRemoveMaliciousFiles($documentRoot, $maliciousHashes);
// --- 3. Проверка директории /ajax/ на подозрительные файлы ---
// Ищем PHP-файлы с именами, состоящими из букв и цифр, и содержащие "eval(base64"
$ajaxDir = $documentRoot . '/ajax/';
if (is_dir($ajaxDir)) {
$files = scandir($ajaxDir);
foreach ($files as $file) {
// Проверяем, что имя файла состоит только из букв и цифр и имеет расширение .php
if (preg_match('/^[a-z0-9]+\.php$/i', $file)) {
$filePath = $ajaxDir . $file;
$content = file_get_contents($filePath);
if (stripos($content, 'eval(base64') !== false) {
if (unlink($filePath)) {
echo "Удалён подозрительный файл: $filePath\n";
} else {
echo "Не удалось удалить подозрительный файл: $filePath\n";
}
}
}
}
} else {
echo "Директория не найдена: $ajaxDir\n";
}
// --- 4. (Опционально) Дополнительное сканирование всего сайта ---
// Если необходимо просканировать весь сайт на наличие фрагмента "eval(base64" и удалить такие файлы,
// раскомментируйте следующий блок. Будьте осторожны – эта операция может затронуть и легитимные файлы.
/*
function scanAndCleanEvalBase64($dir) {
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
foreach ($iterator as $file) {
if ($file->isFile() && strtolower(pathinfo($file->getFilename(), PATHINFO_EXTENSION)) == 'php') {
$filePath = $file->getPathname();
$content = file_get_contents($filePath);
if (stripos($content, 'eval(base64') !== false) {
if (unlink($filePath)) {
echo "Удалён файл с eval(base64): $filePath\n";
} else {
echo "Не удалось удалить файл с eval(base64): $filePath\n";
}
}
}
}
}
// Раскомментируйте следующую строку для запуска сканирования по всему сайту:
// scanAndCleanEvalBase64($documentRoot);
*/
echo "Очистка и исправление завершены.\n";
Создайте файл autofix.php в корне Вашего сайта ( обычно /home/bitrix/www ) и запустите его выполнение из консоли командой
php -f autofix.php
Или можете скачать архив с файлом, распокавать его и так же запустить выполнение autofix.php