Межпроцессорные коммуникации
Процессы должны иметь возможность обмениваться данными, - это бесспорно, в противном случае такая система не будет никому нужна. С другой стороны, наличие каких бы то ни было средств межпроцессорного взаимодействия потенциально позволяет атакующему пагубно воздействовать на чужой процесс, причиняя его владельцу те или иные неприятности. Например, напрягать жертву посылкой больших объемов бессмысленных данных, которые та категорически не хочет принимать. Следовательно, каждый из взаимодействующих процессов должен иметь возможность:
а) самостоятельно решать с кем ему взаимодействовать, а с кем нет;
б) уметь определять подлинность процессов отправителей и процессов получателей;
в) контролировать целостность передаваемых/принимаемый данных;
г) создавать защищенный канал связи, устойчивый к перехвату трафика.
Многообразие средств межпроцессорного взаимодействия, поддерживаемых современными операционными системами, чрезвычайно затрудняет ответ на вопрос: а выполняются ли перечисленные выше требования на практике? Ограниченные объемом журнальной статьи мы рассмотрим лишь два наиболее популярных средства межпроцессорного взаимодействия: каналы,сокеты и сообщения.
Неименованные каналы позволяют связывать лишь родственные процессы и потому полностью отвечают условию пункта а). Даже если посторонний процесс каким-либо образом ухитриться получить дескриптор неименованного канала не родственного ему процесса, то он (дескриптор) вне контекста своего процесса потеряет всякий смыл и ничего пакостного с ним злоумышленник не сможет сделать. Если же злоумышленник проникнет в родственный процесс и попытается, скажем, облить своего соседа толстой струей информационного мусора, то. ничего не произойдет. Если процесс-читатель не будет успевать "заглатывать" посылаемые ему данные, система автоматически приостановит процесс передачи, не давая атакуемому процессу "захлебнуться". Причем, жертва вольна сама решать - выносить ли ей такие издевательства дальше или же просто закрыть канал и послать невоспитанного хакера куда подальше.
Именованные каналы доступны всем процессам в системе, а в 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 выполнен очень плохо и потому не безопасен, причем, адекватных средств защиты от рассмотренных выше атак, ни в близком, ни в отдаленном будущем по видимому не появится, т. к. "собака зарыта" на уровне базовых концепций и философии той и другой системы. А философию очередной заплатой не поменяешь.
Содержание раздела