vista-krnl

археологические раскопки ядра vista/longhorn

крис касперски, ака мыщъх, no-email

ядро висты претерпело множество изменений: усилилась (не)безопасность, добавились новые дыры, оптимизация достигла такого предела, что затормозила даже двуядерные процессоры, но это уже дань техническому прогрессу. давайте, вооружившись шагающим экскаватором, раскорывыряем ядро и посмотрим какие реальные перемены в нем произошли со времен XP и стоит ли этот прогресс того, чтобы за него платить

J» Один мой знакомый думает, что Windows

J» Vista это тема оформления для ХР, просто

J» потому что видел тему с таким названием

J» Он не верит мне, что это ОС.

А> не верю, что это ОС

правильно, это скорее ПЧЕЛ.

из перепалки на rsdn.ru

Ядро надежно скрыто от пользователя множеством слоев абстракции, но именно оно (а вовсе _не_ «прелести» интерфейса) в наибольшей степени ответственно за «характер» операционной системы. Именно ядро управляет памятью, процессорами, вводом/выводом, разграничивает доступ к объектам и делает массу других полезных (и не очень) вещей, эффективность которых определяет надежность, защищенность и производительность всей системы в целом. На плохом фундаменте хорошего сооружения не построишь… Но если качество сооружения легко оценить невооруженным глазом, то дефекты фундамента дают о себе знать в самых неподходящий момент.

Microsoft довольно подробно описывает отличия ядра висты от ее предшественниц в куче презентаций и технических документов, однако, уходит от ответа на вопрос — насколько все это нужно и полезно конкретному пользователю. Как говорится, что хохлу хорошо, то свинье — смерть. Что ж, ничего другого не остается как во всем этом разбираться самостоятельно.

Рисунок 1 взрывая ядро

Ядро висты существенно «оптимизировано» (о чем свидетельствуют многочисленные тесты, предоставленные как самой Microsoft, так и независимыми исследователями), однако, далеко не все изменения полезных для рабочих станций и на однопроцессорных машинах с малым количеством оперативной памяти они вызывают дополнительные тормоза, значительно проигрывая w2k и XP в производительности, что делает ситуацию далеко неоднозначной…

Последовательно рассматривая основные компоненты Windows (менеджер памяти, кучи, менеджер файла подкачки, менеджер ввода/вывода, реестр, загрузчик динамических библиотек) попробуем оценить влияние изменений каждого из них на общую производительность.

менеджер памяти

Перечень изменений, затрагивающих менеджер памяти (memorymanager) можно найти в мультимедийной презентации http://go.microsoft.com/fwlink/?LinkId=67468 и документе download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/kernel-en.doc.

В первую очередь следует отметить (то есть отмести) улучшенную поддержку NUMA-памяти, впервые появившуюся в Server 2003 SP1 и отсутствующую в XP. Напрочь. И вовсе не из жадности (или сложности реализации), а за полной ненадобностью. Аббревиатура NUMA расшифровывается как Non-UniformMemoryArchitecture (Архитектура с Неоднородной Памятью) и охватывает как многопроцессорные машины, так и целые кластеры. Системный планировщик XP ставит все потоки в очередь и гоняет их по кругу, при этом в различные моменты времени каждый поток выполняется то на одном, то на другом процессоре, что снижает производительность за счет накладных расходов на поддержку когерентности (согласованности) всех КЭШей. В Server 2003 SP1 появилось несколько новых API-функций: VirtualAllocExNuma(…, Node), MapViewOfFileExNuma(…, Node) и CreateFileMappingExNuma(…, Node), указывающих системе, что поток предпочтительнее всего запускать на том процессоре, на котором и произошло выделение памяти. Двуядерные и HT-процессоры, разделяющие общий кэш между всеми потоками, к этому абсолютно нечувствительны и выигрыш в производительности будет замечен только на двух _физических_ процессорах, конечно, при условии, что приложение использует новые вызовы API, а такие приложения появятся не скоро… Тоже самое относится и к поддержке расширения AWE, преодолевающему барьер в 4 Гбайта физической памяти на x86 системах. Это чисто серверная штучка и «бытовые» приложения не нуждаются в таких количествах оперативной памяти, во всяком случае пока…

