Как устроено отключение сайта по лицензии 1С-Битрикс?

28.05.2021

Разрабатывая модуль для 1С-Битрикс на пробной версии CMS может возникать ситуация с истечением лицензии и как следствие - прекращение работы сайта. В общем-то все логично 1С-Битрикс коммерческий продукт, и используя его пользователь принимает условия использования. Но стало очень интересно что же внутри :)

Статья является результатом исследования устройства 1С-Битрикс, использование изложенного ниже в неправмерных целях не рекомендуется :)

Как это происходит?

Разработка модуля для 1С-Битрикс на пробной версии может длится спокойно в течении месяца, а затем на сайте в самом начале страницы перед <!DOCTYPE html> появляется такое:

Срок работы пробной версии продукта истек. Через две недели этот сайт полностью прекратит свою работу. Вы можете купить полнофункциональную версию продукта на сайте www.1c-bitrix.ru.

А через несколько дней сайт перстает работать и показывает такое:

Срок работы пробной версии продукта истек. Вы можете купить полнофункциональную версию продукта на сайте www.1c-bitrix.ru.

Поиск источника

В CMS 1С-Битрикс есть интересный файл bitrix/modules/main/include.php, который жестоко обфусцирован. При входе в этот файл, в связи с проблемами лицензии, перестает работать тестовый сайт.

Найти его можно используя классический метод (exit/die в строках файлов начиная с корневого index.php).

Разбиваем файл на строки, и приведем его в более читабельный вид используя exit/die.

В файле есть глобальные переменные:

  • _____832962782 - массив функций ядра 1С-Битрикс
  • ____282722678 - массив встроенных функции php
  • ___413677614 - функция, которая по индексу возвращает элемент из внутреннего массива, здесь уже есть пути, имена переменных и даже javascript код
Данные в массивах _____832962782 и ____282722678 декодируются из base64 при создании массива, а данные массива внутри функции ___413677614 лежат в закодированном виде и каждый раз при обращении к этой функции они декодируются.

Исследуя файл дальше можно обнаружить интересный кусок кода, который die сайт по истечении лицензии:

•••
php
for( $_485561646=(868-2*434), $_260369785=($GLOBALS['____282722678'][65]()< $GLOBALS['____282722678'][66](min(250,0,83.333333333333), (802-2*401),(942-2*471), round(0+2.5+2.5), round(0+0.2+0.2+0.2+0.2+0.2), round(0+402+402+402+402+402)) || $_1612069149 <= round(0+2+2+2+2+2)), $_1713308456=($_1612069149< $GLOBALS['____282722678'][67]((244*2-488), min(36,0,12), (169*2-338), Date(___413677614(124)), $GLOBALS['____282722678'][68](___413677614(125))-$_1747200466, $GLOBALS['____282722678'][69](___413677614(126)))); $_485561646< round(0+5+5),$_260369785 || $_1713308456 || $_1612069149 != $_1026617103; $_485561646++,$GLOBALS['_____832962782'][4]($_947848593) );

При обновлении движка файл bitrix/modules/main/include.php заменяется на новый и все правки теряются.

А что же внутри?

Пробуем убрать всякие выборки из массива, заменяя их на вызовы функций, убираем round так как эта функция здесь бессмысленна, получаем следующее:

•••
php
for( $_485561646=0, $_260369785=(time() < mktime(0, 0, 0, 5, 5, 2010) || $_1612069149 <= 10), $_1713308456=($_1612069149< mktime(0, 0, 0, Date("m"), date("d")-$_1747200466, date("y"))); $_485561646 < 10,$_260369785 || $_1713308456 || $_1612069149 != $_1026617103; $_485561646++,WriteFinalMessage($_947848593) );

Уже лучше. Сразу становится понятно что сообщение вместе с die выдает WriteFinalMessage. Пробуем разобраться что там где:

  • $_485561646 итерируемая переменная, ничего интересного
  • $_1612069149 и $_1026617103 - unixtime истечения пробного периода (в моем слуаче содержало 1612904400 это GMT: Tue, 09 Feb 2021 21:00:00 GMT)
  • $_260369785 - true т.к. текущее время не меньше 2010.05.05
Выкинув лишнее получаем:
•••
php
for( $_485561646=0, $_1713308456=($_1612069149< mktime(0, 0, 0, Date("m"), date("d")-$_1747200466, date("y"))); $_485561646 < 10,$_1713308456; $_485561646++,WriteFinalMessage($_947848593) );

Здесь:

  • $_1747200466 - 14 (через сколько дней сайт полностью отключится)
  • $_1713308456 - содержит bool надо ли отключать сайт ($_1612069149 < (текщая дата - 14 дней)).
Цикл здесь явно не нужен, убираем, также выкидываем не нужные переменные, в итоге:
•••
php
if(($_1612069149 < mktime(0, 0, 0, Date("m"), date("d")-$_1747200466, date("y")))) WriteFinalMessage($_947848593);