plc4good.org.ua

Анализ защиты регистрационным ключом в библиотеке S7-OPEN MODBUS/TCP




modbus



Разбираем вариант защиты программного обеспечения для контроллеров Siemens.




Содержание:

Описание

Получаем ключ отладкой

Выделяем код генерации ключа

Автономный генератор ключа



Описание


Защита применена в библиотеке COMM, функции MODBUSCP, предназначенной для обмена данными по протоколу S7-OPEN MODBUS/TCP.

Сама восстановленная функция MODBUSCP - здесь

Чтобы выполнить правильную регистрацию, необходимо выполнить следующие шаги (взято из официального руководтсва):



Если функция незарегистрирована, при работе контроллера получаем сообщения каждые 4 секунды, в буфере диагностики, об отсутствии лицензии и ошибки обращения к блоку данных.



modbus

Ошибка обращения к блоку данных, формируется строкой PT.IN:=DB0.DBX0.0;



Получаем ключ отладкой



Беглый обзор кода функции, показывает, что полученный REG_KEY сравнивается внутри кода посимвольно, что означает что правильный код генерируется внутри функции.
Попробуем найти этот сгенерированный код с помощью пошаговой отладки.



Получаем IDENT_CODE:





modbus

Задаем серийный номер как константу
(на симуляторе серийный номер CPU не читается).
Устанавливаем точку останова после генерации IDENT_CODE.



Находим IDENT_CODE в экземплярном блоке:





modbus

Копируем получившуюся строку.



Находим REG_KEY:





modbus

Устанавливаем точку останова после генерации лицензионного ключа tAlicenseKey
Изменяем немного участок кода, чтобы ключ копировался в удобную для обработки область sSTATUS_CODE



Копируем результат:





modbus

Эта строка и есть сгенерированный ключ.



Проверяем результат:





modbus

Создаем блок данных, в который прописываем этот ключ.



Подаем ключ на вход блока:





modbus

В ключе 17 символов.





Результат:





modbus

Ключ подходит.





Выделяем код генерации ключа



Анализируя код генерации и последовательно упрощая довольно запутанный код, получаем упрощенный вариант (вариант на PHP).



$serialn:='SC-W0VK37682008';
$tSProductID='MODCP2XV94501MB00';
  for ($i = 1; $i <=17; $i++)
  {
    $IDENT_CODE_arr[$i]=(($serialn_arr[$i] ^ $tSProductID_arr[$i]) % 13) + 65;
  }
$IDENT_CODE_arr[18]=50;
 

Генерация идентификационного кода IDENT_CODE



$sHoldingRegisterState_arr   =  ARRAY(0, 223, 32, 240, 67, 135, 170, 11, 0, 96, 159, 159, 33, 38, 64, 53, 0, 0, 1, 0, 0, 0, 0, 0 );
  for ($i = 1; $i <=17; $i++)
 {
    $tALicenseKey_arr[$i]=$IDENT_CODE_arr[$i] ^ ($sHoldingRegisterState_arr[$i-1] ^ ($i));
    $tALicenseKey_arr[$i]=($tALicenseKey_arr[$i] % 26) + 65;
 }
$tALicenseKey[18]=50;
 

Генерация регистрационного ключа REG_KEY



Как видно, ничего особо сложного нет.
Небольшой вывод: защита довольно слабая, хотя без шифрования кода функции и/или применения аппаратных ключей добиться большего вряд ли возможно.



Автономный генератор ключа



Введя здесь серийный номер вашего CPU можно получить код регистрации.

Назад





Enter serial number CPU


Enter Product ID


идентификационный код IDENT_CODE


регистрационный ключ REG_KEY