В связи с поддержкой больших объемов памяти, Microsoft реализовала механизм динамического выделения адресного пространства (dynamicsystemaddressspace). Если раньше каталог виртуальных страниц инициализировался на ранних стадиях загрузки оси, резервируя 1,5 Мбайта на x86 системах, 3 Мбайта, на x86 системах с поддержкой PAE (PageAddressExtension) и 2,5 Гбайта на x86-64 и IA64, то сейчас выделение памяти и построение страничного каталога происходят по мере необходимости (on-demand), что слегка ускоряет загрузку, но ощутимо замедляет работу приложений, «пожирающих» память. И, если на серверах, работающих на 64-битных процессорах или процессорах с поддержкой AWE, этот шаг еще хоть как-то оправдан (действительно, глупо инициализировать все адресное пространство, не будучи уверенным — понадобиться ли оно или нет), то рабочие станции однозначно оказываются в явном проигрыше.

Рисунок 2 страничный каталог (PageTable) хранит соответствие между физическими адресами (physicaladdress) и страницами виртуальной памяти (virtualmemory)

Параллельное «обнуление» (zeroing) страниц, появившееся в Server 2003 SP1, так же относится к кластерам и не дает никакого выигрыша даже на многопроцессорных системах, поскольку физическая память — одна. Или… все таки дает?! Как сказать… Физическая память страдает огромной латентностью и если «обнуляемые» страницы окажутся принадлежащими различным DRAM-банкам, мы получим практически двукратный выигрыш производительности, но здесь — все дело случая.

Поддержка новых типов проекций и, в частности, чередующихся виртуальных адресных дескрипторов — RotateVirtualAddressDescriptors (или сокращенно VADs) позволит видео-драйверам полнее использовать возможности шины AGP, быстрее отображая видеопамять на адресное пространство прикладных приложений, с выбором одного из следующих типов проекций: cached, non-cached, write-combinedAGP или video-RAMmappings, что несомненно порадует геймеров, но никак не скажется на судьбе остальных пользователей.

менеджер файла подкачки

Виста существенно пересмотрела алгоритмы работы с файлом подкачки, значительно сократив накладные расходы на его поддержку, но… имея 1 Гбайт памяти на борту, в XP файл подкачки можно вообще отключить, поскольку имеющийся физической памяти достаточно даже для весьма «прожорливых» приложений. Виста — другое дело, очень сильно напоминающее анекдот про жену, обещающую решить проблемы, которые возникнут в связи с ее появлением. Платформа .NET потребляет память в таких количествах, что без подкачки уже никак не обойтись и чтобы разрыв в производительности между виста и XP не был столь драматическим, разработчикам пришлось пойти на многочисленные ухищрения, едва не оторвав себе хвост и не разорвав задницу напополам, но далеко не все «улучшения» дают положительный результат. Оптимизация — дело тонкое…

Начнем с того, что страницы, ранее объединенные в связанный список (linkedlist), теперь повешены на сбалансированные AVL-деревья, дающие выигрыш только при размерах файла подкачки в несколько десятков гигабайт. А на хрена нам столько памяти?! Ну да, серверам очень даже и не на хрена, для них это вполне нормально, но мы-то говорим в первую очередь о рабочих станциях! (Сервер можно и на базе Open BSD слепить у нее и с безопасностью и с производительностью всяко получше будет, чем у виста/server longhorn).

А вот сокращение фрагментации файла подкачки (как внешней — на диске, так и внутренней — соседние виртуальные страницы выгружаются рядом) можно только приветствовать, однако… сразу же возникает вопрос — почему же этого не сделали ранее? Да потому, что уменьшение внутренней фрагментации снижает эффективность использования дискового пространства и оправдывает себя только на подкачках очень большого размера. Все очень просто! Выгружая страницу на диск, система вынуждена зарезервировать в файле подкачке место для ее «соседей», которые, возможно, никогда не будут выгружены! Впрочем, при современных объемах жестких дисков это становится уже не столь критично, производительность — важнее.

Радует и тот факт, что система наконец-то перестала выгружать модифицированные страницы, содержимое которых более не используется. Например, при выделении нового блока памяти он автоматически забивается нулями (в противном случае, один процесс мог бы без труда похитить данные всех остальных), но выгружать такую страницу памяти на диск ненужно, поскольку в любой момент времени забивку нулями можно выполнить повторно! Однако, исследование виртуальной памяти и файла подкачки показывает, что «лишние» вытеснения страниц происходят сравнительно редко и выигрыш в производительности на общем фоне практически неощутим, тем не менее «десяток старушек — уже рубль» (с) Раскольников.

