Неявный самоконтроль как средство создания не ломаемых защит [Крис Касперски] (pdf) читать постранично

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

Крис Касперски

íÍåÿâíûé ñàìîêîíòðîëü
êàê ñðåäñòâî ñîçäàíèÿ
íå ëîìàåìûõ çàùèò

kk@sendmail.ru

Крис Касперски
kk@sendmail.ru

Неявный самоконтроль как средство
создания не ломаемых защит

Введение
сновная ошибка подавляющего большинства разработчиков защитных
механизмов состоит в том, что они дают явно понять хакеру, что защита
еще не взломана. Если защита сообщает "неверный ключевой файл (пароль)", то
хакер ищет тот код, который ее выводит и анализирует условия, которые приводят
к передаче управления на данную ветку программы. Если защита в случае неудач
ной аутентификации блокирует некоторые элементы управления и/или пункты ме
ню, – хакер либо снимает такую блокировку в "лоб", либо устанавливает точки
останова (в просторечии называемые бряками) на APIфункции, посредством ко
торых такое блокирование может быть осуществлено (как правило это EnableWin
dows), после чего он опятьтаки оказывается в непосредственной близости от за
щитного механизма, который ничего не стоит проанализировать и взломать. Даже
если защита не выводит никаких ругательств на экран, а просто тихо "кончает",
молчаливо выходя из программы, то хакер либо ставит точку останова на функцию
exit, либо тупо трассирует программу и, дождавшись момента передачи управления
на exit, анализирует один или несколько последующих условных переходов в цепи
управления, – какойто из них непосредственно связан с защитой!
В некоторых защитных механизмах используется контроль целостности
программного кода на предмет выявления его изменений. Теперь, если хакер под
правит несколько байтиков в программе, защита немедленно обнаружит это
и взбунтуется. Святая простота! – воскликнет хакер, – и отключит самоконтроль
защиты, действуя тем же самым способом, что описан выше. По наблюдениям ав
тора, типичный самоконтроль выявляется и нейтрализуется за несколько минут.
Наиболее сильный алгоритм защиты: использовать контрольную сумму критиче
ских участков защитного механизма для динамической расшифровки некоторых
веток программы ломаются уже не за минуты, а за часы (в редчайших случаях –
дни). Алгоритм взлома выглядит приблизительно так: а) подсмотрев контрольную
сумму в оригинальной программе, хакер переписывает код функции CalculateCRC,
заставляя ее всегда возвращать это значение, не выполняя реальной проверки;
б) если защита осуществляет подсчет контрольной суммы различных участков

О

Неявный самоконтроль как средство создания не ломаемых защит
программы и/или разработчик использовал запутанный самомодифицирующийся
код, трудно предсказуемым способом меняющий свою контрольную сумму, то ха
кер может изменить защиту так, чтобы она автоматически само, восстанавливалась
после того, как все критические участки будут пройдены; в) отследив все вызовы
CalculateCRC, хакер может просто снять динамическую шифровку, расшифровав
ее вручную, после чего надобность в CalculateCRC пропадает.
Стоит отметить, что независимо от способа своей реализации любой само
контроль элементарно обнаруживается установкой точек останова на те участки за
щитного механизма, которые были изменены. Остальное – дело техники. Можно
сколь угодно усложнять алгоритм подсчета контрольной суммы, – напичкивать его
антиатладочными приемами, реализовать его на базе собственных виртуальных ма
шин (то есть интерпретаторов), некоторые из которых, такие, например, как
Стрелка Пирса, достаточно трудно проанализировать. Но… если такие меры
и остановят взломщика, то ненадолго.

Техника неявного контроля
шибка традиционного подхода заключается в его предсказуемости.
Любая явная проверка чего бы то ни было, независимо от ее алгорит
ма – это зацепка! Если хакер локализует защитный код, то все – пиши пропало.
Единственный надежный способ отвадить его от взлома – "размазать" защитный
код по всей программе с таким расчетом, чтобы нейтрализовать защиту без полно
го анализа всей программы целиком – было заведомо невозможным. К сожалению,
существующие методики "размазывания" либо многократно усложняют реализа
цию программы, либо крайне неэффективны. Некоторые программисты вставляют
в программу большое количество вызовов одной и той же защитной функции, иду
щих из различных мест, наивно полагая тем самым, что хакер будет искать и анали
зировать их все. Да как бы не так! Хакер ищет ту самую защитную функцию и пра
вит ее. К тому же, зная смещение вызываемой функции, найти, отследить ее вызо
вы можно без труда! Даже если встраивать защитную функцию непосредственно
в место ее вызова, – хакер сможет найти все такие места тупым поиском по сигна
туре. Пускай, оптимизирующие компиляторы, несколько меняют тело inlineфунк
ций с учетом контекста конкретного вызова – эти изменения не принципиальны.
Реализовать же несколько десятков различных защитных функций – слишком