Электронные ключи. AntiHASP: эмулируем ключ аппаратной защиты HASP

Безопасность любого криптографического алгоритма определяется используемым криптографическим ключом. Добротные криптографические ключи должны иметь достаточную длину и случайные значения битов. В табл. 4.3 приведены длины ключей симметричной и асимметричной криптосистем, обеспечивающие одинаковую стойкость к атаке полного перебора (атаке "грубой силы") .

Для получения ключей используются аппаратные и программные средства генерации случайных значений ключей. Как правило, применяют датчики псевдослучайных чисел (ПСЧ). Однако степень случайности генерации чисел должна быть достаточно высокой. Идеальными генераторами являются устройства на основе "натуральных" случайных процессов, например на основе белого радиошума .

В сети со средними требованиями защищенности вполне приемлемы программные генераторы ключей, которые вычисляют ПСЧ как сложную функцию от текущего времени и (или) числа, введенного пользователем.

Один из методов генерации сеансового ключа для симметричных криптосистем описан в стандарте ANSI X9.17. Он предполагает использование криптографического алгоритма DES (хотя можно применить и другие симметричные алгоритмы шифрования).

Обозначения:

Е К (X) – результат шифрования алгоритмом DES значения X;

К – ключ, зарезервированный для генерации секретных ключей;

V 0 – секретное 64-битовое начальное число;

Т – временная отметка.

Схема генерации случайного сеансового ключа R i в соответствии со стандартом ANSI X 9.17 показана на рис. 7.1. Случайный ключ R i генерируют, вычисляя значение

R i = Е К (Е К (Т i) Å V i).

Рисунок 7.1 – Схема генерации случайного ключа R i в соответствии

со стандартом ANSI X9.17

Следующее значение V i+1 вычисляют так:

V i+1 = Е К (Е К (Т i) Å R i).

Если необходим 128-битовый случайный ключ, генерируют пару ключей R i , R i+ 1 и объединяют их вместе.

Если ключ не меняется регулярно, это может привести к его раскрытию и утечке информации. Регулярную замену ключа можно осуществить, используя процедуру модификации ключа.

Модификация ключа – это генерирование нового ключа из предыдущего значения ключа с помощью односторонней (однонаправленной) функции. Участники информационного обмена разделяют один и тот же ключ и одновременно вводят его значение в качестве аргумента в одностороннюю функцию, получая один и тот же результат. Затем они берут определенные биты из этих результатов, чтобы создать новое значение ключа.

Процедура модификации ключа работоспособна, но надо помнить, что новый ключ безопасен в той же мере, в какой был безопасен прежний ключ. Если злоумышленник сможет добыть прежний ключ, то он сможет выполнить процедуру модификации ключа.

Генерация ключей для асимметричных криптосистем с открытыми ключами много сложнее, потому что эти ключи должны обладать определенными математическими свойствами (они должны быть очень большими и простыми и т.д.).

В этой статье описаны способы обхода аппаратных систем защиты. В качестве примера рассмотрена технология HASP (Hardware Against Software Piracy), разработанная компанией Aladdin Knowledge Systems Ltd. В прошлом данная технология являлась одной из самых популярных аппаратных систем защиты ПО.

Мощью аппаратной защиты HASP пользуются многие серьезные разработчики софта, которые не хотят, чтобы их продукт несанкционированно распространялся. Хаспом, например, защищаются пакеты «1С.Бухгалтерия» или «1С.Предприятие», без которых не может прожить ни одно более или менее организованное дело. Популярный юридический справочник «КонсультантПлюс» также защищает доступ к данным с помощью электронных ключиков. Чтобы воспользоваться вышеупомянутым или другим не менее дорогостоящим софтом, не платя никому ни копейки, недостаточно просто полазить по Сети в поисках txt’шника с ключиками. Однако хакер всегда разберется, что делать с защитой, пусть и аппаратной. И паяльник ему для этого не понадобится.

Взглянем

Утрируя, можно сказать, что HASP состоит из двух частей: аппаратной и программной. Аппаратная часть - это электронный ключик в виде USB-брелка, PCMCIA-карты, LTP-девайса или вообще внутренней PCI-карты. Установленный софт будет работать только на той машине, в которую воткнут электронный ключ. Собственно, неплохо было бы отучить софт от такой неприятной для кошелька привычки.

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

Механизм системы защиты

Сам брелок нас почти не интересует, в отличие от ПО в его комплекте. Для нас наибольший интерес представляет модуль hardlock.sys. Не углубляясь в подробности, отмечу, что этот драйвер отвечает за взаимодействие с аппаратным ключом. Он имеет два объекта устройства, один из которых обладает символьным именем DeviceFNT0. Используя этот объект, защищенное приложение посредством диспетчера ввода-вывода проверяет лицензию на использование данного ПО.