На волне общемировой тенденции глобализации усилилась интеграция менеджера файла подкачка с дисковым кэшем, чего общественность уже давно ждала. Теперь сброс страниц на диск и сброс дисковых буферов происходят согласовано, что увеличивает производительность при интенсивном вводе/выводе, который опять-таки характерен в основном для серверов, а рабочие станции дрыгают диском только по «торжественным» случаем.

менеджеркучи

Динамическая память, так же называемая кучей (без которой немыслимо существование приплюснутого си и платформы .NET) облагает программиста ощутимыми накладными расходами, особенно заметными на маленьких блоках, однако, оптимизация менажера кучи _не_ способна ощутимо повлиять на производительность, поскольку выделение маленьких блоков берет на себя библиотека времени исполнения (RTL) конкретного компилятора, обращающаяся к операционной системе только с «оптовыми» заказами.

Если отбросить улучшения, касающееся многопроцессорных систем, виста отличается от XP только уменьшенной фрагментацией кучи (thelow-fragmentationheap — LFH), эвристическими алгоритмами, автоматически подстраивающимися под характер запрос на выделение памяти и отложенной (lazy) инициализацией.

Насчет фрагментации — это откровенное вранье. Фрагментация кучи приводит отнюдь не к падению производительности, а к невозможности выделения непрерывного блока требуемых размеров, хотя по «кускам» свободной памяти может быть в сотни раз больше. Приложение просто отказывает в работе, показывая какой лось его создатель. С нормальными программами такого не случается. У них другая проблема — утечки памяти. Ошибки проектирования приводят к тому, что выделенная однажды память не освобождается, образуя мощные «осадочные» пласты, наслаивающиеся друг на друга вплоть до полного исчерпания всей свободной памяти, завершающегося падением приложения. Справиться с утечками операционная система к сожалению не в силах, поскольку не существует никаких признаков, позволяющих отличить полезный блок от блока который забыли освободить. Что же касается адаптивных алгоритмов, то всегда существует угроза, что они сработают с точностью до наоборот, и вместо обещанного выигрыша (составляющего от силы десятки процентов) мы получим грандиозное падение производительности.

Тоже самое относится и к переписанному lookup-алгоритму (на котором базируются функции выделения и освобождения памяти), теперь его эффективность составляет не O(n), а O(1), то есть время поиска представляет собой константу, не зависящую ни от каких внешних факторов (например, количества выделенных блоков). Как это влияет на производительность? А вот как! У нас есть два ящика. Один черный, другой прозрачный и в нем лежит $100. Какой из ящиков содержит больше денег? Вот-вот, так же и здесь! O(n) – это линейная зависимость, представляющая собой наклонную кривую, O(1) — это прямая, параллельная оси OX. В точке пересечения двух прямых (которая из условий задачи нам _не_ известна) эффективность обоих алгоритмов совпадает, после чего алгоритм O(1) начинает давать все больший и больший выигрыш, чем O(n), однако, по левую сторону от точки пересечения все не так и там выгоднее O(n). Но это в теории. На практике, опять-таки, наибольшее влияние на производительность оказывает именно RTL, то есть библиотека времени исполнения, поставляемая вместе с компилятором…

Рисунок 3 куча — как она есть в висте

менеджер ввода/вывода

Большим шагом вперед стало появление приоритизированного ввода/вывода, при котором поток ввода/вывода с более высоким приоритетом вытесняет поток с более низким приоритетом, что, например, позволяет копировать большое количество файлов в фоновом режиме без потери производительности и запуске того же Word'а теперь система не будет так дико тормозить. Но… так ли часто приходится рабочим станциям сталкиваться с подобной ситуацией?! На серверах — да, там это _очень_ полезно, даже если это «домашний» ftp, который теперь можно перевести в фоновой режим, чтобы при большом наплыве пользователей, система не «проседала» под нагрузкой, открывая файлы со скоростью черепахи.

Изменилась и политика сброса дисковых буферов. Файлы, отображаемые в память (memorymappedfile) раньше сбрасывались на диск маленькими кусочками, не превышающими 64 Кбайт, теперь же эта цифра увеличена аж до 4 Гбайт. Какой выигрыш это дало? Учитывая, что подавляющее большинство приложений работает с файлами напрямую, без проецирования их в память — ровным счетом никакого. Правда, слегка ускоряется работа с файлом подкачки (поскольку, он — проецируемый), да и то лишь на быстрых дисках, предпочтительно SCSI, и при интенсивном дисковом вводе/выводе.

