На главную | Содержание | Назад | Вперёд
Наши друзья

 

 

Дилемма защитника

Внешний язык, который определяется правилами входных данных компьютерной программы, всегда является гораздо более сложным, чем это представляется программисту. Одна из сложностей состоит в том, что программа интерпретирует команду исходя из своего внутреннего состояния, что очень трудно поддается оценке. Чтобы установить полное соответствие возможностей специально подготовленных данных на языке программирования со всеми возможными внутренними состояниями программы, требуется узнать обо всех возможных внутренних состояниях программы, а также обо всех логических решениях в программе, которые влияют на ее состояние. Поскольку диапазон состояний крайне велик, предсказать что-либо очень сложно.
Хакеры хотят привести программу в такое состояние, при котором подготовленные входные данные обеспечат выход программы из строя, а также появится возможность введения собственного кода или запуска привилегированных команд. Достаточно просто описать ситуации, при которых это возможно. Намного сложнее доказать, что таких ситуаций не существует. Сложность всегда "на стороне" хакера, и она практически всегда гарантирует ему успех атак. Как можно сохранить в безопасности что-то непонятное? Специалисты по защите компьютерных систем находятся в очень неудобном положении, ведь для защиты от атак нужно знать обо всех возможных атаках против своей системы, а хакеру для проведения атаки достаточно найти только одну эффективную программу атаки.
Согласно логике опровержения утверждения (о безопасности системы), достаточно найти только один случай, при котором утверждение неверно (т.е. существует возможность успешного взлома системы). С другой стороны, для доказательства утверждения недостаточно привести один или более примеров, когда утверждение справедливо (т.е. примеры неудачных попыток взлома).
Очевидно, что обеспечение защиты является весьма сложной задачей и даже практически невозможной в некоторых случаях. Под "видимой" логикой вычислительной системы скрывается "дракон сложности". Долгие годы некоторые поставщики программ по обеспечению безопасности игнорировали наиболее серьезные трудности, давая нереальные обещания, которые были основаны на нескольких простых примерах.
Брандмауэры, антивирусные системы и системы обнаружения вторжений представляют собой технологии, которые работают в ответ на сложившуюся ситуацию. Эти системы пытаются остановить "опасные" входные данные и предотвратить проведение опасных вычислений. Значительно эффективнее было бы создать более сложную вычислительную систему, которая бы не требовала такой защиты. Проблема усугубляется следующим обстоятельством: как правило, вообще непонятно, что следует блокировать, а что — нет. Не существует универсального списка недопустимых входных данных, поскольку в каждой программе используется свой уникальный "язык".
Повторим еще раз: создание списка допустимых входных данных ("белый список") значительно эффективнее, чем создание "черных списков"блокируемых данных. Вместо того чтобы заниматься определением всех возможных вредоносных входных данных, лучше создать список "того, что разрешено" и придерживаться этого списка. В этом и заключается принцип наименьших привилегий. Предоставляйте своим программам столько прав, сколько им необходимо для нормальной работы, и ничего более. Не следует предоставлять слишком большие привилегии, а затем блокировать входные данные.
Фильтры
Некоторые программисты, которые с недавних пор начали беспокоиться о безопасности, стремятся добавить фильтры или специальный код для блокирования "некорректных" запросов1. Вместо того чтобы в первую очередь устранить возможность программы открывать критически важные файлы, программист добавляет фильтры, которые не пропускают "опасных" имен файлов. Безусловно, такой метод изначально является ошибочным. Как можно сказать, что что-то является "плохим", когда вы не знаете, как именно "оно выглядит"? Можно ли создать универсальное правило для блокирования всех вредоносных данных?
Рассмотрим пример. Если предоставленные пользователем данные подаются на вход вызова функции файловой системы, то при наличии в запросе строки ". . / . ." программист может заблокировать такие запросы. В данном случае программист пытается остановить вредоносное использование системного вызова для проведения хакером атаки с использованием перехода по дереву каталогов. Системные вызовы, которым предоставлены чрезмерные привилегии, вполне могут позволить злоумышленнику скачать файл или получить доступ к любому файлу в файловой системе, если будет указан путь к этому файлу относительно текущего каталога. Обычно программист "исправляет" эту ошибку, используя правило для выявления строки ". . /" в строке входных данных. Но обратите внимание, что это напоминает обнаружение вторжений, т.е. мы пытаемся выявить "некорректные" данные. Неизвестно, что произойдет, если хакер использует строку " . . . //..." или закодирует символ косой черты в шестнадцатеричном формате (ведь это зависит еще и от правила, заданного программистом).
Взаимодействующие системы
Давайте рассматривать все программное обеспечение как систему. Основными целями хакеров являются подсистемы или системы большого масштаба. В атакуемых подсистемах могут храниться данные, которые представляют интерес для хакера. Например, злоумышленник может подготовить такие входные данные, которые приведут к возникновению события, опасного для безопасности системы.
Каждая подсистема, как правило, находится во взаимодействии с другими подсистемами. Данные взаимодействующих подсистем могут быть необходимы для проведения вычислений, но это взаимодействие иногда позволяет хакеру использовать одну уязвимую подсистему для атаки на другие (более надежные) подсистемы. Таким образом, взаимодействие между системами следует всегда рассматривать как еще один уровень для распространения подготовленных хакером вредоносных данных. Точный формат и порядок данных, которые переда­ются согласно установленным для подсистемы правил, является "диалектом" языка вредоносных входных данных.

 

На главную | Содержание | Назад | Вперёд
 
Яндекс.Метрика