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

 

 

Три основные проблемы

Почему же так трудно контролировать работу программного обеспечения? Три основных фактора превращают управление рисками при использовании программ в основную задачу современности. Этими факторами являются сложность, расширяе­мость и возможность взаимодействия.
СЛОЖНОСТЬ
Современное программное обеспечение довольно сложное, и есть все предпо­сылки считать, что оно станет еще сложнее в ближайшем будущем. Например, в 1983 году программа Microsoft Word состояла только из 27000 строк кода, но, со­гласно данным Натана Мирвольда (Nathan Myhrvold)6, к 1995 году эта программа увеличилась уже до 2 млн. строк кода! Программисты потратили годы на то, чтобы придумать единицы измерения для программного обеспечения. Целые книги по­священы существующим системам измерения размера программ. Но только одна единица измерения позволяет установить соотношение с числом ошибок — количе­ство строк кода (LOC). И действительно, в некоторых кругах специалистов по про­граммированию число строк кода стало единственным приемлемым средством из­мерения объема программ.
Количество ошибок на тысячу строк кода (KLOC) изменяется для каждой кон­кретной системы. Достоверное значение варьируется от 5 до 50 ошибок на 1000
6 В журнале Wired Magazine есть статья по этой теме, доступная по адресу http:// www.wired.com/wired/archive/3.      09/myhrvold.html ?person=gordon_moore&topic_ set=wiredpeople.

строк кода. Даже в системах, которые прошли строгий контроль качества (Quality Assurance — QA) все равно содержатся ошибки — приблизительно 5 ошибок на 1000 строк кода. В программной системе, которая прошла тестирование только на пред­мет работоспособности функциональных возможностей, что справедливо для боль­шей части коммерческого программного обеспечения, присутствует намного больше ошибок — около 50 ошибок на 1000 строк кода. Большая часть программ попадает в последнюю категорию. Многие поставщики программного обеспечения неверно предполагают, что они выполняют строгий контроль качества QA, хотя в действи­тельности их методы тестирования являются весьма поверхностными. Строгий кон­троль качества программного обеспечения заключается не только в тестировании возможностей программ, но и должен включать в себя тестовое внесение неисправ­ностей и анализ ошибок.
Чтобы оценить всю сложность современного программного обеспечения, проана­лизируйте следующую информацию.
Количество строк кода
400000 17 млн 40 млн 10 млн 7 млн 35 млн 1,5 млн менее 5 млн 40 млн
Система
Solaris 7 Netscape
Космическая станция
Космический челнок
Boeing 777
NT5
Linux
Windows 95 Windows XP
Как мы указывали ранее, для приведенных здесь систем характерна частота оши­бок от 5 до 50 на 1000 строк кода.
Для демонстрации постоянного роста количества строк кода рассмотрим его на примере операционных систем компании Microsoft. На 5 показано, как вырос объем операционной системы Windows, начиная с ее появления в 1990 году в виде версии Windows 3.1 (3 млн. строк программного кода) и заканчивая ее последней версией Windows XP, вышедшей в 2002 году (40 млн. строк программного кода). Один простой, но не слишком радостный факт справедлив для всего программного обеспечения: чем больше строк, тем больше ошибок. Если эта тенденция сохрани­лась, то в Windows XP должно быть достаточно много ошибок7. Здесь возникает очевидный вопрос: какое количество таких ошибок приводит к проблемам системы безопасности? И какая существует связь между ошибками и другими уязвимыми местами и разработкой хакерами программ атаки?
Настольный компьютер под управлением Windows XP и приложения для этой системы зависят от нормальной работы ядра. Это касается и приложений, обеспечи­вающих защиту от атак хакеров. Однако сама система Windows XP состоит из при-
близительно 40 млн. строк кода, и приложения тоже соответственно становятся сложнее. Когда система становится такой сложной, ошибки просто неизбежны.
Кроме того, усложняет проблему широкое использование низкоуровневых язы­ков программирования, таких как С и C++, которые не способны защитить от про­стейших атак, например от атак на переполнение буфера (которые мы рассмотрим в этой книге). Кроме дополнительных возможностей для взлома вследствие ошибок и других просчетов, вообще в сложных системах как таковых легче скрыть вредонос­ный код. Теоретически мы можем проверить и доказать, что в простой программе нет ошибок, влияющих на безопасность, но в действительности это невозможно, да­же если речь идет о самой простой современной настольной системе, и уж точно не­вероятно в отношении систем масштаба предприятия.
Больше строк, больше ошибок
Рассмотрим сеть из 30000 узлов (типичный размер сети средней корпорации). На каждой рабочей станции сети есть программное обеспечение в виде исполняемых файлов (ЕХЕ) и библиотек, а также около 3000 исполняемых модулей. Средний размер каждого модуля около 100 Кбайт. Предполагая, что в каждой строке кода со­держится по 10 байт кода, и задав минимальное количество ошибок (5) на 1000 строк кода, получим, что в каждом исполняемом модуле содержится около 50 ошибок.
~ 100 Кбайт 10 тыс. строк кода
исполняемый файл    исполняемый файл 5 ошибок 50 ошибок
1000 строк кода