Рассмотрим ситуацию: у нас имеется файл, спроецированный в память, и приложение, дрыгающее жестким диском. Если сброс будет происходить кусочками по 64 Кбайта, то головка жесткого диска будет непрерывно метаться между сбрасывающимися буферами и запросами приложения. Увеличение размера сбрасываемых буферов позволяет записать их за один проход и только потом дрыгнуть головкой в направлении приложения. Суммарная производительность возрастет, но… и время простоя запросов в очереди тоже. Рассуждая по аналогии — одновременное выполнение нескольких программ в многозадачной среде занимает намного больше времени, чем если бы эти программы выполнялись по очереди. Так не пора ли вернуться к пакетному режиму?! Тесты покажут колоссальный выигрыш!!! Но то тесты (они на то и придуманы, чтобы дурачить людей) и совсем другое дело — реальная жизнь. Если мы сначала будет слушать winamp и только потом запустим word, то производительность труда навряд ли возрастет.

То, что с производительностью нам ничего не светит, все пользователи знали еще заранее и постепенно (читай: по мере знакомства с новыми бетами) с этим как-то смирились. Да Microsoft, в общем-то, на производительность не сильно и напирает, делая ставку на защищенность висты от хакерских атак. Количество заплаток для XP превысило всякие пределы терпения, а вирусные эпидемии последних лет все еще свежи в памяти. Кому-то очень выгодно держать людей в постоянном страхе перед атакой, заставляя их покупать дорогостоящие (но не слишком-то надежные) защитные продукты. И хотя бытует мнение, что Microsoft серьезно подмочила себе репутацию, на самом деле, такая ситуация ей только на руку. Лучшей мотивации чем безопасность для перехода на новую систему и не придумать!

Проблема в том, что «безопасность» не является той потребительской характеристикой, которую можно пощупать руками или проверить на зуб. Даже высококвалифицированные эксперты, свободно владеющие дизассемблером (или имеющие доступ к исходным текстам) могут лишь приблизительно _оценить_ насколько (не)безопасна система. Но если безопасность говорит шепотом, то небезопасность орет во весь голос, что, с вистой на данный момент и происходит.

Рисунок 4 Windows под хакерским прицелом

атаки на переполняющиеся буфера

Microsoft продолжила наступление на переполняющееся буфера, начатое еще в w2k, вводя в действие все новые и новые защитные механизмы, существенно (якобы) затрудняющие реализацию удаленных атак. «Новые», естественно, только для Windows. В остальных операционных системах они были реализованы задолго до появления висты и в гораздо более полным объеме.

С большим опозданием в висте появилась поддержка рандомизации адресного пространства AddressSpaceLayoutRandomization — ASLR. По умолчанию все системные библиотеки теперь загружаются по одному из 256 возможных адресов, а в заголовке исполняемых файлов появился специальный бит, указывающий должен ли он загружаться по случайному адресу или нет.

Подробности о реализации ASLR от Microsoft можно почерпнуть из blog'а Michael'я Howard'а: http://blogs.msdn.com/michael_howard/archive/2006/05/26/608315.aspx. Там даже приводится конкретный пример расположения системных библиотек его ноутбука до и после перезагрузки:

wsock32.dll (0x73ad0000)

winhttp.dll (0x74020000)

user32.dll (0x779b0000)

kernel32.dll (0x77c10000)

gdi32.dll (0x77a50000)

Листинг 1 базовые адреса некоторых системных библиотек в висте

wsock32.dll (0x73200000)

winhttp.dll (0x73760000)

user32.dll (0x770f0000)

kernel32.dll (0x77350000)

gdi32.dll (0x77190000)

Листинг 2 базовые адреса тех же самых библиотек после перезагрузки системы

Насколько этот трюк усложняет атаку? И каким боком системные библиотеки относятся к переполняющимся буферам? Все просто — первым действием атакующего обычно становится подмена адреса возврата из функции на адрес машинной команды jmp esp (FFh E4h), находящейся в доступной оперативной памяти. На машинах с задействованным аппаратным DEP'ом (блокирующим исполнение кода в стеке) приходится предварительно вызывать API-функции, присваивающие данному региону статус исполняемого или выделяющие блок памяти с нужными атрибутами и копирующие туда shell-код. Такие атаки получили называние return-to-libc, поскольку впервые были реализованы на UNIX-системах, где основным «поставщиком» API-функций становится библиотека libc.lib, ну а в Windows хакеры используют прямой вызов KERNEL32.DLL, которая теперь загружается по случайному адресу и атакующий имеет 1/256 шанс на удачу, в противном случае, произойдет исключение и работа уязвимого приложения будет завершена в аварийном режиме, что не есть хорошо.