Главным недостатком такой системы защиты является возможность перехвата вызовов диспетчера ввода-вывода и эмулирования аппаратного ключа. Существует также вариант разработки драйвера виртуального ключа, но это гораздо более сложная техническая задача, нежели перехват вызовов.
Как тебе известно, модель драйвера описывается в структуре DRIVER_OBJECT при загрузке модуля. Она хранит массив обработчиков сообщений. Причем никто не мешает переписать эти адреса и получить управление, выполнив наш код. Таким образом, можно перехватывать и подменять IRP-пакеты, подставляя лицензионные данные. Другими словами, имея дамп ключа защиты, можно передать его программе, проверяющей верность лицензионных данных!

Для эксплуатации другого метода также требуется дамп ключа, но подстановка данных осуществляется иначе, а именно - в программной эмуляции. То есть драйвер защиты сможет обращаться с виртуальным ключом так же, как и с физическим.

Перехват и эмуляция

Как уже отмечалось, идея перехвата состоит в перезаписи обработчиков IRP-пакетов. Для этого необходимо иметь возможность изменять поля структуры DRIVER_OBJECT. К счастью, существует функция IoGetDevicePointer, которая возвращает указатель на объект вершины стека именованных устройств и указатель на соответствующий файловый объект. Вот фрагмент кода функции, устанавливающей ловушку:

UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;

RtlInitUnicodeString(&DeviceName, lpDevice);
IoGetDeviceObjectPointer(&DeviceName, 1u, &FileObject, &DeviceObject);

Получив указатель на структуру DEVICE_OBJECT, имеем указатель на DRIVER_OBJECT. Теперь заменим адреса обработчиков и функций выгрузки драйвера на свои:

NTSTATUS HookDevice(LPWSTR lpDevice)

gDriverObject = DeviceObject-> DriverObject;

gDeviceControl = gDriverObject-> MajorFunction;
gDriverObject-> MajorFunction = HookDispatch;

gInternalDeviceControl = gDriverObject-> MajorFunction;
gDriverObject-> MajorFunction = HookDispatch;

gDriverUnload = gDriverObject->DriverUnload;
gDriverObject->DriverUnload = HookUnload;

ObfDereferenceObject(FileObject);

В последней строчке вызывается функция ObfDereferenceObject, которая уменьшает количество ссылок на файловый объект. Это необходимо делать для корректной выгрузки драйвера, чтобы не было утечки ресурсов и аналогичных ошибок.

Так как указатель на объект драйвера защиты сохранeн, то чтобы снять ловушку, нужно просто восстановить прежние обработчики IRP-пакетов:

void UnhookDevice(void)

gDriverObject-> MajorFunction = gDeviceControl;
gDriverObject-> MajorFunction = gInternalDeviceControl;
gDriverObject->DriverUnload = gDriverUnload;

Конечно, надо добавить соответствующие проверки на валидность указателей и прочее.

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

void HookUnload(PDRIVER_OBJECT DrvObj)

UnhookDevice();
gDriverUnload(DrvObj);

Здесь происходит восстановление полей структуры DRIVER_OBJECT, и передаeтся управление на оригинальный код выгрузки драйвера перехваченного устройства.

Аналогично поступаем, если наш драйвер завершает работу раньше системы защиты. Только нужно высвободить захваченные ресурсы и не вызывать сохранeнный gHookUnload.

Принцип работы эмулятора

Перехватчик

Зная основные принципы простейшего перехвата IRP-пакетов, приступим к реализации пока только самого перехватчика для дальнейшего анализа. Для этого создадим объект драйвера, который содержит символьное имя (например DosDevicesHook) и точки входа CREATE, CLOSE, READ.

IoCreateDevice(DriverObject, 0, &usDeviceName, FILE_DEVICE_NULL, 0, 0, &pDeviceObject);
IoCreateSymbolicLink(&usSymbolicDeviceName, &usDeviceName);

DriverObject->MajorFunction = DriverDispatch;
DriverObject->MajorFunction = DriverDispatch;
DriverObject->MajorFunction = DriverDispatch;
DriverObject->DriverUnload = DriverUnload;