Теперь вспомним, что на каждом хосте содержится около 3000 исполняемых файлов. Это означает, что на каждый компьютер сети приходится около 150000 уникальных ошибок в программном коде.
50 ошибок 3000 исполняемых файлов     150000 ошибок
-х-=-
исполняемый файл хост хост
Конечно, это огромное количество ошибок. Но проблемы только начинаются. Определим количество возможных целей атаки и количество копий однотипных ошибок, которые доступны как цели для атаки. Поскольку эти же 150000 ошибок повторяются множество раз на 30 тыс. хостов, то число потенциальных целей для хакера поистине огромно. В сети из 30 тыс. хостов насчитывается около 4,5 млрд. ошибок, благоприятствующих проведению атак (согласно нашим оценкам, только 150 тыс. из этих ошибок уникальны, но это число не точно).
150000 ошибок   30000 хостов
-х-= 4,5 млрд. ошибок в сети
хост сеть
Если представить, что 10 % всех ошибок приводят к проблемам в системе безо­пасности и что только 10 % из них могут быть использованы при удаленных атаках (по сети), то согласно нашим данным, в этой небольшой локальной сети будет 5 млн. уязвимых мест в программном обеспечении, доступных для удаленной атаки. Уст­ранение 5 млн. уязвимых мест является серьезной задачей, а правильное управление заплатами для 5 млн. уязвимых мест, разбросанных по 30000 хостам, еще сложнее.
4,5 млрд х 10% = 500 млн. ошибок по безопасности
500 млн х 10% = 5 млн. доступных удаленно уязвимых мест
Согласно этим цифрам, хакер заранее находится в выигрышном положении. И неудивительно, что при использовании одинаковых операционных систем и прило­жений (что усугубляет значение этих цифр) вирус Blaster смог так успешно распро-страниться8.
Расширяемость
Современные системы, которые строятся на основе виртуальных машин (VM), обеспечивают безопасность типов (type safety) и выполняют динамические проверки прав доступа (таким образом разрешается выполнение непроверенного переносимо­го кода), называют расширяемыми системами (extensible systems). Наиболее извест­ные примеры — Java и .NET. Поскольку на расширяемую систему можно добавлять обновления или расширения, которые еще называют переносимым кодом (mobile code), то функциональные возможности такой системы могут постоянно увеличи­ваться. Например, виртуальная машина Java Qava Virtual Machine — JVM) может

задавать класс в пространстве имен и потенциально разрешать другим классам взаимодействовать с ним.
Большинство современных операционных систем поддерживают расширяемость с помощью динамически загружаемых драйверов устройств и динамически загру­жаемых модулей. В современных приложениях, таких как текстовые процессоры, клиенты электронной почты, программы для работы с электронными таблицами и Web-браузеры, расширяемость поддерживается с помощью сценариев, элементов управления, компонентов, динамически загружаемых библиотек и аплетов. Ни одно из этих средств не является новым. И действительно, программное обеспечение яв­ляется основным способом расширения возможностей компьютеров, предназначен­ных для решения стандартных задач. Именно программы определяют работу ком­пьютера и оригинальным способом расширяют его базовые возможности.
К сожалению, истинная сущность современных расширяемых систем усложняет задачу безопасности. Например, очень трудно предотвратить проникновение на компьютер вредоносного кода, замаскированного под расширение, т.е. расширение, которое позволяет расширить функциональные возможности системы (например механизм для загрузки классов Java), должно создаваться с учетом требований безо­пасности. Более того, исследование безопасности расширяемой системы должны проводиться намного тщательней, нежели цельной системы, не подверженной изме­нениям. Как можно проверить код, который только что доставлен? Эти и другие проблемы безопасности расширяемого кода подробно рассмотрены в книге Securing Java (Мак-Гроу и Фелтен, 1999).
Компания Microsoft резко перешла на переносимый код с внедрением своей платформы .NET Framework. Как показано на 6, архитектура .NET имеет мно­го общего с Java. Главное отличие заключается в наличии многоплатформенной поддержки. Но в любом случае, расширяемые системы будут использоваться и дальше. Вскоре сам термин переносимый код будет излишним, поскольку весь код станет переносимым.
Но, к сожалению, у переносимого кода, который предназначен для расширения возможностей программ, есть оборотная сторона. В некотором смысле вирусы и "черви" тоже можно назвать переносимым кодом. Вот почему исполняемые вложе­ния в сообщения электронной почты и виртуальные машины, которые запускают код, внедренный на Web-страницы, становятся ночным кошмаром для специалистов по безопасности. Классические методы атак, включая распространение вирусов че­рез дискеты и передачу инфицированных исполняемых файлов с помощью модемов, сегодня заменены электронной почтой и содержимым Web-страниц. Современные хакеры широко используют атаки с помощью переносимого кода. Вирусы и "черви" не просто распространяются по сети, они устанавливают потайные ходы, определя­ют тип системы и реализуют компрометацию компьютера, т.е. хакер получает зара­женный компьютер в свое распоряжение.

Программное обеспечение — источник всех проблем
"Золотая эра" вирусов наступила в начале 1990-х годов, когда они распространя­лись с помощью исполняемых файлов и кочевали с одного компьютера на другой с помощью дискет. "Червь" представляет собой особую форму вируса, который само­стоятельно распространяется по сети. "Черви" являются очень опасной модифика­цией вирусов,  особенно с учетом современного размаха использования сетей.

"Черви" стали активно распространяться по сетям в конце прошлого века, хотя мно­гие опасные "черви" (разработанные хакерами-энтузиастами) так никогда и не будут запущены в сеть, а значит, никогда не будут исследованы. С момента появления пер­вых "червей" технология создания этих программ сделала значительный шаг вперед. "Черви" позволяют хакеру провести "ковровое бомбометание" по всей глобальной сети, а также атаку на конкретное уязвимое место в максимальном масштабе. Это значительно усиливает суммарный эффект атаки и позволяет получить результаты, которые никогда не были бы достигнуты при поочередных атаках хакера вручную на разные компьютеры. В результате атак "червей" в большинство компьютерных сетей 1000 глобальных корпораций были внедрены потайные ходы. В сообществе хакеров ходят слухи о существовании так называемого Списка успеха 500 {Fortune 500 List) — списка действующих потайных ходов в компьютерные сети 500 крупнейших компа­ний мира.
Один из первых вредоносных "червей", которому удалось поразить глобальную сеть и который широко использовался как средство взлома, был создан группой ха­керов-единомышленников, которые называли себя ADM (Association De Malfaiteurs). "Червь" ADMwOrrn использует ошибку переполнения буфера в DNS-серверах10. По­сле заражения "червем", взломанный компьютер начинает сканирование сети в по­исках других уязвимых серверов. Этот "червь" заразил десятки тысяч компьютеров, в прессе появилось немало заметок о его распространении. Некоторые из первых жертв атаки "червя" ADM остались зараженными по сей день. Особое беспокойство вызывает тот факт, что уязвимое место, использованное для распространения "червя" ADM, было изучено весьма поверхностно. При этом структура "червя" по­зволяет без труда добавить в него другой код для проведения атаки. Таким образом, "червь" сам по себе является расширяемой системой. Остается только догадываться, сколько версий этого "червя" сейчас "разгуливают" по Internet.
В 2001 году сообщение о знаменитом сетевом "черве" под названием Code Red вышло на первых полосах газет. Этот "червь" поразил сотни тысяч серверов, в том числе компьютеры, на которых был запущен ISS-сервер от компании Microsoft. При этом использовалась очень простая, но, к сожалению, широко распространенная ошибка программного обеспечения11. Как это бывает обычно при успешной и раз­рекламированной атаке "червя", появилось несколько его модификаций. "Червь" Code Red заражает сервер, который затем начинает сканирование сети в поисках но­вых целей атаки. В оригинальной версии Code Red преимущественно осуществля­лось сканирование систем, которые находились поблизости от пораженного хоста. Этим ограничивалась скорость распространения этого "червя".
Совсем немного времени прошло после дебюта Code Red в глобальной сети, как появилась его усовершенствованная версия, в которой использовался улучшенный алгоритм сканирования сети. Это еще больше ускорило темпы распространения Code Red. Успех "червя" Code Red основан на очень простом недостатке в про-
граммном обеспечении, которое широко использовалось более 20 лет. Повсеместное наличие этого недостатка на Windows-системах, безусловно, помогло быстрому рас­пространению Code Red.
Подобные результаты были достигнуты еще несколькими "червями", включая Blaster и Slammer. Мы более подробно рассмотрим вредоносный код и его влияние на использование программного обеспечения далее в этой книге. Мы также изучим средства хакеров, с помощью которых они взламывают чужие программы.

 

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