Да… не слишком-то надежная защита. К тому же 1/256 — это _гигантская_ цифра. Если в сети находится 1.000 уязвимых машин, то в первой же итерации атаки заражаются ~4 из них. Фактически, «тасовка» системных библиотек лишь увеличивает количество попыток, которые необходимо предпринять атакующему, но не препятствует самой атаке в принципе. К тому же, если уязвимый исполняемый файл (или принадлежащие ему динамические библиотеки) не используют флаг рандомизации, то вместо прямых вызов KERNEL32.DLL атакующий может использовать таблицу импорта или RTL файла-жертвы. Теоретически, взвести бит рандомизации можно и в hiew'е, но практически все старое программное обеспечение останется уязвимым и продолжит им оставаться до тех пор, пока не появятся линкеры, поддерживающие данную фичу и разработчики не пересоберут ими свои проекты, что случится не скоро, к тому же, загрузка исполняемого файла по случайному адресу требует наличия fixup'ов (так же называемых перемещаемыми элементами), что увеличивает размер exe-файла и замедляет его загрузку. Беглый опрос нескольких знакомых разработчиков показал, что никто из них не собирается задействовать рандомизацию ни сейчас, ни даже когда она будет поддерживается VC и другими компиляторами.

К тому же, рандомизация не затрагивает стек, и лишь частично воздействует на кучу, оставляя атакующему достаточно предсказуемой информации для успешной реализации атаки, неизбежность которой очевидна всем, кроме парней из Microsoft. В частности, пакет PaX, созданный для UNIX и успешно перенесенный на NT (где он известен под именем Wehnus, см. — http://www.wehnus.com) рандомизует все, что только можно рандомизовать, успешно работая от w2k до Server 2003 с минимальными издержками производительности. Подробнее о «настоящей» рандомизации можно прочитать на en.wikipedia.org/wiki/Address_Space_Layout_Randomization.

Другим, не менее «выдающимся» шагом вперед стало помещение списка обработчиков структурных исключений (SEH) в специальную секцию PE-файла (.pdata), доступную только на чтение. До этого список обработчиков располагался в стеке и был свободно доступен для модификации. На самом деле, это (достаточно широко разрекламированное решение) не имеет никакого отношения к операционной системе и обуславливается исключительно одной лишь политикой компилятора. _Никто_ не запрещает вытворять подобные трюки даже на 9x, не говоря уже про w2k или XP. Вот только подходящих компиляторов пока что нет. Ах да, маленькая деталь. Даже если приложение не устанавливает никаких своих обработчиков, то за обработку исключений отвечает обработчик, назначаемый операционной системой, и вплоть до Server 2003 SP1 размещающийся в стеке. Теперь же, с приходом висты к власти, его там нет.

Препятствует ли это удаленным атакам? Хм. Навряд ли. Обработчики структурных исключений очень широко распространены в приплюснутом си, где они устанавливаются компилятором неявно, не говоря уже о специальных средствах вроде секций try/except. До тех пор, пока разработчики не перекомпилируют все свои приложения новыми версиями компиляторов (поддерживающих эту фишку), в стеке по прежнему будет болтаться куча SEH'ов, спасающих хакеров от голодной смерти. Но даже после перекомпиляции, в секцию .pdata попадут лишь статические обработчики (адрес которых известен еще не стадии трансляции), а с учетом активного внедрения парадигм метапрограммирования, таковых окажется не так уж и много. Конечно, если засунуть указатели на динамически назначаемые обработчики в секцию .data (или локальную память потока), это существенно усложнит хакерам жизнь, но… опять-таки все упирается в вопрос: «когда появятся соответствующие компиляторы».

Аналогичным образом обстоят дела и с защитой кучи. Шифрование блока метаданных по XOR со случайно сгенерированным ключом, проверка целостности заголовков блоков, pseudo-рандомизация кучи (деликатно именуемая randomheaprebasing) — все это, конечно, позволяет обнаружить разрушение кучи перевод выполнением функции VirtualFree, действующей в таких условиях как оператор Бейсика POKE, т. е. записывающей ячейку памяти размером в двойное слово (на 64-битных редакция — четвертное) по произвольному адресу, но… весь фокус в том, что прямые вызовы API-функций, работающих с кучей, используются довольно редко и приложения предпочитают полагаться на RTL компилятора, реализующую свою собственную кучу, остающуюся незащищенной.

Комментарии, как говорится, излишне. Microsoft утверждает, что предпринятые меры убивает не только ранее написанные exploit'ы, но и препятствуют появлению новых. Однако, на самом деле, даже старые exploit'ы в большинстве своем остаются в строю. Некоторые лоси уже опубликовали внушительный список exploit'ов, неработающих на висте. Ну и что с того? На w2k/XP со всеми установленными заплатками они (не)работают с тем же успехом. Если exploit проникал через дыру в Горящем Лисе или любом другом приложении, пользователь которого не удосужился скачать последнюю версию, то с большой степенью вероятности, exploit продолжит поражать Лиса и на висте.

понижение привилегий служб и фоновых процессоров

Наконец-то до Microsoft дошел тот факт, что запускать службы с привилегиями system это сплошной бэд, особенно если эти службы написаны кое-как и порождают многочисленные зависимости, которые нельзя отключить без ущерба для функциональности системы. Штатные службы висты работают на минимально возможном уровне привилегий. Естественно, «минимально возможном» в представлении парней из Рэймонда. При желании этот уровень можно было бы существенно понизить, разбив службы на несколько частей, каждая из которых работает на том уровне привилегий, который ей реально необходим. Это сокращает долю привилегированного кода, упрощая его проверку и сокращая количество возможных дыр.

Собственно говоря, _технически_ все это можно было сделать и на w2k. Тем более, что службы, разработанные сторонними поставщиками, по-прежнему работают на том уровне привилегий, под который они были спроектированы (и, как правило, этим уровнем является system). В отдаленном будущем разработчики _возможно_ последуют рекомендациям Microsoft и перепроектируют свои службы так, чтобы они смогли работать на пониженном уровне, но… даже на пониженном уроне службам доступны все файлы, доступные простому пользователю. То есть, установить backdoor и перехватить конфиденциальную информацию хакер все-таки сможет. Да, на NTFS-разделах пользователь в силах запретить непривилегированным службам видеть свои секретные файлы, но только кто из пользователей это будет делать?! Тем более, что если бы пользователи делали это, то никакие антивирусы им были бы не нужны.

Загрузить rootkit'а на пониженном уровне привилегий уже труднее (точнее, легальными средствами — вообще невозможно), однако, учитывая что большинство сидит под администратором (факт, против которого не попрешь), хакеры продолжат атаковать прикладные приложения, содержащих намного больше ошибок, чем службы. А с открытием большого класса атак на драйвера через ошибки синхронизации, дающих хакеру ядерные привилегии, актуальность атак на службы значительно снижается.

изоляция нулевой сессии

Нет, ну это уже хвост знает что! Гордится закрытием дыры четырехлетней (!) давности может только отдел маркетинга Microsoft. Остальные бы по крайней мере сдали это втихую, чтобы не позориться…

История началась в августе 2002 с публикации Криса Пэджета (ChrisPaget) «ExploitingdesignflawsintheWin32 APIforprivilegeescalation» (использование дефектов проектирования Win32 API для повышения привилегий), описывающей элегантный трюк: находим окно более привилегированного приложения со строкой редактирования и засылаем туда shell-код путем посылки сообщения WM_SETTEXT, управление на который передается через таймер, работающий в контексте уязвимого приложения и устанавливаемый отправкой еще одного сообщения — WM_TIMER. Атаки подобного типа получили название «shatterattacks» и чрезвычайно взволновали общественность, просочившись даже в некомпьютерную прессу.

Собственно говоря, оконная подсистема Windows является одной большой дырой, простительной для Windows 3.x и 9x, где понятие привилегий отсутствует как класс, и «натянутой» на NT без учета системы разграничения доступа. Ни для кого не секрет, что сообщения позволяют манипулировать элементами управления более привилегированных приложений, в частности, отключать брандмауэры и антивирусы, запускать от их имени другие программы и т. д. Тем не менее, Microsoft категорически отказалась признавать это «дефектом проектирования» и выпустила заплатки для NT, w2k и XP лишь в декабре, под напором возмущенных пользователей.

Изучение заплаток показало, что никакие это не заплатки, а… так, слабая подобие левой руки, в смысле лишь имитация защиты. Возможность отправки сообщения окнам более привилегированных процессов как была, так и осталась. И вот в висте… нет, до решения проблемы дело так и не дошло, но кое-какие подвижки уже сделаны. Правда, не в том направлении, но это ничего… Microsoft предприняла для «революционных» шага, касающиеся системных сервисов (но никак не затрагивающие все остальные приложения).

Если раньше локальный пользователь, первым входящий в систему, регистрировался в нулевой сессии, откуда запускались все службы, то теперь нулевая сессия целиком отдана под службы и ее очередь сообщений изолирована от очереди сообщений всех остальных сессий, в которых регистрируются пользователи. В результате, мы имеем на одну сессию больше, чем раньше. Для серверов это, может быть, и не страшно, а вот на рабочих станциях, 99% своего времени проводящих в «объятиях» одного-единственного пользователя (изредка запускающего утилиту runas) мы получаем неоправданное транжирство системных ресурсов.

Рисунок 5 в w2k и XP службы работают в той же самой сессии, что и приложения первого вошедшего в систему пользователя

Второй шаг является следствием того, что первый шаг получился не так, как хотелось и пришлось в спешном порядке анонсировать изоляцию пользовательских интерфейсов от принадлежащих им процессов — «UserInterfaceProcessIsolation» (или, сокращенно, UIPI). Если бы хакеры были действительно лишены возможности по-прежнему посылать сообщения окнам более привилегированных приложений — этого бы в принципе не потребовалось. А так Microsoft «отодрала» интерфейс от привилегированных служб, запустив его в непривилегированном режиме.

Рисунок 6 в висте службы работают в отдельной сессии, изолированной от пользовательских приложений

Надо признать, что и второй шаг у Microsoft не очень хорошо получился. Какая радость — shatter-атаки перестали работать!!! То есть _как_ _бы_ перестали, а на самом деле они очень даже! Да, повысить свои привилегии через засылку shell-кода хакеры уже не смогут, но вот взаимодействовать со службой через предоставленный ею интерфейс им _ничего_ не мешает!!! А большего хакерам обычно и не нужно. Тем более, что речь идет о локальных атаках, актуальность которых в приличном обществе нормальные люди не обсуждают, поскольку, существует тысяча и один способ повышения своих привилегий, если, конечно, их есть куда повышать (про то, что большинство пользователей сидит под администратором мы уже говорили).

Подводя итог, можно сказать — безопасность ядра висты никаких радикальных изменений не претерпела (а с учетом переписанного с нуля сетевого стека она даже пострадала, но об этом — в отдельной статье!) и виста по-прежнему остается открытой для атак. you'realwayswelcome, — как говорят англичане. Переходить на висту можно только ради красивого интерфейса, нового DirectX и прочего потребительского барахла, идущего в разрез с безопасностью. Как ни парадоксально, но Windows 98 на сегодняшний день остается самой защищенной операционной системой, подвластной лишь небольшому числу DoS атак, да и то лишь в том случае, если не установлены соответствующие заплатки.

В мире существует три типа людей: умные, дураки и все кто между ними. Дураки, ставят xBSD/Linux потому, что любят халяву и только потом, когда им объясняют про «совокупную стоимость владения», они переезжают на NT, переходя в категорию тех, кто «между». (Типа, прикиньте пацаны какую зарплату придется платить администратору, разбирающимся в xBSD/Linux'е и сравните ее с ценой на MicrosoftServer, с которым управится даже уборщица Маня). Э… помнится, «голубые» обижаются когда их так называют, предпочитая формулировку «сексуальное меньшинство». А что, если по аналогии с этим ввести в употребление термин «интеллектуальное большинство»?

Допустим, у нас есть сервер и есть свой бизнес. Допустим, час простоя сервера обходится в $100, а убытки от потери/кражи информации составляют $100.000. Теперь подсчитаем частоту падений NT и помножим ее на вероятность атаки. По данным различных агентств, ежегодно в мире компании теряют _миллиарды_ долларов и у подавляющего большинства из них установлена та или иная версия NT.

Умные люди используют xBSD/Linux не потому, что он бесплатный, а потому что существует такое понятие, как «учет рисков». Экономя на зарплате администратора, компания идет на огромный и ничем неоправданный риск, зачастую наступая на одни и те же грабли несколько раз!