Многие операционные системы имеют встроенные средства безопасности. В этом есть здравый смысл – часто лучше всего поместить средства безопасности на нижних уровнях системы: на аппаратном или уровне операционной системы. Тому есть несколько причин.
Во-первых, часто существует возможность обойти средства безопасности на некотором уровне посредством атаки, проведенной уровнем ниже. Например, встроенные функции кодирования в текстовом редакторе не зависят от того, может ли злоумышленник взломать операционную систему, под управлением которой он работает. Таким образом, более надежной является защита на самом низком уровне программного обеспечения.
Во-вторых, так проще. В ядро системы обычно легче ввести дополнительные меры безопасности. Упрощается осуществление и анализ таких мер. И, как следовало ожидать, в результате получается более защищенная система.
В-третьих, часто так получается быстрее. Все средства работают лучше, если они встроены в операционную систему, и средства безопасности не исключение. Криптография, например, может съедать много времени, и имеет смысл сделать ее работу как можно более эффективной.
Поэтому безопасность операционных систем остается предметом исследований уже в течение десятилетий. Раз так, для нее разработан свой собственный набор понятий.
• Монитор обращений. Часть программных средств, которая осуществляет доступ субъектов к объектам. Когда некий процесс делает вызов операционной системы, монитор обращений останавливает процесс и выясняет, следует ли разрешить или запретить вызов. Например, он не позволит пользователю с конфиденциальной регистрационной учетной записью читать секретные документы или создавать несекретные документы.
• Надежная вычислительная база. Это все защитные устройства внутри компьютера – оборудование, программно-аппаратные средства, операционная система, программные приложения и т. д. – все, что используется для осуществления политики безопасности. Некий администратор указывает компьютеру, что, от кого и каким образом следует защищать (это и есть политика безопасности), а надежная вычислительная база обеспечивает выполнение этой задачи.
• Ядро безопасности. Это оборудование, программно-аппаратные средства, операционная система, программные приложения и все остальные элементы надежной вычислительной базы, которые реализуют концепцию монитора обращений.
Монитор обращений – это абстрактное устройство защиты; оно занимается такими вещами, как управление файлами и управление памятью. Ядро безопасности обеспечивает действие монитора обращений. Надежная вычислительная база содержит все средства защиты, в том числе и ядро безопасности. А все в целом реализует некую модель безопасности – Белла-Лападулы или какую-то другую – и осуществляет защиту наиболее простыми и эффективными средствами. И конечно, надежная вычислительная база по определению надежна – пользователи не должны иметь возможность изменить ее, иначе безопасность может быть утрачена.
Эту концепцию трудно осуществить в реальной операционной системе. Компьютер – сложный зверь, и все в нем должно быть надежным. Любая мелочь способна испортить все дело. Если кто угодно имеет доступ к жесткому диску с правом на чтение и запись, то как можно помешать одному пользователю читать то, что пишет другой? Что, если один пользователь хочет, чтобы второй прочитал, что он написал? Возможно ли, чтобы пользователь, используя прерывания, делал что-то, чего он делать не должен? Как защитить доступ к принтеру? Может ли один человек узнать секреты другого через клавиатуру? Что, если базовые средства надежной вычислительной базы выйдут из строя? Как вам удастся выполнить дефрагментацию диска, если у вас есть доступ только к своим файлам?
Исторический пример почти правильной реализации этой теории – это операционная система под названием Multics, которую в конце 1960-х разработали MIT, Bell Labs и Honeywell. В Multics модель Белла-Лападулы построена с нуля. (Фактически, именно проект Multics дал толчок развитию модели Белла-Лападулы.) Разработчики применяли формальную математическую систему этой модели, чтобы продемонстрировать безопасность своей системы, а затем обозначили понятия модели в своей операционной системе. Ни одного кода не было написано до того, как спецификации были одобрены. Multics работала, хотя средства безопасности в ней были слишком громоздкими. К настоящему времени почти все уже забыли о Multics и уроках, вынесенных из этого проекта.
Один из уроков, о которых люди позабыли, – в том, что ядро должно быть простым. (Даже ядро Multics, которое содержало только 56 000 кодовых строк, как выяснилось, слишком сложно.) Ядро – это по определению высоконадежные программы. В главе 13 будет рассказано о надежности программ, мораль же в том, что неразумно ждать, что в программах не будет сбоев защиты. Поэтому чем проще программа, тем меньше в ней будет ошибок безопасности.
К сожалению, современные операционные системы страдают болезнью, известной как «распухание ядра». Это означает, что большой объем кода располагают внутри ядра, а не снаружи. Когда система UNIX была написана впервые, считалось обязательным помещение несущественных кодов за пределами ядра. С тех пор все забыли этот урок. Все имеющиеся сейчас разновидности UNIX в той или иной степени страдают распуханием ядра: у них либо слишком много команд в ядре, либо имеются непонятные утилиты, запускающиеся в случае корневого доступа, либо что-то еще.
Windows NT устроена намного хуже. Эта операционная система может служить примером того, как полностью игнорируются исторические уроки безопасности. То, что находится в ядре, по определению защищено, поэтому с точки зрения разумного проектирования необходимо уменьшить размер ядра, насколько возможно, и убедиться, что оно полностью защищено. Windows, похоже, придерживается мнения, что, поскольку то, что содержится в ядре, защищено по определению, следует просто побольше всего разместить прямо в ядре. Если разработчикам было непонятно, как обеспечить безопасность чего-либо, они просто запихивали это в ядро и считали его уже защищенным. Очевидно, это не помогает при длительной работе.
В системе Windows драйверы принтеров являются частью ядра. Пользователи регулярно загружают эти драйверы или устанавливают их, наверное, не осознавая, что норовистый (или неисправный) драйвер принтера может полностью уничтожить защиту их системы. Было бы намного разумнее разместить драйверы принтеров снаружи ядра, тогда они не должны были бы быть надежными, но это вызвало бы у разработчиков больше трудностей. А философия Windows NT в том, чтобы всегда отдавать предпочтение простому над безопасным – и в обращении, и в разработке.
Windows 2000 еще хуже.
Тайные каналы – это головная боль разработчиков моделей защиты. Помните, что одно из двух основных правил безопасности в том, что пользователь или процесс не может записывать данные на более низком уровне доступа? Тайные каналы – это способ обойти этот контроль.
Тайные каналы – это способ для субъекта с доступом более высокого уровня послать сообщение на более низкий уровень защиты – обычно посредством какихто ресурсов совместного использования. Например, злоумышленная программа, уровень доступа которой «Совершенно секретно», могла бы послать, манипулируя сетевой пакетной передачей (два пакета подряд означают единицу, а два пакета с промежутком между ними – нуль), сообщение, в котором сообщались бы коэффициент загрузки ЦПУ, распределение памяти, доступ к жесткому диску, установка очередности печати и т. п. Тайным каналом могут быть и пробелы в документе, и «случайное» заполнение в конце записи базы данных. Не быстро, но вполне осуществимо отправить сообщения процессов высокого уровня доступа процессам более низкого уровня, разрушая модель безопасности.
Создавать тайные каналы просто и забавно. Опасность представляют не те пользователи, которые копируют с экрана данные с грифом «Совершенно секретно» и переправляют их в Китай, а те, кто пишет программы, которые могут тайно собирать данные, оставаясь в тени.