Введение
Степень защищенности вашего компьютера во многом зависит от совершенства установленной на нем операционной системы.
Несколько утрируя можно сказать: что максимально достижимая
защищенность узла никогда не превосходит степени защищенности самой ОС
(разумеется, при условии, что узел не оснащен никакими внешними
защитами, такими например, как брандмаузер).
Представляется логичным протестировать несколько популярных
систем, отобрать из них наиболее защищенную и. Тут-то и выясняется,
что:
а) такого тестирования еще никто не проводил, во всяком случае,
материал найденный по этой теме в Сети, носит субъективный и
поверхностный характер, сильно завязанный на непринципиальных
недостатках конкретных реализаций ОС, большая часть из которых
давным-давно исправлена очередной заплатой;
б) если семейство NT представлено всего тремя операционными
системами: самой NT, Windows 2000 и Windows XP с практически
идентичными архитектурами, то пестрота UNIX-подобных систем вообще не
поддается описанию;
в) очень трудно выбрать адекватные критерии защищенности: количество зафиксированных взломов данной ОС
- это не совсем тот показатель, который нам нужен: во-первых, точной
статистики у нас нет и не может быть в принципе (по настоящему успешные
взломы как правило не регистрируются), а, во-вторых, статистика такого
рода отражает не защищенность, а распространенность тех или иных систем
и в значительной степени искажена преобладающим интересом хакеров
(попросту говоря модой); количество обнаруженных дыр - само по себе еще ни о чем не говорит (уже хотя бы по указанным выше причинам).
Поэтому мы решили абстрагироваться от особенностей конкретных реализаций, и сравнить потенциальную концептуальную уязвимость операционных
систем семейств NT и UNIX. Что такое "потенциальная уязвимость"? Это
такое свойство архитекторы системы, которое при определенных
обстоятельствах с той или иной вероятностью может привести к снижению
степени ее защищенности. В частности, сложность считается одной
из потенциальных концептуальных уязвимостей и при прочих равных
условиях менее сложная система объявляется более защищенной и,
соответственно, наоборот. Кончено, помимо сложности (кстати, уровень
сложности измеряется не объемом программного кода, а количеством
взаимосвязей между отдельными компонентами программы), большую роль
играет профессионализм разработчиков, качество тестирования и т. д.
Однако, поскольку все эти факторы практически не поддаются объективному
учету (только не надо пожалуйста говорить, что LINUX тестируют миллионы
людей по всему миру, - знаем-знаем мы как они ее тестируют), лучше их вообще учитывать, чем учитывать неправильно.
Так же, мы будет рассматривать лишь концептуальные уязвимости, -
т. е. такие, которые настолько глубоко зарыты в системе, что без
серьезного хирургического вмешательства в архитектуру ядра их не
удалить. (Да и не получим ли мы после такой операции совершенно другую операционную систему?).
Философские концепции
Open Source vs дизассемблер
По определению, данному Ильей Медведовским атака на компьютерную
систему - это действие, предпринимаемое злоумышленником, которое
заключается в поиске и использовании той или иной уязвимости.
Существует множество разнообразных методик поиска уязвимостей, но ведь
мы договорились не останавливаться на конкретных реализациях, верно?
Вот и давайте разделим все методики на две полярные категории слепого и целенаправленного поиска.
Слепые методики рассматривают защитный механизм как
черный язык с входом и выходом. Методично перебирая всевозможные
входные значения злоумышленник пытается выявить такие из них, которые
бы нарушали нормальную работу защитного механизма или в той или иной
степени ослабляли степень защиты. Эта чрезвычайно простая и
интеллектуально непритязательная стратегия взлома весьма популярна в
кругах начинающих хакеров, начитавшихся дешевой фантастики и свято
уверовавших в свою исключительность. Впрочем, после .дцатой по счету
попытки взлома терпение "хакера" кончается и вся эйфория внезапно
проходит. Конечно, время от времени некоторым особо везучим
счастливчикам все-таки удается проникнуть то в одну, то в другую
защищенную систему, но особой опасности такие атаки не представляют в
силу свой малочисленности.
Действительно, защитный механизм, принцип действия которого
неизвестен, может быть взломан только грубой силой, то есть имеет
вполне предсказуемую степень защищенности. Поэтому, любая мало-мальски
серьезная акция начинается с изучения атакуемого объекта (целенаправленный взлом).
Отсюда: при прочих равных условиях степень защищенности системы обратно
пропорционально легкости анализа ее кода. А легкость самого анализа в
первую очередь определяется доступностью исходных текстов защитного
механизма!
Большинство UNIX'ов поставляются вместе с исходными текстами, в
то время как исходные тексты NT недоступны, а анализ дизассемблерных
листингов не только чрезвычайно трудоемок и утомителен сам по себе, но
еще и требует изрядной профессиональной подготовки, которая есть далеко
не у всех. К тому же подсистема защиты NT много сложнее аналогичной
подсистемы большинства UNIX'ов и весьма поверхностно документирована,
чем и отпугивает многих потенциальных злоумышленников.
Как следствие: количество дыр, обнаруженных в NT за все время
ее существования, можно свободно пересчитать по пальцам одной руки
(причем, большая часть из них была обнаружена практически случайно). В
UNIX же, напротив, дыры обнаруживаются постоянно. С другой стороны..
Каждому хакеру - по системе!
.с другой стороны, степень опасности "дыры" зависит не сколько от ее
"линейных размеров", столько от распространенности операционной
системы, в которой она обнаружена. Огромное количество клонов UNIX
ставит эту систему в весьма выигрышное (с точки зрения безопасности)
положение. К тому же, постоянно переписываемые да и просто
альтернативные ядра даже одну-единственную систему размножают до целого
семейства, благодаря чему, уязвимость, найденная в одной версии ядра,
зачастую недействительна для всех остальных.
В результате, могущество хакера, нашедшего дыру в UNIX,
оказывается много ниже, чем если бы дыра аналогичных размеров была
обнаружена в NT (в силу не многочисленности своих разновидностей,
каждая, отдельно взятая версия NT, установлена на значительно большем
количестве машин, нежели UNIX). Именно поэтому NT все-таки ломают или
во всяком случае пытаются это сделать. Соблазн в самом деле
настолько велик, что хакеров не останавливают ни отсутствие исходных
текстов, ни трудоемкость анализа. К тому же, ядро NT не переписывается
каждый день и практически все дыры, обнаруженные в NT 4.0 остаются
актуальными и в Windows 2000, а то и в Windows XP. (Подробнее об этом
рассказывается в книге Криса Касперски "Техника сетевых атак").
Напротив, если некоторая операционная система установлена на
считанных компьютерах в мире, ломать ее сподобятся разве что мазохисты.
Во всяком случае, хакеру потребуется весьма сильный стимул для изучения
последней. Конечно, если эта операционная система защищает банковский
компьютер, охраняющий миллиард электронных долларов, то за его
сохранность ни один администратор не рискнет поручиться, что и
неудивительно, ведь малораспространенные операционные системы
практически полностью выпадают из внимания специалистов по
информационной безопасности, вследствие чего частенько содержат большое
количество тривиальных и легко обнаруживаемых ошибок, обнаруживаемых
даже при поверхностном анализе.
Тем не менее, установка малораспространенной системы
автоматически отсекает большую армию "хакеров", пользующихся для атак
чужими эксплоитами. А, чтобы вас не атаковал профессионал, необходимо
создать второй уровень защиты - узел с проверенной временем и тщательно
проверенной специалистами операционной системой.
Неплохая идея: на передний план обороны водрузить какой-нибудь
"редкоземельный" клон UNIX, а на второй - NT. Большинство хакеров, как
показывает практика, в основном специализируются на одной операционной
системе, и лишь в исключительных случаях - на двух сразу.
UNIX - это просто!
Сложность отладки и тестирования компьютерных программ стремительно
растет с увеличением их сложности. И, начиная с некоторого уровня,
затраты на тщательное "вылизывание" программы начинают перевешивать
совокупный доход от ее продаж, вынуждая разработчиков ограничиться лишь
поверхностным тестированием (если программа не зависла во время запуска
- это уже хорошо).
Современные операционные системы давным-давно перешагнули через
этот рубеж и никакая из них не застрахована от ошибок. С вероятностью
близкой к единице можно утверждать, что критические ошибки присутствуют
в любой ОС общего назначения, и потому любой узел в сети может быть
гарантированно взломан, это всего лишь вопрос времени и усилий.
Между тем, ошибки крайне неоднородны по своей природе: одни
лежат, что называется на поверхности, и обнаруживаются даже
автоматизированными средствами контроля качества кода; другие же,
напротив, зарыты так глубоко, что найти их можно только случайно.
Фундаментальная проблема отладки заключается в том, что любая, даже
самая незначительная модификация программного кода, чревата появлением
каскада ошибок, возникающих в самых неожиданных местах. И потому,
внесение каких бы то ни было изменений во внутренности операционной
системы и/или сопутствующих ей приложений должно сопровождаться полным
циклом повторного тестирования. Но ведь полное тестирование, как уже
было показало выше, выполнить просто невозможно!
Чрезмерная сложность NT вкупе с огромным количеством изменений,
вносимых в код каждой новой версии, собственно и объясняют скверное
качество ее тестирования. Несмотря на все усилия, предпринимаемые
Microsoft, уязвимость NT заложена уже в самой политике ее развития, а
потому является принципиально неустранимой, т.е. фундаментальной.
Большинство UNIX'ов напротив, довольно компактны и содержат
минимум необходимых для функционирования системы компонентов (или, во
всяком случае, позволяют урезать себя до такого состояния). К тому же
их медленное, эволюционное (а не революционное как у NT) развитие
отнюдь не способствует появлению грубых, легко обнаруживаемых ошибок,
которыми так славится NT.
Удаленный доступ: оружие пролетариата?
Одно из концептуальных отличий философии NT от UNIX заключается в
том, что UNIX не делает практически никаких различий между локальным и
удаленным доступом к машине. В NT же, напротив, лишь некоторые
действия могут быть выполнены удаленно, а для полноценного управления
сервером администратор вынужден прибегать к физическому доступу.
Никто не спорит - удаленно управлять сервером очень удобно, но
давайте задумаемся - насколько это безопасно? Увы, никакое удобство не
проходит даром! Что комфортно администрировать, то комфортно и
атаковать! Этому, кстати, будут способность и продвинутые командные
интерпретаторы, поддерживающие полноценные языки программирования,
разительно отличающие от того уродства, что переваривает примитивная
оболочка NT. Вообще же, в NT удаленным доступом очень мало что можно
сделать (правда, начиная с Windows 2000 в ней все-таки появилось более
или менее совершенные механизмы удаленного управления).
Тем не менее не стоит впадать в крайности и полностью
отказываться от возможности удаленного администрирования. Конечно,
полностью запретив удаленный доступ вы в значительной степени усилите
защищенность своего сервера, но. при этом будете вынуждены постоянно
находится непосредственно рядом с сервером. Спрашиваете: зачем? А кто
хакеров будет гонять?! Ведь проникнуть на атакуемую машину можно через
любой, установленный на ней сервис (скажем, WEB) и потому крайне
нежелательно лишать себя всех средств дистанционного мониторинга и
управления сервером.
Словом, удаленное управление - палка о двух концах,
одновременно и ослабляющая защищенность узла, но и усиливая
оперативность выявления и нейтрализации злоумышленников. С другой
стороны, в ответственных случаях, от удаленного управления все же лучше
совсем отказаться, заменив его прикованным к серверу оператором.
Комплектность штатной поставки
Комплект штатной поставки подавляющего большинства UNIX включает в
себя огромное количество разнообразных программ от игрушек до
компиляторов и интерпретаторов. А чем больше приложений установлено на
машине, тем выше вероятность образования "дыр" в системе безопасности!
К тому же, наличие компиляторов (интерпретаторов) на атакуемой машине
значительно упрощает взлом, поскольку, во-первых, усиливает
переносимость эксплоитов, во-вторых, позволяет автоматизировать атаку,
и, в-третьих, предоставляет доступ к функциям и сервисам недоступным из
командной оболочки.
Операционные системы семейства NT, укомплектованные более чем
скромным набором утилит, в этом отношении выглядят более защищенными.
Впрочем, это непринципиальное различие: грамотный администратор и так
удалит из UNIX все лишнее.
Архитектурные концепции
Механизмы аутентификации
Механизмы аутентификации пользователей (то есть, попросту говоря
алгоритмы проверки правильности пароля) и в UNIX, и в NT построены на
практически идентичных принципах. А именно: эталонный пароль вообще
нигде не хранится, - вместо этого используется его хэш (грубо говоря:
контрольная сумма). Пользователь вводит пароль, операционная система
хэширует его по тому или иному алгоритму и сравнивает полученный
результат с хэш-суммой эталонного пароля, хранящейся в специальной базе
паролей. Если они совпадают, то все ОК и, соответственно, наоборот.
Такая схема (при отсутствии ошибок реализации, конечно) гарантирует,
что даже если злоумышленник и получит доступ к базе паролей, он все
равно не сможет проникнуть в систему иначе, чем методом перебора.
Впрочем, если спуститься с небес идеализированных математических
концепций на грешную землю, можно обнаружить, что "нормальные герои
всегда идут в обход". В частности, в большинстве UNIX'ов вводимый
пароль открытым текстом передается по сети и при наличии хотя бы одного
уязвимого узла в цепочке передачи, может быть перехвачен хакером. В NT
же открытый пароль никогда не передается (ну, разве что администратор
не настроит ее соответствующим образом) и используемая в ней схема
аутентификации устойчива к перехвату трафика.
С другой стороны, NT крайне небрежно относится к охране
парольной базы от посягательств хакеров. На первый взгляд кажется, что
никакой проблемы вообще нет, т. к. доступ к базе имеется лишь у
системы, администраторов и ограниченного количества специально
назначенных администратором пользователей (например, операторов архива,
периодически сохраняющих базу на резервных носителях). А вот в
некоторых, правда, довольно немногочисленных UNIX'ах файл паролей
свободно доступен всем пользователям системы и зачастую даже "виден" по
сети! Ну и что с того? - спросите вы. - Ведь паролей в парольном файле
все равно нет, а "обращение" хеша методом перебора занимает слишком
много времени, пускай хакер перебирает, если ему это занятие так
нравится. Хорошо, тогда такой вопрос: возможно ли в одном единственном
переборе взломать все машины в сети? Не спешите отвечать "нет", ибо
правильный ответ: "да"! Объем жестких дисков сегодня возрос настолько,
что хакер может сохранить хеши всех перебираемых паролей. Неважно
сколько это займет времени: месяц или даже несколько лет, - ведь теперь
у взломщика появится возможность практически мгновенно
восстановить пароль по его хешу - была бы только парольная база в
руках! Мало того, что в NT резервные копии парольной базы по умолчанию
хранятся в общедоступных каталогах, так алгоритм аутентификации не
использует привязки (salt), в результате чего хеши одинаковых паролей в
NT всегда будет совпадать, значительно упрощая тем самым взлом!
Впрочем, от атак данного типа привязка все равно не спасает, разве что
немного продляет "мучения" системы.
Повышение своих привилегий
Модель привилегий пользователей и механизмы контроля прав доступа, -
ключевое и вместе с тем наиболее уязвимое (по статистике) звено
подсистемы безопасности любой многопользовательской ОС. В общем случае
к ней предъявляются следующие требования:
а) модель пользователей должна быть достаточно гибкой, удобной
и интуитивно понятной, в противном же случае ошибки администрирования -
неизбежны;
б) механизмы контроля прав доступа должны не только
гарантировать невозможность не санкционирования повышения уровня своих
привилегий, но и быть максимально устойчивыми к программистским
ошибкам;
в) и сама система, и работающие в ней пользователи должны обходится минимально необходимым уровнем привилегий.
Анализ показывает, что перечисленные выше требования не
выполняются ни в одной ОС массового назначения, а потому все они в той
или иной степени заведомо уязвимы. Между тем, степень защищенности UNIX
и NT различна.
Модель привилегий пользователей, применяемая в большинстве UNIX, является одноуровневой
и допускает существование только двух типов пользователей: обычные
пользователи и суперпользователь (он же root или администратор). В NT
же, напротив, используется иерархическая схема, причем, помимо root'а в
ней имеется еще один суперпользователь, - система. Что это
означает? А то, что в NT, в отличии от UNIX, каждый пользователь
получает минимум необходимых ему прав и никогда не повышает уровень
своих привилегий без особой необходимости. Широко распространенное
заблуждение гласит, что правильное администрирование UNIX позволяет
добиться такого же точно распределения прав доступа, как и в NT, пускай
и ценой большего времени и усилий. На самом же деле это не так. Отсутствие системного пользователя в UNIX приводит к
невозможности выполнения целого ряда действий иначе, чем временным
повышением привилегий запущенной программы до root'a. Взять хотя бы
классическую задачу смены пароля. Пользователи могут (и должны!)
периодически менять свои пароли. Но ведь в UNIX (как впрочем и в NT)
пароли всех пользователей хранятся в одном файле, причем, используемая
модель привилегий не позволяет назначать различным частям файла
различные права доступа. Но ведь должен пользователь как-то изменять
свой пароль, верно? В UNIX эта задача решается так: утилите,
ответственной за смену пароля, присваивается специальный атрибут,
позволяющий ей при необходимости получать права root'а, что она,
собственно, и делает. Если бы этот механизм использовался только при
операциях с паролями большой беды и не было бы. На самом же деле, такой
атрибут необходим очень большому количеству приложений, в частности WEB
и e-mail серверам. Задумайтесь, что произойдет, если в одной из
программ, исполняющихся с наивысшими привилегиями, обнаружится ошибка,
так или иначе приводящая к возможности передачи управления хакерскому
коду? А ведь такие ошибки сыплются из UNIX'ых программ как из рога
изобилия!
Совершенно иная ситуация складывается в среде NT.
Непривилегированные пользователи только в исключительных случаях
вынуждены повышать свои права до уровня администратора, а все остальное
время они пользуются API-функциями операционной системы, выполняющими
потенциально опасные действия "руками" самой ОС. Даже если в одном из
таких приложений будет допущена ошибка и хакер захватит управление, -
он унаследует минимум прав и причинит система минимум вреда.
Таким образом, NT устойчива к программистским ошибкам, а UNIX чрезвычайно чувствительна к ним.
Угроза переполнения буфера
Переполнение буфера - наиболее "популярная" и в то же время наиболее
коварная ошибка, которой не избежало практически ни одно сколь ни будь
сложное приложение. Коротко объясним ее суть: если размера выделенного
программистом буфера вдруг окажется недостаточно для вмещения всех,
копируемых в него данных, то содержимое памяти за концом буфера
окажется разрушено (а точнее - замещено) не вместившимися в буфер
данными. В зависимости от ситуации за концом буфера могут находится:
а) другие буфера и переменные программы;
б) служебные данные - в частности, адрес возврата из функции;
в) исполняемый код;
г) незанятая или д) отсутствующая страница памяти.
Наибольшую опасность представляют пункты б) и в) так как они
чреваты возможностью полного захвата контроля над уязвимой программой.
Пункт д) менее коварен и в худшем случае приводит к возможности
реализации атаки отказа в обслуживании (при обращении к отсутствующей
странице памяти процессор выбрасывает исключение, приводящее к
аварийному завершению уязвимого приложения). Угроза от пункта а) в
значительной степени зависит от рода и назначения переменных,
находящихся за концом переполняющегося буфера и хотя теоретически
уязвимое приложение способно на что угодно на практике угроза
оказывается не столь уж и велика.
Есть еще одно обстоятельство, - для полноценного захвата
управления хакер должен иметь возможность исполнять на удаленной машине
собственный код, обычно передаваемый непосредственно через сам
переполняющийся буфер. В зависимости от расположения уязвимого буфера и
"характера" операционной системы, исполнение переданного хакером кода
может быть как разрешено, так и нет.
Все системы: и UNIX, и NT потенциально допускают существование
пунктов а), б), г) и д), исключая лишь единственный из них - пункт в).
Следовательно, они в равной мере подвержены угрозе переполнения буфера.
Кроме того, и UNIX, и NT имеют исполняемый стек (то есть разрешают
выполнение кода в стеке) и запрещают его выполнение в сегменте данных.
А это значит, что переполнение буферов, содержащихся в автоматических
(т.е. стековых) переменных несет в себе угрозу полного захвата
управления над уязвимой программой. Правда, для некоторых UNIX
существуют заплаты, отнимающие у стека право выполнения, но сфера их
применения весьма ограничена (исполняемый стек необходим множеству
вполне легальных программ, в частности, компиляторов).
Самое забавное, что и UNIX, и NT написаны на Си - языке
программирования, не поддерживающим автоматический контроль границ
массива и потому подверженному ошибкам переполнения. Старожилы говорят,
что в некоторых версиях UNIX ошибка переполнения присутствовала даже на
вводе имени пользователя при регистрации в системе.
Доступ к чужому адресному пространству
С защитой адресных пространств процессор связано огромное количество
слухов, сплетен, легенд, да и простого непонимания самой философии
защиты. Популярные руководства постоянно упускают из виду, что эта
защита в первую очередь предназначается для непредумышленного
доступа, то есть для того, чтобы процесс, пошедший "в разнос", не
утащил бы на тот свет и все остальные процессы, исполняющиеся
параллельно с ним.
Полноценной защиты от предумышленного доступа в чужое адресное пространство ни в UNIX, ни в NT на самом деле нет.
Собственно, UNIX вообще не представляет никаких средств такого
взаимодействия, кроме разве что разделяемых (т. е. совместно
используемых) областей памяти, но это совсем не то. NT же обеспечивает
весьма гибкий контроль доступа адресному пространству процессоров, но
все-таки значительно проигрывает UNIX в отношении безопасности. И вот
почему:
а) в NT доступ в чужое адресное пространство по умолчанию
разрешен всем, даже гостю, и если какой-то процесс (точнее его
владелец) не хочет, чтобы в него проникали, он должен заявить об этом явно;
б) в UNIX для отладки процессов необходимо, чтобы отлаживаемый
процесс не только дал согласие на свою отладку, но и выполнил некоторые
действия, причем, отладка уже запущенных процессов запрещена! NT же
беспрепятственно позволяет отлаживать активные процессы и инициировать
отладку новых, естественно, с наследованием всех привидений
процесса-отладчика (то есть в общем случае, отладка более
привилегированных процессов из менее привилегированных невозможна).
Короче говоря, - NT предоставляет весьма вольготные условия для
существования Stealth-вирусов, клавиатурных и паролей шпионов и всех
прочих тварей, нарушающих покой системы.
Межпроцессорные коммуникации
Процессы должны иметь возможность обмениваться данными, - это
бесспорно, в противном случае такая система не будет никому нужна. С
другой стороны, наличие каких бы то ни было средств межпроцессорного
взаимодействия потенциально позволяет атакующему пагубно воздействовать
на чужой процесс, причиняя его владельцу те или иные неприятности.
Например, напрягать жертву посылкой больших объемов бессмысленных
данных, которые та категорически не хочет принимать. Следовательно,
каждый из взаимодействующих процессов должен иметь возможность:
а) самостоятельно решать с кем ему взаимодействовать, а с кем нет;
б) уметь определять подлинность процессов отправителей и процессов получателей;
в) контролировать целостность передаваемых/принимаемый данных;
г) создавать защищенный канал связи, устойчивый к перехвату трафика.
Многообразие средств межпроцессорного взаимодействия,
поддерживаемых современными операционными системами, чрезвычайно
затрудняет ответ на вопрос: а выполняются ли перечисленные выше
требования на практике? Ограниченные объемом журнальной статьи мы
рассмотрим лишь два наиболее популярных средства межпроцессорного
взаимодействия: каналы, сокеты и сообщения.
Неименованные каналы позволяют связывать лишь родственные
процессы и потому полностью отвечают условию пункта а). Даже если
посторонний процесс каким-либо образом ухитриться получить дескриптор
неименованного канала не родственного ему процесса, то он (дескриптор)
вне контекста своего процесса потеряет всякий смыл и ничего пакостного
с ним злоумышленник не сможет сделать. Если же злоумышленник проникнет
в родственный процесс и попытается, скажем, облить своего соседа
толстой струей информационного мусора, то. ничего не произойдет. Если
процесс-читатель не будет успевать "заглатывать" посылаемые ему данные,
система автоматически приостановит процесс передачи, не давая
атакуемому процессу "захлебнуться". Причем, жертва вольна сама решать -
выносить ли ей такие издевательства дальше или же просто закрыть канал
и послать невоспитанного хакера куда подальше.
Именованные каналы доступны всем процессам в системе, а
в NT и процессам, исполняющимся на остальных узлах сети. Естественно,
для открытия именованного канала необходимо иметь соответствующие
привилегии, но вот для создания нового именованного канала такие
привилегии необязательны, причем под NT не существует легальных
способов определения "авторства" создателя того или иного канала!
Учитывая, что именованные каналы активно используются системой для
передачи зашифрованных паролей и удаленного управления реестром, угроза
внедрения подложных каналов уже не покажется незначительной. Частично
эта проблема решается установкой соответствующего пакета обновления (в
частности для Windows 2000 это Service Pack 2), который предотвращает
создание подложного экземпляра уже существующего именованного
канала, между тем возможность создать подложный канал "с нуля" по
прежнему остается, а механизмов идентификации создателей канала в win32
API как не было, так до сих пор и нет. Локальность именованных каналов
в UNIX оказывается одновременно и сильной, и слабой ее стороной. Тем не
менее, отсутствие удаленного доступа к каналам еще не дает повода
расслабляться, - ведь создать подложный канал может даже гостевой
пользователь, что в ряде случаев позволяет ему успешно атаковать более
привилегированные процессы.
Именованные каналы имеют еще один серьезный недостаток:
обработка каждого нового подключения требует какого-то количества
системных ресурсов, а максимальное количество создаваемых экземпляров
канала обычно не ограничено. Создавая все новые и новые экземпляры
злоумышленник "сожрет" все ресурсы и система рано или поздно "встанет".
Даже если максимальное количество экземпляров было заранее ограничено,
получим те же самые яйца, только в профиль. Захватив все свободные
каналы, злоумышленник нарушит нормальную работу всех остальных
легальных процессов. Система, правда, не рухнет но пользы от этого
будет немного. Решение проблемы состоит в введении квот с клиентской (а
не серверной!) стороны, но во-первых, не совсем ясно как такое
реализовать в сетевой среде, а, во-вторых, клиентскую защиту всегда
легко обойти.
Сокеты, использующиеся в основном в межузловых
межпроцессорных взаимодействиях (хотя в UNIX они широко применяются и
для локального обмена данными), так же катастрофически незащищены перед
попыткой захвата всех свободных ресурсов и огромное количество
постоянно совершающихся flooding-атак - лучшее тому подтверждение.
Кстати, наличие "сырых" (RAW) сокетов в UNIX делает ее платформой номер
один для любой мало-мальски серьезной TCP/IP-атаки. Системы семейства
NT долгое время вообще не позволяли "вручную" формировать сетевые
пакеты и потому атаки типа Land, Teardrop и Bonk осуществить с их
помощью было невозможно (правда, это еще не означает, что NT устойчива
к таким атакам). Не этим ли обстоятельством вызвана патологическая
любовь большинства хакеров к UNIX? Правда, сегодня только ленивый не
найдет NDIS-драйвер к NT, позволяющий работать с TCP/IP пакетами на
низком уровне, так что репутация UNIX как чисто хакерской платформы в
скором будущем обещает пошатнуться.
Наконец, сообщения представляют еще один тип
неавторизированного межпроцессорного взаимодействия. В NT любой процесс
независимо от уровня своих привилегий может послать сообщение окну
другого процесса (в том числе и более привилегированного!), причем нет
никакой возможности установить отправителя сообщения! Вот тебе бабушка
и сказка о безопасности! Находим окно какого-нибудь привилегированного
приложения (а такая возможность у нас есть), получаем дескриптор
интересующего нас элемента управления (кнопки, пункта меню, строки
редактирования) и. эмулируем ввод пользователя!!! Привилегированный
процесс все сделает за нас, так ничего при этом и не заподозрив! Таким
образом, запускать средства администрирования безопасно лишь на
заведомо "стерильной" машине (по сети сообщения не передаются, точнее.
не передаются в штатной конфигурации NT, но ряд утилит удаленного
управления системой позволяет обмениваться сообщениям и по сети).
Нашумевшая дыра, связанная с передачей shell-кода в строку
редактирования привилегированного процесса с последующей установкой
таймера, выполняющего этот код в адресном пространстве и с привилегиями
атакуемого процесса, в настоящее время по заверениям Microsoft уже
устранена. Подробности рецепта "лечения" в момент написания этих строк
еще не известны, но по всей видимости они сводятся к проверке адреса
таймерной процедуры - она не должна находится в буфера какого бы то ни
было окна. Ну, еще быть может, запретили передавать сообщение WM_TIMER
более привилегированным процессам. Полностью же запретить (или
защитить) межпроцессорную рассылку сообщений невозможно, поскольку она
является частью философии оконной подсистемы Windows и любые попытки
внесения каких бы то ни было ограничений не замедлят столкнуться с
проблемами совместимости и приведут к неработоспособности большого
количества прикладных программ. Оконная подсистема UNIX хороша тем, что, не является
неотъемлемой частью системы и при желании от нее можно отказаться,
ограничившись надежным и безопасным текстовым режимом. К тому же, обмен
сообщениями в графических оболочках UNIX обычно осуществляется по
протоколам TCP/IP, которые защищают окна и элементы управления одного
процесса от посягательств всех остальных (если, конечно, сам
процесс-владелец этого не захочет).
Итак: межпроцессорный обмен в и UNIX, и в NT выполнен очень
плохо и потому не безопасен, причем, адекватных средств защиты от
рассмотренных выше атак, ни в близком, ни в отдаленном будущем по
видимому не появится, т. к. "собака зарыта" на уровне базовых концепций
и философии той и другой системы. А философию очередной заплатой не
поменяешь.
Сводная таблица
Так какая же система надежнее? В идеале, конечно, следовало бы
присвоить каждой характеристике свой "вес" и посчитать "очки" обоих
систем. Поскольку, "весомость" понятие субъективное, нам ничего не
стоит настроить измерительную шкалу так, чтобы более надежной оказалась
наша любимая система, причем, такая подтасовка может происходить и
подсознательно, а потому в свободной таблице, приведенной ниже, никакие
весовые категории вообще не используются.
Не стоит так же забывать, что оценка безопасности системы
весьма чувствительна к количеству и роду сравниваемых характеристик.
Исключая одни или добавляя другие мы можем значительно изменить
конечный результат. Так что не стоит считать наше сравнение истинной в
последней инстанции.
характеристика
|
NT
|
UNIX
|
качество и полнота документирования
|
документирована поверхностно
|
документирована весьма обстоятельно
|
доступность исходных текстов
|
исходные тексты недоступны
|
исходные тексты доступны
|
сложность анализа
|
высокая
|
умеренная
|
распространенность
|
существует весьма ограниченное количество представителей NT, причем
наблюдается ярко выраженная преемственность дыр от одних версий системы
к другим
|
существует огромное количество разнообразных клонов, причем ошибки одной версии системы зачастую отсутствуют в остальных
|
сложность кода
|
код излишне сложен
|
код предельно прост
|
поддержка удаленного администрирования
|
частично поддерживает
|
поддерживает
|
комплектность штатной поставки
|
содержит минимум необходимых приложений
|
содержит огромное количество приложений, в том числе и не протестированных
|
механизмы аутентификации
|
устойчив к перехвату паролей
|
передает открытый пароль
|
использование привязки
|
не использует
|
использует
|
выполнение привилегированных операций
|
выполняется операционной системой
|
выполняется самим приложением со временным повышением привилегий
|
модель пользователей
|
иерархическая
|
одноуровневая
|
защита от переполнения буфера
|
отсутствует, причем сама ОС написана на языке провоцирующим такие ошибки
|
отсутствует, причем сама ОС написана на языке провоцирующим такие ошибки
|
возможность доступа в адресное пространство чужого процесса
|
имеется, разрешена по умолчанию
|
отсутствует
|
возможность отладки процессов
|
имеется, разрешена по умолчанию
|
имеется, но связана с рядом ограничений
|
возможность отладки активных процессов
|
имеется, но требует наличия соответствующих привилегий
|
отсутствует
|
удаленный доступ к именованным каналам
|
есть
|
нет
|
создание подложных именованных каналов
|
есть, можно создать и канал, и даже подложный экземпляр уже открытого канала
|
есть, можно создать лишь подложный канал
|
защита именованных каналов от нежелательных подключений
|
отсутствует
|
отсутствует
|
защита сокетов от нежелательных подключений
|
отсутствует
|
отсутствует
|
возможность эмуляции ввода в более привилегированный процесс
|
имеется
|
отсутствует
|
Таблица 1 Сравнение основных характеристик UNIX и NT прямо или
косвенно относящихся к безопасности. Неудачные характеристики залиты
серым цветом |