Это нужно для того, чтобы работать с нашим перехватчиком как с файлом, используя функции CreateFileReadFileCloseHandle. При такой реализации обмена данными между приложением и перехватчиком невозможно сразу же отправить их пользовательской программе, поэтому необходимо создать некоторую структуру для хранения необходимых данных о пойманном пакете. Например односвязный список, как это реализовано мной. Теперь следует определиться, какую информацию нужно буферизировать. Это общая информация о пакете (тип, флаги, прочее) и, конечно, буферы. Также можно добавить время перехвата. При копировании содержимого буферов нужно помнить об их типе, иначе - крах. Забегая вперед, отмечу, что драйвер защиты использует буферизированный ввод-вывод, это немного упрощает код.

Код HookDispatch

if (idlTail->IrpData.InputLength)
{
idlTail->InputBuffer = ExAllocatePool(NonPagedPool, idlTail->IrpData.InputLength);
RtlCopyMemory(idlTail->InputBuffer, Irp->AssociatedIrp.SystemBuffer, idlTail->IrpData.InputLength);
}

if (IoSL->MajorFunction == IRP_MJ_DEVICE_CONTROL)
Status = pHookedDriverDispatch(DeviceObject, Irp);

if (idlTail->IrpData.OutputLength)
{
idlTail->OutputBuffer = ExAllocatePool(NonPagedPool, idlTail-> IrpData.OutputLength);
RtlCopyMemory(idlTail->OutputBuffer, lpBuffer, idlTail->IrpData.OutputLength);
}

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

Код DriverDispatch

Length = IoSL->Parameters.Read.Length;
if (Length == sizeof(IRP_DATA) && idlHead)
RtlCopyMemory(Irp->UserBuffer, &idlHead->IrpData, Length);
else if (idlHead && Length == (idlHead-> IrpData.InputLength + idlHead-> IrpData.OutputLength))
{
RtlCopyMemory(Irp->UserBuffer, idlHead-> InputBuffer, idlHead->IrpData.InputLength);
RtlCopyMemory((PVOID)((ULONG)Irp->UserBuffer + idlHead->IrpData.InputLength), idlHead-> OutputBuffer, idlHead->IrpData.OutputLength);
}
else if (Length == 1 && idlHead)
{
if (idlHead->InputBuffer)
ExFreePool(idlHead->InputBuffer);
if (idlHead->OutputBuffer)
ExFreePool(idlHead->OutputBuffer);

idlTemp = idlHead->ldlNext;
ExFreePool(idlHead);
idlHead = idlTemp;
if (!idlTemp)
idlTail = NULL;
}

Когда перехватчик готов, запускаем сначала его, а затем - защищенное приложение с ключами и без. Из полученных логов становится видно, какие управляющие коды посылаются и их результаты. Также можно видеть, что запросы и ответы на два различных кода (9c402450, 9c4024a0) не изменяются. Казалось бы, можно построить табличный эмулятор, но после серии запусков убеждаемся, что это невозможно, так как содержимое буферов различно, и неизвестно, как оно образуется.

Перехваченные пакеты без ключа

Перехваченные пакеты с ключом

Затем возможны несколько вариантов дальнейших действий:

  • изучать дебри драйвера защиты;
  • воспользоваться информацией самих разработчиков системы.

Оба варианта дают необходимую информацию. Итак, оказывается, содержимое пакетов шифруется публичным симметричным алгоритмом AES (Advanced Encryption Standard). Логичной целью является получение ключа шифрования.

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

Пример дампа ключа

Поэтому первое, что нужно сделать, это получить ключ. Поставленную задачу может решить обычный брутфорс:

unsigned short Key;
unsigned char RefKey, VerKey;

for (Key = 0; Key <= 0x7fff, Key++)
{
if (!HL_LOGIN(Key, 1, RefKey, VerKey))
{
HL_LOGOUT();
Break;
}
}

Функции HL_LOGIN, HL_LOGOUT доступны из HASP SDK для разработчиков приложений, защищенных на этой платформе, и имеют следующие прототипы:

WORD HL_LOGIN(WORD ModAd, Word Access, Byte *RefKey, Byt *VerKey);
WORD HL_LOGOUT(void);

Первая функция служит для открытия сессии работы с ключом защиты посредством драйвера, вторая – завершает сессию. Это прототипы старых версий HASP SDK, но работают они и с новыми типами ключей, так как разработчики обеспечили обратную совместимость.

Новый API мало отличается от старого, и это никак не сказывается на принципе работы брутфорса. Подробную документацию Hasp API, готовые реализации брутфорса и дампера ключей можно найти на .

Обработчик

Теперь есть все необходимое для корректной работы модуля. Осталось реализовать подстановку лицензионной информации. Причем можно перехватывать лишь некоторые IRP-пакеты. Здесь все уже зависит от конкретной версии ключа и защищаемой программы.

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

NTSTATUS HookDispatch():

PIO_STACK_LOCATION Stack = Irp-> Tail.Overlay.CurrentStackLocation;
ULONG IoControlCode;
if (Stack->MajorFunction == 14)
{
IoControlCode = Stack.DeviceIoControl.IoControlCode;
If (IoControlCode != 0x9c402458)
{
Return gDeviceControl(DeviceObject, Irp);
}
else
{
Encrypt(Irp->AssociatedIrp.SystemBuffer);
Crypt(Irp->AssociatedIrp.SystemBuffer, Key, DumpMemory);
}
}

Return STATUS_FAILED;

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

Код Encrypt()

void Encrypt(BYTE * Buffer)
{
WORD Seed = ((WORD )Buffer + 0x5e);
WORD Ver = ((WORD )Buffer + 0xba);

if (Ver)
{
for (int i = 0; i < 0xB9; i++) {
(WORD )(Buffer + i) += Seed;
Seed = (Seed >> 15) | (Seed << 1);
Seed -= (WORD )(Buffer + i) ^ i;
}

for (int i = 0xBE; i < 0xFF; i++) {
(WORD )(Buffer + i) -= Seed;
Seed = (Seed >> 15) | (Seed << 1);
Seed += (WORD )(Buffer + i) ^ i;
}

((WORD )Buffer + 0xba) = Seed;
}
}

Видно, что алгоритм гораздо сложнее, чем обычный сдвиг и исключающее «или». А вот алгоритм дешифрования:

Код Decrypt()

void Decrypt(BYTE* Buffer)
{
WORD Seed = ((WORD )Buffer + 0x5e);
WORD Ver = ((WORD )Buffer + 0xba);

if (Ver) {
for (int i = 0xFE; i > 0xBD; i—) {
Seed -= (WORD )(Buffer + i) ^ i;
Seed = (Seed << 15) | (Seed >> 1);
(WORD )(Buffer + i) += Seed;
}

for (int i = 0xB8; i >= 0; i—) {
Seed += (WORD )(Buffer + i) ^ i;
Seed = (Seed << 15) | (Seed >> 1);
(WORD )(Buffer + i) -= Seed;
}

((WORD )Buffer + 0xba) = Seed;
}
}

Затем следует ещe один этап преобразования данных, более сложный и уже полностью зависящий от структуры запроса. Тут не обойтись без дизассемблера, придется покопаться в бине и позаимствовать немного кода у создателей. Это непросто, так как код драйвера защиты сильно обфусцирован, но он не отличается разнообразием уловок. Достаточно будет декомпилировать драйвер не полностью, а только лишь некоторые кусочки кода.

В заключение отмечу, что построение табличного эмулятора, основанного на перехвате DeviceIoControl, - достаточно трудная задача. Но такой принцип эмулятора можно использовать и на другом уровне взаимодействия: создать виртуальную USB-шину.

Заключение

Это не единственный способ избавиться от системы защиты. Существуют и другие, более совершенные методы. Изложенные в статье принципы можно использовать и для анализа работы драйверов, перехватывая IRP-пакеты. Таким образом можно добавить неплохой инструмент в свой сделанный на коленке набор. Удачи!

Где находится дверь

роблемы защиты программного обеспечения от пиратского распространения или защиты данных от несанкционированного копирования неизбежно возникают во всем мире, доставляя немало хлопот производителям программ и хранителям конфиденциальных данных. Естественно, решение этих проблем не обходится без дополнительных неудобств, причиняемых рядовым пользователям. В настоящее время все способы защиты ПО или данных можно разделить на две основные группы:

  • защита с помощью различных аппаратных ключей (миниатюрных устройств, вставляемых в последовательные, параллельные, USB-порты, PCMCIA-слоты, специальные считывающие устройства и т.д.);
  • защита с помощью различных программных ключей и шифрования данных.

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

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

Работать с электронными «заглушками» можно как в локальном, так и в сетевом варианте. При использовании сетевого ключа нет необходимости устанавливать локальные ключи на каждое рабочее место. Лицензирование в данном случае осуществляется одним ключом с программного сервера, обрабатывающего запросы защищенных приложений. Например, если на сервер устанавливается ключ и обслуживающий его драйвер (небольшую программу, обслуживающую ключ, удобно регистрировать в Windows NT/2000/XP как сервис, запускаемый при загрузке, а в Windows 95/98/Me как резидентную программу), то любая удаленная программа может запросить с сервера лицензию и только в случае ее получения продолжить работу. Число лицензий для каждого ключа может быть специально задано, и в зависимости от того, на какое количество одновременно запущенных копий рассчитана приобретенная вами программа, она или запустится, или нет. При этом распределение лицензий, как правило, осуществляется по простому принципу: «один компьютер - одна лицензия». Это означает, что если на конкретном компьютере запущено несколько копий приложения, то на это будет отведена всего одна лицензия. Таким образом, здесь налагается ограничение на количество рабочих мест, с которых возможно одновременное использование программы.

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

Естественно, защищать свою программу или данные подобным образом следует только в том случае, если их стоимость (или нематериальная ценность) сравнима с ценой ключа аппаратной защиты (даже самый примитивный подобный ключ для параллельного порта стоит около 10 долл.).

Кроме того, правда жизни такова, что говорить об абсолютной защите при любом подходе в принципе не приходится. А для того чтобы приложение невозможно было взломать, пришлось бы полностью исключить какой-либо доступ к нему. Поэтому степень защищенности должна быть адекватна угрозе. Как подсказывает здравый смысл, чем сложнее доступ к приложению или данным, тем менее удобно с ними работать. Грамотно построенная система защиты способна противостоять взлому на том уровне, которому она может быть подвержена, и не более.

Что такое электронный ключ

лектронный ключ - это устройство, предназначенное для защиты программ и данных от несанкционированного использования, копирования и тиражирования. Он представляет собой, как правило, небольшое микроэлектронное устройство, которое имеет два разъема: один из них предназначен для подключения к параллельному или последовательному порту компьютера, а другой служит для подключения принтера, модема или других устройств, работающих с этим портом. При этом ключ не должен влиять на работу порта и должен быть полностью «прозрачным» для подключаемых через него устройств (то есть не должен мешать их нормальной работе). Существуют, впрочем, и другие виды ключей для разных портов и в различном исполнении (внутренние, внешние, в виде брелока, в виде PCMCIA или смарт-карты и т.д.). Ключи могут работать каскадно, когда к одному порту одновременно подключается несколько ключей, в том числе и разных типов. Протокол обмена данными ключа с портом, как правило, динамически изменяется, кодируется и «зашумляется» для защиты от эмуляции.

Многие современные типы ключей оснащены электрически программируемой энергонезависимой памятью. Обычно ключ не имеет встроенных источников питания, полностью пассивен и сохраняет записанную в него информацию при отключении от компьютера. Однако возможны модификации со встроенными часами и автономной батареей питания, что позволяет строить различные модели продажи, аренды, лизинга и лицензирования защищенного программного обеспечения. Интеллектуальные и физические возможности ключа во многом определяются той базой, на основе которой изготовлен ключ.

Исходя из аппаратной базы современные ключи можно подразделить на следующие типы:

  • с использованием микросхем энергонезависимой электрически перепрограммируемой памяти (EEPROM);
  • построенные на заказных конфигурациях ASIC (Application Specific Integrated Circuit);
  • с использованием чипов с памятью или без;
  • построенные на базе полнофункциональных микропроцессоров (микроконтроллеров).

По своему внешнему исполнению наиболее популярны ключи, выпускаемые в виде брелоков, для подключения к USB-портам.

