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

По просьбе наших посетителей, данный материал перенесен с сайта plc4good.org.ua, в связи с полной его потерей. Всё возражения принимаются через форму обратной связи.

plc4good.org.ua/view_post.php?id=246

modbus

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

Описание

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

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

  • Вызываем функцию MODBUSCP в организационном блоке регистрируемого CPU, открываем экземплярный блок данных, переходим в онлайн Ctrl+F3 и копируем строку IDENT_CODE.
  • Посылаем эту строку по адресу [email protected] (попробовал проделать эту операцию, получил письмо с текстом ‘Your email is not read and not processed.’ и просьбой перейти по ссылке, неоднократно переходя по которой упираешься в надпись ‘Unfortunately there might be a temporary problem in accessing the data, but we are making every effort to clear any faults as quickly as possible. Please try again in a few minutes.
    We apologize for any inconvenience.’
    Тупик вообщем 🙂
  • Получаем в ответ регистрационный ключ, который подаем на вход функции REG_KEY
  • Регистрация закончена.

 

Если функция незарегистрированная, при работе контроллера получаем сообщения каждые 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 &lt,=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 &lt,=17, $i++)
 {
    $tALicenseKey_arr[$i]=$IDENT_CODE_arr[$i] ^ ($sHoldingRegisterState_arr[$i1] ^ ($i)),
    $tALicenseKey_arr[$i]=($tALicenseKey_arr[$i] % 26) + 65,
 }
$tALicenseKey[18]=50,

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

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

Комментарии к материалу

Добавлен: Paolo Дата: 2015-01-17

Evaluation is pretty amazing,But it is better to be a key generator makes it possible to accept the ‘Product ID’ as a variable

Добавлен: komatic Дата: 2015-01-17

&gt,Paolo
Good idea, done

Добавлен: Paolo Дата: 2015-02-10

Is it valid for FB109 MB_PAC16?If ‘yes’ why it delete the ‘ ‘ and ‘.’ characters and wrong IDENT_CODE?

Добавлен: komatic Дата: 2015-02-10

&gt,Paolo
I think this generator incompatible with MB_PAC16, cause different product

Добавлен: Евгений Дата: 2015-03-24

откуда взять serial number CPU и Product ID ?

Добавлен: komatic Дата: 2015-03-25

серийный номер CPU легче всего посмотреть на самом CPU на этикетке,
Product ID это идентификатор библиотеки S7-OPEN MODBUS/TCP и конкретно для функций FB106,FB107,FB108 MB_CPCLI,MB_CPSRV,MODBUSCP он равен MODCP2XV94501MB00
Описанный генератор работает только для этого случая, для библиотек с другими Product ID подтверждений правильной работы пока не было.

Добавлен: Sergey Дата: 2015-04-03

Не получается сгенерить правильный ключ. У меня CPU S7-315F. Серийный номер SC-E1TV7698. Идентификационный код расчитанный генератором ключа не совпадает с идентификационным ключем который можно посмотреть в DB108 ‘EHHGIDMABCMIDILEJ2’. Product IDMODCP2XV94501MB00.

Добавлен: Max Дата: 2015-06-07

Опытным путём установил, что Product ID для новой версии MODPN2XV94501MB02 – в этом случае совпадает IDENT_CODE, который генерирует скрипт и блок в контроллере. А вот ключик не подошёл..

Добавлен: Zeta Дата: 2015-08-26

Max, Sergey, the code above only works with the default product ID, because array [0, 223, 32, etc] is not a constant, but it’s generated based on the product id, so it will be different with different products.
But you can do your own script (it’s fun), starting from the real constants:
rcv_time = [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1]
snd_time = [128,64,32,16,8,4,2,1,128,64,32,16,8,4,2,1,128]
also, putin suks

Добавлен: Max Дата: 2015-09-04

Zeta, I’d tried to debug the new block, but didn’t played with it enough time. The customer had bought the license 🙂
Maybe somewhen I’ll finish it 🙂

Добавлен: Blendi Дата: 2016-03-24

&gt,komatic
Can you post your php source for pascal or delphi please ? Thanks.

Добавлен: Watchara Дата: 2016-06-30

where to get the Product ID

Добавлен: Алексей Дата: 2016-10-02

Все работает. Спасибо

Добавлен: x Дата: 2016-11-18

Разобрался с генерацией лицензии для MODBUSPN, все получилось, блок принял лицензию.
От кода генерации MODBUSCP отличаются
1) Product ID = MODPN2XV94501MB02
2) HoldingRegisterState = (0,$DF,32,$E8,83,$97,$B2,3,0,96,$9F,$9F,33,38,64,53,0,0,1)
Вот тут набросал код генерации на паскале:
ideone.com/3ehALQ
Если кто будет пробовать, не забудьте ввести серийный номер в строке 13

0 0 голоса

Оцените статью!

guest
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии