Основы защиты информации. Учебное пособие
.pdf2.3.9. ОТКАЗ В ОБСЛУЖИВАНИИ
Другое название этих атак – DoS-атаки (Denial of Service). Наиболее часто встречающиеся DoS-атаки:
1) атаки, вызывающие крах приложения или операционной системы. Такие атаки всегда используют недостатки не очень качественно написанных программ. Чтобы избежать подобных проблем при написании защищенного кода, нужно проверять всё что только можно (например, не указывает ли указатель на NULL);
2)атаки, вызывающие перегрузку процессора. Цель подобных атак – заставить приложение «зависнуть» в цикле ресурсоемких вычислений. Обычно такая атака имеет шанс стать успешной, если некоторые функции программы написаны неоптимально и без учета возможности их использования злоумышленником;
3)атаки, вызывающие нехватку памяти. Такие атаки могут завершиться успешно, например, если в программе не проверяется успеш-
ность выделения памяти оператором new. Один из способов предотвращения подобных атак – не создавать «тяжеловесных» структур до тех пор, пока не установлено, что на другом конце подключения находится правомочный клиент;
4) атаки, вызывающие нехватку ресурсов, например, сокетов, подключений к базе данных и пр. Основная проблема здесь в том, что злоумышленник может попытаться занять много ресурсов, не освобождая их. В качестве решения этой проблемы можно предложить ограничить некоторым предельным значением выделение ресурса каждому пользователю. Один из лучших способов борьбы с нехваткой ресурсов – запрограммировать приложение так, чтобы его поведение менялось в зависимости от того, подвергается оно в данный момент атаке или нет.
2.4. СПОСОБЫ ЗАЩИТЫ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ОТ НЕСАНКЦИОНИРОВАННОГО ТИРАЖИРОВАНИЯ
2.4.1. РЕГИСТРАЦИОННЫЕ КОДЫ
Поскольку имя пользователя не является уникальным, каждый экземпляр продаваемой продукции целесообразно связывать с некоторым неповторяющимся значением, называемым серийным номе-
41
ром или регистрационным кодом. Это позволяет производителю собирать статистические данные о своих клиентах, а в случае незаконного распространения программного продукта вместе с серийным номером найти и наказать ассоциированного с этим номером пользователя.
Программа должна содержать некоторый механизм, позволяющий проверить, является ли введенный пользователем серийный номер (или регистрационный код) правильным. Причем те фрагменты кода или данных, доступ к которым разрешен только легальным пользователям, следует зашифровать стойким алгоритмом, а ключ шифрования вычислять, используя регистрационный код. Тогда без знания регистрационного кода получить полноценную версию программы не удастся.
Еще одна идея, позволяющая улучшить стойкость защиты, – это применение распределенных проверок правильности введенного регистрационного кода. Этот подход заключается в том, что введенный код проверяется не сразу в одном месте, а частями и в разных местах программы, причем неоднократно проверяется одно и то же. Если выяснилось, что регистрационные данные неверны, то вовсе не обязательно сразу же сообщать об этом пользователю. Лучше установить специальный флаг, указывающий на то, что программа не была корректно зарегистрирована, а в другой функции, относящейся к совершенно иному фрагменту программы, анализировать один или несколько таких флагов и предпринимать соответствующие действия.
Рассмотримкритерии сравнения свойств регистрационныхкодов:
1)возможность связать код с именем пользователя или характеристиками компьютера;
2)невозможность вычислить какой-нибудь правильный код, имея в распоряжении только алгоритм проверки;
3)невозможность вычислить код для определенного пользователя, зная алгоритм проверки и правильный код другого пользователя;
4)невозможность расшифровать программу (получить ключ шифрования) при наличии заблокированного (занесенного в черный список) регистрационного кода;
5)длина ключевой строки (удобство пользователя).
42
Все методы проверки правильности кодов можно условно разделить на три категории:
1)алгоритмические, основанные на принципе «черного ящика».
При использовании «черного ящика» разработчик старается запутать алгоритм проверки, чтобы его было труднее понять. Такой подход применяют не только неопытные разработчики. «Черный ящик» сравнительно прост в реализации и позволяет использовать короткие коды, привязанные к имени пользователя. Но почти всегда в этом подходе возможно использование генератора ключей;
2)алгоритмические, основанные на математически сложной за-
даче, не нуждаются в сокрытии деталей реализации. Их особенность в том, что для генерации кода и проверки его правильности используются два разных алгоритма, и получение алгоритма генерации из алгоритма проверки является математической задачей, не имеющей в настоящее время эффективного решения. Чаще всего для этих целей используются криптографические алгоритмы с открытым ключом. Однако у асимметричной криптографии есть одна особенность: размер блока, над которым производятся операции, довольно большой. Очевидно, что ввести без ошибок длинную бессмысленную последовательность, состоящую из букв, цифр и знаков препинания, почти невозможно, что делает данную схему неудобной для пользователя;
3)табличные. В табличных методах генерируется заданное количество регистрационных кодов (по числу возможных пользователей), и
впрограмме хранятся таблицы, построенные на основе этих кодов. Разумеется, коды не могут зависеть от имени пользователя или характеристик системы, так как генерируются до того, как появляются первые зарегистрированные пользователи. Самый простой способ – хранить в программе результат вычисления криптографической хэш-функции от каждого кода. При этом легко проверить правильность ключа, вычислив его хэш, но, имея значение хэша, вычислить ключ практически невозможно. Недостатками табличных методов являются невозможность привязать код к имени пользователя и значительный объем памяти, требуемый для хранения таблиц (из-за большого числа пользователей).
Таким образом, при выборе оптимального метода генерации ключей в каждом конкретном случае стоит руководствоваться свойствами продукта, характеристиками потенциального рынка и т. д.
43
При создании демонстрационной версии для отключения некоторых функциональных элементов не стоит делать их просто недоступными. Лучше сделать так, чтобы те функции, которые должны присутствовать только в полной версии, были исключены из исходного кода перед сборкой программы. Для того чтобы не пришлось писать две очень похожие программы, можно использовать препроцессорные директивы условной компиляции #define, #ifndef, #ifdef, #else,
#endif, которые позволяют включать или не включать определенные части программного кода в зависимости от одного препроцессорного определения вида
#define FULLVERSION
Приведем пример, как это может выглядеть на практике:
#define FULLVERSION
. . .
#ifdef FULLVERSION
/* Код полной версии */ #else
/* Код демоверсии */ #endif
Здесь в зависимости от того, была ли определена препроцессорная переменная FULLVERSION, включается или не включается соответствующий код.
2.4.2. ПРИВЯЗКА К НОСИТЕЛЯМ ИНФОРМАЦИИ
Идея этого способа защиты от тиражирования программ заключается в том, что программа должна запускаться и работать только в том случае, если пользователь вставил в дисковод оригинальный диск.
Во времена DOS в качестве оригинальных дисков использовались дискеты, которые специальным образом делались некопируемыми. Для этого применялось форматирование дискет с нестандартным размером сектора или нанесение физических повреждений на магнитный слой.
После того как дискеты стали выходить из употребления, в качестве оригинальных дисков стали использовать CD-диски.
Способы защиты от тиражирования при использовании CD-дисков: 1) защищаемая программа может проверять метку тома диска, се-
рийный номер и т. п.;
44
2)незначительно изменив параметры диска, на него можно записать больше данных, чем при обычной записи (например, на CD-диск можно записать больше 700 Мб), при этом диск будет без проблем читаться в большинстве приводов CD-ROM;
3)при записи оригинального диска можно отклониться от стандарта записи на диск;
4)внесение нарушений в область данных диска, которые приводят
кошибкам чтения.
2.4.3.АППАРАТНЫЕ КЛЮЧИ
Сточки зрения подключения существуют аппаратные ключи следующих видов: на порт принтера (LPT), последовательный порт (COM), USB-порт и ключи, подключаемые к специальной плате, вставляемой внутрь компьютера. Но с точки зрения защиты по-настоя- щему важно только то, что в ключе является секретным и неповторимым.
Для того чтобы заставить программу работать так, как она работала бы с ключом, можно или внести исправления в программу, или эмулировать наличие ключа. Модификация программы, как правило, возможна лишь в тех случаях, когда ответы, полученные от ключа, просто проверяются, но не являются необходимыми для дальнейшей работы программы. При эмуляции никакого воздействия на программу не происходит и полный эмулятор, если его удается построить, просто повторяет всё поведение реального ключа.
Классификация аппаратных ключей
1.Ключи с памятью. Ключи с памятью имеют определенное число ячеек, из которых разрешено считывание. В некоторые из этих ячеек также может производиться запись. Ключи с памятью не способны противостоять эмуляции. Достаточно один раз прочитать всю память и сохранить ее в эмуляторе, после чего правильно эмулировать ответы на все запросы к ключу не составит большого труда.
2.Ключи с неизвестным алгоритмом. Многие современные аппаратные ключи содержат секретную функцию преобразования данных, на которой и основывается секретность ключа. При разработке защиты программист делает несколько запросов к алгоритму и запоминает по-
45
лученные ответы. Во время выполнения программа повторяет те же запросы и сравнивает полученные ответы с сохраненными значениями. Если обнаруживается несовпадение, значит, программа получает ответ не от оригинального ключа. Недостатком такого подхода является то, что существует возможность построения табличного эмулятора, который будет знать правильные ответы на все запросы, их результат может проверить программа.
3.Ключи с известным алгоритмом. Пусть аппаратный ключ реализует симметричный алгоритм шифрования, а программист имеет возможность выбирать используемый ключ шифрования. В такой схеме программа может передавать данные на вход аппаратного ключа и получать в ответ результат шифрования на выбранном ключе. Но тогда если в программе отсутствует ключ шифрования, то возвращаемые данные можно проверять только табличным способом, а значит, в ограниченном объеме. Если же ключ шифрования известен программе, то существует возможность извлечь ключ шифрования и построить эмулятор.
Когда ключ реализует асимметричный алгоритм шифрования, программисту не обязательно знать используемый секретный ключ, достаточно знать открытый ключ. Эта схема не может быть обойдена только эмуляцией, так как для построения полного эмулятора требуется по открытому ключу шифрования вычислить секретный ключ, а это математически сложная задача.
4.Ключи с программируемым алгоритмом. Это ключи, в которых может быть реализован произвольный алгоритм. Сложность алгоритма ограничивается только объемом памяти и системой команд ключа.
Вэтом случае для защиты программы важная часть вычислений переносится в ключ и у противника не будет возможности запротоколировать правильные ответы на все запросы или восстановить алгоритм по функции проверки. Главное – это реализовать в ключе такую функцию, чтобы противник не смог по контексту догадаться, какие именно операции производятся в ключе.
Утверждение, что аппаратные ключи способны остановить компьютерное пиратство, является мифом, многие годы распространяемым производителями ключей. Для хорошо подготовленного противника ключ редко является серьезным препятствием.
46
К тому же часто программисты слепо доверяют автоматизированным средствам защиты, поставляемым вместе с ключами, и не прикладывают самостоятельных усилий для усиления защиты.
Большая часть защитных механизмов, применяемых в современных ключах, реализуется на программном уровне. Следовательно, почти всегда тот же уровень защиты может быть достигнут без привлечения аппаратных средств.
2.4.4. ПРОТЕКТОРЫ
Протекторы – это программные инструменты, предназначенные для защиты других программ. Прежде всего протекторы защищают программу от исследования. При этом защищаться могут код программы, данные, ресурсы.
Некоторые протекторы позволяют создавать версии программы с ограничениями. Например, защищенная программа может прекратить работать через заданный промежуток времени, если не будет введен правильный регистрационный код или до ввода кода будет регулярно появляться окно с предложением приобрести лицензию или напоминанием о том, что программа не зарегистрирована.
Наиболее современные протекторы имеют программные интерфейсы, доступные из защищаемой программы и позволяющие более четко контролировать процесс ее выполнения. Часто программные интерфейсы используются для динамической разблокировки фрагментов кода, которые должны быть доступны только в зарегистрированной версии.
Для того чтобы защитить исполняемый файл, протектор должен каким-то образом преобразовать его содержимое и добавить свой код, отвечающий за правильную загрузку измененной программы в память. Код, данные и ресурсы обычно защищаются с помощью шифрования.
При запуске защищенной программы управление сразу получает код протектора, который выполняет предусмотренные проверки и расшифровывает в памяти все необходимые области, а также проводит настройку таблицы адресов импортируемых функций. После успешного завершения процедуры настройки протектор передает управление на оригинальную точку входа и начинается выполнение основной программы.
47
Недостатки использования протекторов:
1)протекторы вызывают дополнительный расход памяти и замедляют работу программ;
2)защищаемая программа может работать нестабильно. Для того чтобы усложнить работу исследователя, разработчики протектора вынуждены идти на использование нестандартных или недокументированных особенностей операционных систем и оборудования. Но поскольку с некоторой периодичностью появляются новые версии операционных систем и оборудования, любая недокументированная особенность, существовавшая ранее, может отсутствовать в новой версии.
Ктому же из-за разнообразия версий программного обеспечения и оборудования невозможно проверить обнаруженную особенность на всех конфигурациях, которые могут встретиться у пользователя.
Грамотное использование протекторов позволяет значительно усложнить задачу снятия защиты и, если не предотвратить взлом, значительно снизить его рентабельность. Нелегальные копии программ с хорошей защитой часто появляются в Интернете только благодаря кардингу: если взломать программу не удается, можно купить лицензию, воспользовавшись украденным номером кредитной карты.
2.5. ИЗБЫТОЧНАЯ ЗАЩИТА ПРИЛОЖЕНИЙ
При разработке программного продукта всегда должен возникнуть вопрос: нужно ли усиливать защиту до тех пор, пока это возможно, или стоит остановиться, достигнув определенного уровня защиты?
Прежде чем ответить на этот вопрос, нужно отметить, что существуют две принципиально разные категории продуктов, использующих средства защиты информации. К первой категории относятся такие продукты, для которых обеспечение информационной безопасности – первоочередная задача. Во вторую категорию попадают прикладные продукты из любых других областей, по тем или иным причинам нуждающиеся в средствах защиты.
При разработке решений, относящихся к первой категории, всё должно быть нацелено именно на обеспечение максимальной степени защиты, пусть даже в ущерб другим характеристикам. Для продуктов, относящихся ко второй категории, обеспечение безопасности – не ос-
48
новная задача. Поэтому в данном случае нужно искать компромисс между удобством и степенью защиты.
Последствия применения избыточной защиты
1.Неудобства для пользователей. Неудобства для пользователей могут создавать слишком длинные регистрационные ключи, процедуры активации и т. п.
2.Снижение производительности, вызванное регулярными дополнительными проверками легальности использования программного продукта.
3.Сбои в системе защиты. Поскольку внедрение защитных механизмов в программу приводит к увеличению ее сложности, возрастает вероятность нестабильной работы программы и отказа в доступе легитимному пользователю.
2.6. КРИТЕРИИ СРАВНЕНИЯ СРЕДСТВ ЗАЩИТЫ ПРИЛОЖЕНИЙ
Поскольку почти всегда можно найти более одного способа решения той или иной задачи, желательно иметь некоторые критерии, позволяющие оценивать и сравнивать между собой разные варианты решений. Рассмотрим критерии сравнения средств защиты приложений.
Качество защиты
Проблема оценки качества защиты заключается в том, что отличить качественную защиту от некачественной очень трудно, особенно неискушенному в области информационной безопасности пользователю.
При оценке качества работы средств защиты далеко не все аспекты можно увидеть невооруженным глазом, а стоимость проведения независимой экспертизы с большой вероятностью окажется очень высокой по сравнению со стоимостью программного продукта. Редко какой пользователь станет тратить средства на экспертизу, поэтому оценка качества средств защиты почти всегда основывается на сравнении заявленных разработчиком характеристик и интерфейса, хотя ни то ни другое не отражает реальных свойств защиты. Причем описываемые достоинства могут быть и выдуманными, а о некоторых недостатках
49
разработчик не всегда знает в силу своих заблуждений или элементарной технической безграмотности.
Надежность защиты
По-настоящему надежными могут считаться только те средства защиты, которые во всех возможных (а не только часто используемых) режимах не оставляют противнику шанса эффективно реализовать одну из угроз безопасности на протяжении всего срока жизни защищаемой информации.
Такие жесткие требования практически невозможно удовлетворить
всилу следующих причин:
1)во-первых, стойкость таких элементов защиты, как шифрование,
вподавляющем большинстве случаев можно оценить исключительно экспертными методами. Однако никто не даст гарантии, что шифрование абсолютно надежно и эффективный метод взлома не существует или никогда не будет найден;
2)во-вторых, проверить безошибочное функционирование средств защиты реальной программы во всех возможных режимах ее работы практически невозможно;
3)в-третьих, существуют способы защиты, в которых приходится прибегать к использованию методов, не имеющих математического обоснования стойкости, т. е. сложность взлома защиты определяется сложностью анализа внутреннего устройства «черного ящика». И если «черный ящик» реализован чисто программными средствами, то никаких технических препятствий анализу не существует. Здесь ключевую роль играет следующий принцип: «То, что один человек построил, другой всегда сможет разобрать».
Экономическая эффективность защиты
Защита будет эффективной тогда, когда взлом или обход защиты перестает быть самым дешевым способом получения доступа к защищаемой информации. Но если стоимость защищаемой информации оказывается ниже стоимости средств защиты, то такую защиту трудно назвать эффективной.
Выгодность взлома некоторого средства защиты значительно повышается, если это средство используется многократно при защите различных программ. И может наступить момент, когда затраты на
50