Дополнительную информацию по устройству и эксплуатации ключей защиты можно найти на русском Web-сайте (http://www.aladdin.ru/) компании Aladdin Knowledge Systems (http://www.aks.com/) - разработчика системы защиты HASP.

Защита программного обеспечения и данных

аким образом можно защитить приложение при помощи электронного ключа?

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

Более сложные методы базируются на использовании специализированного API, которые поставляют производители электронных ключей разработчикам защищаемых ПО. Функции этого API предназначены для выполнения различных операций по взаимодействию программы с ключом: поиск нужного кода, чтение/запись памяти ключа, запуск аппаратных алгоритмов ключа и преобразование кода и данных приложения с их помощью.

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

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

Http://glasha.zap.to/ всем предлагаются эмуляторы ключей HASP).

Так что если речь идет о программном обеспечении, то для борьбы с пиратством значительно эффективнее наладить хорошую службу технической поддержки, а секретные данные держать в сейфе…

КомпьютерПресс 3"2002

Для борьбы с компьютерным пиратством наряду со специальными программными средствами используются и аппаратно-программные средства. Они базируются на применении электронных устройств, подключаемых либо к внутренней шине компьютера, либо к его наружным разъемам. Если оценивать степень надежности защиты объемом трудозатрат, необходимых для ее «взлома», то аппаратно-программные средства «прочнее» чисто программных.

Действительно, для вскрытия такой защиты недостаточно распутать ухищрения в программе. Необходимо восстановить протоколы и содержание обмена программ с дополнительной аппаратурой. Решение этих задач требует, как правило, применения специальных аппаратных средств типа логических анализаторов.

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

Электронные ключи могут использоваться для решения следующих задач:

  • защита программ от несанкционированного распространения;
  • защита данных от раскрытия содержащейся в них информации;
  • защита компьютеров от доступа к ним посторонних лиц

1. Защита программ осуществляется двумя способами. Первый способ (назовем его ручным) состоит во встраивании самим разработчиком в свою программу фрагментов, взаимодействующих с электронным ключом. Второй способ основан на автоматическом включении в защищаемый файл обменов с ключом. В этом случае поставляемая вместе с ключом специальная программа автоматически обрабатывает исполняемые файлы таким образом, что без ключа они оказываются неработоспособными. Преимуществом автоматической защиты перед ручной является практически нулевая трудоемкость этой процедуры. Кроме того, программа автоматической защиты создается высококвалифицированными специалистами, что обеспечивает ее большую надежность.

2. Защита данных от раскрытия содержащейся в них информации достигается путем шифрования. Существуют достаточно эффективные методы шифрования, например алгоритм DES. Однако надежность шифрования не может быть выше надежного хранения и передачи шифровального ключа. В этом случае шифровальный ключ не надо запоминать или записывать и, что очень важно, вводить в компьютер с клавиатуры. Хранящиеся в компьютере данные могут быть дешифрованы только при наличии ключа. Кроме того, для повышения надежности сама программа шифрования - дешифрования может быть защищена с помощью того же самого ключа.


3. Защита компьютера от посторонних лиц предполагает загрузку операционной системы только для санкционированных пользователей, а также обеспечение доступа каждого пользователя только к выделенным ресурсам, среди которых могут быть логические диски, каталоги и отдельные файлы. Реализация такой защиты связана с идентификацией пользователей. Для этого могут быть использованы электронные ключи. При этом возможны два подхода.

Первый подход предполагает, что каждый санкционированный пользователь имеет в своем распоряжении уникальный электронный ключ. Распознавание пользователя осуществляется без ввода каких-либо паролей после подсоединения ключа к разъему. В этом случае можно утверждать, что ключ к тайнам пользователя хранится у них в кармане. Но, если компьютер эксплуатируется в организации, то администрация, как правило, желает иметь доступ ко всем файлам и контролировать работу всех пользователей. Для этого необходимо иметь хотя бы по два одинаковых набора ключей, причем один набор хранится у руководителя организации.

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

Вопросы для самопроверки

  1. Что подразумевают по понятием «угроза» информации
  2. Характеристики случайных и преднамеренных угроз
  3. Каналы преднамеренного доступа к информации
  4. Источники нарушений информации
  5. Основные каналы утечки информации
  6. Классификация мер по защите информации и их характеристики
  7. В чем заключается стратегия и тактика защиты информации на этапе проектирования и эксплуатации систем
  8. Концепция аутентификации. Виды аутентификации
  9. Методы и средства защиты информации в каналах связи
  10. Назначение цифровой подписи и методы их построения
  11. Области применения цифровой подписи
  12. Назначение и классификация паролей. Достоинства и недостатки каждой из групп паролей
  13. Биометрические средства защиты. Их характеристики и области применения
  14. Достоинства и недостатки биометрических средств защиты
  15. Назначение электронных ключей. Сферы его применения.

Под целостностью данных понимается система правил Microsoft Access, позволяющих при изменении одних объектов автоматически изменять все связанные с ними объекты и обеспечивать защиту от случайного удаления или изменения связанных данных.

Список значений может быть задан либо фиксированным набором зна­чений, которые вводятся пользователем при создании поля, либо спис­ком значений из ссылочной таблицы или запроса.

Индекс - средство Microsoft Access, ускоряющее поиск и сортировку в таблице. Ключевое поле таблицы индексируется автоматически. Не допускается создание индексов для полей типа MEMO и «Гипер­ссылка» или полей объектов OLE.

Уникальный индекс - индекс, определенный для свойства Индекси­рованное поле значением «Да (Совпадения не допускаются)». При этом ввод в индексированное поле повторяющихся значений становится невозможным. Для ключевых полей уникальный индекс создается автоматически.

(ПО) и данных от копирования, нелегального использования и несанкционированного распространения.

Электронный ключ - небольшое по размерам аппаратное устройство.

Основой данной технологии является специализированная микросхема , либо защищённый от считывания микроконтроллер , имеющие уникальные для каждого ключа алгоритмы работы. Донглы также имеют защищённую энергонезависимую память небольшого объёма, более сложные устройства могут иметь встроенный криптопроцессор (для аппаратной реализации шифрующих алгоритмов), часы реального времени. Аппаратные ключи могут иметь различные форм-факторы , но чаще всего они подключаются к компьютеру черезUSB -, LPT -интерфейсы.

Установка ключа

После присоединения ключа к порту запустится стандартный Мастер нового оборудования. операционная система будет осведомлена о данном классе оборудования, что подтвердится наличием в консоли Мастера названия ключа Guardant Stealth/Net USB Key. После поиска и конфигурирования Мастер сообщит, что драйверы не подписаны корпорацией Майкрософт и предложит отказаться от установки. Для продолжения установки драйверов необходимо выбрать опцию “Всё равно продолжить” , после чего установка драйверов будет завершена.

Принцип действия электронных ключей таков.

Ключ присоединяется к определённому интерфейсу компьютера. Далее защищённая программа через специальный драйвер отправляет ему информацию, которая обрабатывается в соответствии с заданным алгоритмом и возвращается обратно. Если ответ ключа правильный, то программа продолжает свою работу. В противном случае она может выполнять любые действия, заданные разработчиками - например, переключаться в демонстрационный режим, блокируя доступ к определённым функциям.

Для обеспечения безопасности сетевого ПО служат специальные электронные ключи. Для защиты и лицензирования (ограничения числа работающих в сети копий программы) сетевого продукта достаточно одного ключа на всю локальную сеть . Ключ устанавливается на любой рабочей станции или сервере сети.

Многие компании, работающие в области защиты информации , предлагают свой взгляд на то, каким должен быть электронный ключ. На российском рынке наиболее известны следующие линейки продуктов (в алфавитном порядке): CodeMeter от WIBU-SYSTEMS, Guardant от компании «Актив», HASP от Aladdin, LOCK от Astroma Ltd., Rockey от Feitian, SenseLock от Seculab, Sentinel от SafeNet и др.

История

Защита ПО от нелицензионного пользования увеличивает прибыль разработчика. На сегодняшний день существует несколько подходов к решению этой проблемы. Подавляющее большинство создателей ПО используют различные программные модули, контролирующие доступ пользователей с помощью ключей активации, серийных номеров и т. д. Такая защита является дешёвым решением и не может претендовать на надёжность. Интернет изобилует программами, позволяющими нелегально сгенерировать ключ активации (генераторы ключей ) или заблокировать запрос на серийный номер/ключ активации (патчи , крэки ). Кроме того, не стоит пренебрегать тем фактом, что сам легальный пользователь может обнародовать свой серийный номер.

Эти очевидные недостатки привели к созданию аппаратной защиты программного обеспечения в виде электронного ключа. Известно, что первые электронные ключи (то есть аппаратные устройства для защиты ПО от нелегального копирования) появились в начале 1980ых годов, однако первенство в идее и непосредственном создании устройства по понятным причинам установить очень сложно.

Защита ПО с помощью электронного ключа

^ Комплект разработчика ПО

Донгл относят к аппаратным методам защиты ПО, однако современные электронные ключи часто определяются как мультиплатформенные аппаратно-программные инструментальные системы для защиты ПО. Дело в том, что помимо самого ключа компании, выпускающие электронные ключи, предоставляют SDK (Software Developer Kit - комплект разработчика ПО). В SDK входит все необходимое для начала использования представляемой технологии в собственных программных продуктах - средства разработки, полная техническая документация , поддержка различных операционных систем , детальные примеры, фрагменты кода. Также SDK может включать в себя демонстрационные ключи для построения тестовых проектов.

^ Технология защиты

Технология защиты от несанкционированного использования ПО построена на реализации запросов из исполняемого файла или динамической библиотеки к ключу с последующим получением ответа (и, если предусмотрено, анализом этого ответа). Вот некоторые характерные запросы :


  • проверка наличия подключения ключа;

  • считывание с ключа необходимых программе данных в качестве параметра запуска;

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

  • проверка целостности исполняемого кода путём сравнения его текущей контрольной суммы с оригинальной контрольной суммой, считываемой с ключа;

  • запрос к встроенным в ключ часам реального времени (при их наличии) и т. д.
Стоит отметить, что некоторые современные ключи (ключи Senselock от Seculab, Rockey6 Smart от Feitian, Guardant Code от Компании Актив) позволяют разработчику хранить отдельные части кода приложения (например, недетерминированные специфические алгоритмы разработчика, получающие на вход большое число параметров) и исполнять их в самом ключе на его собственном микропроцессоре . Помимо защиты ПО от нелегального использования такой подход позволяет защитить используемый в программе алгоритм от изучения и клонирования конкурентами. Однако простой алгоритм (а большинство из тех, что можно туда поместить именно таких) можно успешно криптоанализировать по методу анализа "черного ящика".

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

Алгоритм шифрования может быть секретным или публичным. Секретные алгоритмы разрабатываются самим производителем средств защиты, в том числе и индивидуально для каждого заказчика. Главным недостатком использования таких алгоритмов является невозможность оценки криптографической стойкости . С уверенностью сказать, насколько надёжен алгоритм, можно было лишь постфактум: взломали или нет. Публичный алгоритм, или «открытый исходник», обладает криптостойкостью несравнимо большей. Такие алгоритмы проверяются не случайными людьми, а рядом экспертов, специализирующихся на анализе криптографии . Примерами таких алгоритмов могут служить широко используемые ГОСТ 28147-89 , AES , RSA , Elgamal и др.

^ Обход защиты

Задача злоумышленника - заставить защищённую программу работать в условиях отсутствия легального ключа, подсоединённого к компьютеру. Не вдаваясь очень глубоко в технические подробности, будем исходить из предположения, что у злоумышленника есть следующие возможности:


  • Перехватывать все обращения к ключу;

  • Протоколировать и анализировать эти обращения;

  • Посылать запросы к ключу и получать на них ответы;

  • Протоколировать и анализировать эти ответы;

  • Посылать ответы от имени ключа и др.
Такие широкие возможности противника можно объяснить тем, что он имеет доступ ко всем открытым интерфейсам , документации , драйверам и может их анализировать на практике с привлечением любых средств.

Для того чтобы заставить программу работать так, как она работала бы с ключом, можно или внести исправления в программу (взломать её программный модуль ), или эмулировать наличие ключа.

^ Эмуляция ключа

При эмуляции никакого воздействия на код программы не происходит, и эмулятор, если его удается построить, просто повторяет все поведение реального ключа. Эмуляторы строятся на основе анализа перехваченных запросов приложения и ответов ключа на них. Они могут быть как табличными (содержать в себе все необходимые для работы программы ответы на запросы к электронному ключу), так и полными (полностью эмулируют работу ключа, так как взломщикам стал известен внутренний алгоритм работы).

Построить полный эмулятор современного электронного ключа - это достаточно трудоёмкий процесс, требующий большого количества времени и существенных инвестиций. Ранее злоумышленникам это удавалось: например, компания Aladdin признаёт, что в 1999 году злоумышленникам удалось разработать довольно корректно работающий эмулятор ключа HASP3. Это стало возможным благодаря тому, что алгоритмы кодирования были реализованы программно. Аппаратная реализация кодирования существенно усложнила задачу, поэтому злоумышленники предпочитают атаковать какой-то конкретный защищённый продукт, а не защитный механизм в общем виде. Тем не менее взлому были подвержены и ключи серии HASP4. И по сей день в природе имеются эмуляторы для HASP HL (HASP 5), но не в так называемом «паблике» (публичном доступе).

^ Взлом программного модуля

Злоумышленник исследует логику самой программы, с той целью, чтобы, проанализировав весь код приложения, выделить блок защиты и деактивировать его. Взлом программ осуществляется с помощью отладки (или пошаговое исполнение), декомпиляции и дампа оперативной памяти . Эти способы анализа исполняемого кода программы чаще всего используются злоумышленниками в комплексе.

Отладка осуществляется с помощью специального ПО - отладчика, который позволяет по шагам исполнять любое приложение, эмулируя для него операционную среду. Важной функцией отладчика является способность устанавливать точки или условия остановки исполнения кода. С помощью них злоумышленнику проще отслеживать места в коде, которые реализуют обращение к ключу (например, остановка выполнения на сообщении типа «Ключ отсутствует! Проверьте наличие ключа в USB-интерфейсе»).

Дизассемблирование - это способ преобразования исполняемых модулей в язык программирования, понятный человеку - Assembler . В этом случае злоумышленник получает распечатку (листинг ) того, что делает приложение.

Суть атаки с помощью дапма памяти заключается в следующем. Специальные программы (дамперы) считывают содержимое оперативной памяти на тот момент, когда приложение начало нормально исполняться, и злоумышленник получает рабочий код (или интересующую его часть) в чистом виде. Главное для злоумышленника - верно выбрать этот момент. К примеру, часть кода появляется в оперативной памяти в открытом виде только на время своего исполнения.

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