Andrew Tanenbaum
Изд. Питер
ISBN 5-318-00299-4
2004
отрывок из 9-й главы (стр. 677-699)
Варианты атак системы, обсуждавшиеся в предыдущих разделах, по большей части предпринимались изнутри системы, то есть уже зарегистрировавшимися пользователями. Однако последнее время, с распространением Интернета и локальных сетей, все большую угрозу для компьютеров представляют атаки снаружи. Компьютер, подключенный к сети, может быть атакован по этой сети с удаленного компьютера. Почти во всех случаях такая атака состоит из передачи по сети на атакуемую машину некоторой программы, при выполнении которой атакуемой машине наносится ущерб. По мере того как количество подключенных к Интернету компьютеров продолжает увеличиваться, опасность подобных атак также растет. В следующих разделах мы рассмотрим некоторые аспекты операционных систем, связанные с внешней угрозой, уделив основное внимание вирусам, червям, мобильному коду и апплетам Java.
В последнее время сообщения об атаке компьютеров каким-либо вирусом иди червем появляются в газетах почти каждый день. Вирусы и черви представляют главную проблему безопасности для отдельных пользователей и компаний. В следующих разделах мы изучим их принципы работы и обсудим, что можно предпринять для борьбы с ними.
Я долго колебался, стоит ли столь подробно описывать детали в данном разделе, не желая подвигнуть некоторых пользователей на реализацию плохих идей, но уже существующие книги содержат значительно больше подробностей, в некоторых их них даже приводятся настоящие программы [218]. Кроме того, в Интернете полно информации о вирусах, так что джин уже выпущен из бутылки. Кроме того, трудно научиться бороться с вирусами, не зная, как они работают. Наконец, у очень многих пользователей неверное представление о вирусах, которое требует коррекции.
В отличие от программистов, пишущих игры, создатели вирусов не ищут популярности после того, как их творения выходят в свет. Основываясь на скудных свидетельствах, можно предположить, что основными авторами вирусов являются старшие школьники и студенты или недавние выпускники колледжей, написавшие вирус, просто чтобы проверить, удастся ли им это, и не сознавая (или не беспокоясь), что жертв у вирусной атаки может быть столько же, сколько у ypaгана или землетрясения. Цель типичного автора вируса заключается в создании вируса, который быстро распространяется, который трудно обнаружить и от которого трудно избавиться после обнаружения.
Что такое вирус? В двух словах, вирус - это программа, которая может размножаться, присоединяя свой код к другой программе, что напоминает размножение биологических вирусов. Кроме того, вирус может выполнять и другие функции. Черви напоминают вирусов, но размножаются сами. Это отличие не будет интересовать нас в данной книге, поэтому мы будем пока использовать термин "вирус" для обоих типов программ. Черви будут рассмотрены отдельно в разделе - "Интернет-черви" данной главы.
Поскольку вирус - это программа, он может делать то, что может программа. Ha пример, он может выводить на экран сообщение или изображение, воспроизводить звуки или выполнять другие безвредные действия. К сожалению, он также может удалять, модифицировать, уничтожать или воровать файлы (передавая их кому-либо по электронной почте). Шантаж тоже возможен. Представьте себе вирус, который зашифровал все файлы на жестком диске жертвы, после чего вывел следующее сообщение:
ПРИВЕТ ОТ КОМПАНИИ GENERAL ENCRYPTION! ДЛЯ ПРИОБРЕТЕНИЯ КЛЮЧА ДЕШИФРАЦИИ К ВАШЕМУ ЖЕСТКОМУ ДИСКУ, ПОЖАЛУЙСТА, ВЫШЛИТЕ $100 В МЕЛКИХ НЕМАРКИРОВАННЫХ КУПЮРАХ НА А/Я 2154, ПАНАМА-СИТИ, ПАНАМА. СПАСИБО. МЫ РАДЫ СОТРУДНИЧАТЬ С ВАМИ.
Кроме того, вирус может сделать невозможным использование компьютера во время своей работы. Такая атака называется атакой отказа в обслуживании. Обычно для этого вирус поедает ресурсы компьютера, например процессорное время, (или заполняет жесткий диск всяким мусором. Вот, например, программа, состоящая из одной строки, способная поставить на колени любую систему UNIX:
main() {while (1) fork();}
Эта программа создает процессы, пока не переполнится таблица процессов, после чего ни один новый процесс не сможет запуститься. Теперь представьте себе вирус, заразивший в системе этим кодом каждую программу. Для защиты от подобной атаки во многих современных системах UNIX количество дочерних процессов ограничено.
Что еще хуже, вирус может повредить аппаратное обеспечение компьютера. Многие современные компьютеры содержат подсистему ввода-вывода BIOS во флэш-ПЗУ, содержимое которого может программно изменяться (чтобы проще было обновлять BIOS). Вирус может записать в BIOS случайный мусор, после чего компьютер перестанет загружаться. Если флэш-ПЗУ вставлено в кроватку, то для устранения проблемы нужно открыть компьютер и заменить микросхему. Если же флэш-П3У впаяно в материнскую плату, то, возможно, всю материнскую плату придется выбросить и купить новую. Определенно невеселый опыт.
Как правило, вирусы наносят ущерб кому попало, но вирус может также преследовать и строго определенную цель. Например, компания может выпустить вирус, проверяющий, не работает ли он на компьютере конкурирующей фирмы и не отсутствует ли системный администратор в настоящий момент в системе. Если горизонт чист, он может вмешаться в производственный процесс, снижая качество продукции и создавая, таким образом, проблемы для конкурента. В остальных случаях он не будет ничего предпринимать, снижая вероятность своего обнаружения.
Другой пример вируса направленного действия - вирус, написанный амбициозным вице-президентом корпорации, который запускает его в локальную сеть собственного предприятия. Вирус проверяет, работает ли он на компьютере президента, и если да, то находит электронную таблицу и меняет в ней две случайные ячейки. Рано или поздно, основываясь на этой электронной таблице, президент примет неверное решение и будет уволен, освобождая кресло - сами понимаете для кого.
Мы достаточно налюбовались картинами разрушений. Рассмотрим теперь принципы работы вирусов. Автор вируса создает свое творение, вероятно, на ассемблере, после чего аккуратно вставляет его в программу на собственном компьютере с помощью специального инструмента, называемого "пипеткой" (dropper). Затем инфицированная программа распространяется, возможно, с помощью опубликования ее на BBS или в виде свободно распространяемой программы через Интернет. Эта программа может представлять собой занимательную новую игру, пиратскую версию коммерческого программного продукта или еще что-либо подобное, вызывающее интерес у публики. Затем пользователи начинают загружать эту программу на свои компьютеры.
После запуска программы вирус, как правило, начинает с того, что заражает другие программы на этой машине, после чего выполняет свою "полезную" нагрузку, то есть запускает ту часть программы, для которой и писался вирус. Во многих случаях эта программа может не запускаться, пока не наступит определенная дата или пока вирус гарантированно не распространится на большое число компьютеров. Выбранная дата может даже быть привязана к какому-либо политическлыу событию (например, к столетию или 500-летию обиды, нанесенной этнической группе автора).
Ниже мы обсудим семь разновидностей вирусов, основываясь на том, что ими заражается. Это вирусы-компаньоны, а также вирусы, заражающие исполняемое файлы, память, загрузочный сектор, драйверы устройств, макросы и исходные тексты программ. Без сомнения, вскоре появятся новые разновидности вирусов.
Вирусы-компаньоны не заражают программу, а запускаются вместо какой-либо программы. Проще всего объяснить эту концепцию на примере. В системе MS-DOS, когда пользователь вводит команду
prog
MS-DOS сначала ищет файл prog.com. Если такого файла нет, операционная система ищет файл prog.ехе. В системе Windows, когда пользователь в меню Пуск выбирает пункт Выполнить..., происходит то же самое. Сегодня большинство программ представляют собой файлы с расширением .ехе, файлы .com используются очень редко.
Предположим, что автору вируса известно, что многие пользователи запускают программу prog.ехе из командной строки в MS-DOS или Windows. Он может просто создать программу, назвав ее prog.com. Этот файл будет запускаться каждый раз, когда кто-либо пытается запустить prog.exe без указания расширения файла. Выполнив свою работу, программа prog.com запускает файл prog.ехе, так что пользователь ничего не замечает.
Сходный вариант атаки использует рабочий стол Windows, на котором расположены ярлыки (символьные связи) программ. Вирус может подменить путь, содержащийся в ярлыке, так, чтобы тот указывал не на программу, а на вирус. Когда пользователь щелкает дважды мышью на пиктограмме, запускается вирус. 3акончив свое черное дело, вирус запускает оригинальную программу.
Несколько более сложными являются вирусы, заражающие исполняемые файлы, Простейший вид таких вирусов просто записывает себя поверх исполняемой программы. Такие вирусы называются перезаписывающими вирусами. Логика заражения файла, содержащаяся в таком вирусе, показана в листинге 9.4.
Листинг 9.4. Рекурсивная процедура, ищущая исполняемые файлы в системе UNIX
#include <sys/types.h> /* стандартные заголовки POSIX */ #include <sys/stat.h> #include <dirent.h> #include <fcntl.h> #include <unistd.h> struct stat sbuf; /* для вызова lstat, чтобы убедиться, что */ /* файл представляет собой символьную связь */ search(char *dir_name) { /* рекурсивный поиск исполняемых файлов */ DIR *dirp; /* указатель на открытый каталог */ struct dirent *dp; /* указатель на запись каталога */ dirp = opendir(dir_name); /* открыть этот каталог */ if (dirp == NULL) return; /* каталог не открывается */ while (TRUE) { dp = readdir(dirp); /* прочитать следующую запись каталога */ if (dp == NULL) { /* NULL означает, что достигнут конец каталога */ chdir (".."); /* вернуться в родительский каталог */ break; /* выход их цикла */ } if (dp->d_name[0] == '.') continue; /* пропустить каталоги . и .. */ lstat(dp->d_name, &sbuf); /* является ли запись символьной ссылкой? */ if (S_ISLNK(sbuf.st_mode)) continue; /* пропустить символьные ссылки */ if (chdir(dp->d_name) == 0) { /* если chdir завершился успешно, */ /* то это должен быть каталог */ search("."); /* да, войти в него т продолжить поиск в нем */ } else { /* нет (файл), заразить его */ if(access(dp->d_name,X_OK) == 0)/* если файл исполняемый, заразить его */ infect(dp->d_name); } closedir(dirp); /* каталог обработан; закрыть его */ } }
Головной модуль этого вируса сначала копирует свою двоичную программу в массив, открывая argv[0] и считывая его для надежного хранения. Затем он сканирует файловую систему, начиная с корневого каталога, и вызывает процедуру search с корневым каталогом в качестве параметра.
Рекурсивная процедура search обрабатывает каталог, открывая его, а затем счиnывaя его записи по одной при помощи функции readdir, пока эта функция не вернет значение NULL. Это означает, что в каталоге больше нет записей. Если запись представляет собой каталог, он также обрабатывается рекурсивным вызовом процедуры search. Если же это исполняемый файл, он заражается процедурой infect, которой в виде параметра передается имя файла. Записи каталогов, имена которых начинаются с точки, пропускаются, чтобы избежать проблем с каталогами "." и "..". Кроме того, пропускаются символьные связи, так как программа предполагает, что она сможет открыть каталог при помощи системного вызова chdir, а затем вернуться в предыдущий каталог, двигаясь по ссылкам "..", что возможно при использовании жестких связей, но невозможно при символьных ссылках. Для использования символьных ссылок требуется более сложная программа.
Процедура инфицирования файлов infect (не показанная) просто должна открыть файл по имени, записать вирус, хранящийся в массиве, в файл, после чего закрыть файл.
Этот вирус может быть "усовершенствован" различными способами. Во-первых, заражение файла может производиться не со 100-процентной вероятностью, а скажем, лишь в одном случае из 128, для чего можно использовать генератор псевдослучайной последовательности чисел. Это позволит снизить шансы раннего обнаружения вируса, в результате чего у вируса будет больше времени на pacпространение. Биологические вирусы обладают сходными свойствами: вирусы, которые быстро убивают свои жертвы, не распространяются так же быстро, как те, что вызывают долго длящиеся заболевания, возможно, вообще без летального исхода. В последнем случае у жертвы существенно больше шансов распространить вирус. Альтернативная схема представляет собой более высокий процент заражения (например, 25%), но при этом есть ограничение на количество одновременно заражаемых файлов. Таким образом снижается активность диска, чтобы вызвать меньше подозрений.
Во-вторых, процедура infect может проверять, заражен ли уже файл. 3apaжение одного и того же файла дважды представляет собой просто потерю времени. В-третьих, вирус может сохранять время последнего изменения файла и размер файла неизменными, пытаясь скрыть факт заражения файла. Если программа по размеру больше, чем вирус, ее размер останется неизменным, но программы меньшие, чем вирус, увеличатся в размерах. Однако поскольку размеры большинства вирусов меньше размеров большинства программ, эта проблема не является серьезной.
Хотя эта программа не очень длинна (полный текст программы на языке С помещается на одну страницу, и размер программного сегмента не превосходит 2 Кбайт), ассемблерная версия вируса может быть еще короче. Людвиг приводит вариант написанного на ассемблере вируса для операционной системы MS-DOS, заражающего все файлы в своем каталоге и состоящего всего из 44 байт в двоичном виде [218].
Ниже в этой главе будут рассмотрены антивирусные программы, то есть программы, обнаруживающие и уничтожающие вирусы. Следует отметить, что логика, используемая вирусом для обнаружения всех исполняемых файлов (см. листинг 9.4), может применяться и в антивирусных программах. Технологии инфицирования и дезинфекции идут рука об руку, и для успешной борьбы с вирусами необходимо иметь хорошее представление о принципах работы вирусов.
С точки зрения автора вируса недостаток перезаписывающего вируса заключается в том, что его очень легко обнаружить. В конце концов, при запуске инфицированная программа сможет распространить вирус, заразив еще несколько файлов, но она не выполнит то, что должна выполнять, и пользователь это мгновенно заметит. Соответственно, большинство вирусов прицепляются к программам, позволяя им нормально выполняться после того, как вирус выполнит свое черное дело. Такие вирусы называют паразитическими вирусами.
Паразитические вирусы могут присоединяться в начало, конец или в середину исполняемого файла. Если вирус прикрепляется к началу файла, он должен сначала считать файл в память, записать в файл сначала себя, а затем дописать считанный файл (рис. 9.8, б). Однако на новом виртуальном адресе программа работать не будет, поэтому вирус либо должен настроить программу на работу по новому адресу, либо сдвинуть ее на виртуальный адрес 0 после своей работы.
Чтобы избежать сложностей, связанных с размещением вируса в начале файла, большинство вирусов прикрепляются в конец файлов и изменяют адрес запуска программы в заголовке, перенаправляя его на себя (рис. 9.8, в). Теперь вирус должен уметь запускаться по виртуальному адресу, зависящему от длины зараженной программы, а это означает, что вирус должен быть написан в позиционно-независимом коде, используя относительные, а не абсолютные адреса. Для опытного программиста это не сложно.
Рис. 9.8. Исполняемый файл (а); с вирусом в начале (б); с вирусом в конце (в); с вирусом, распределенным по свободным участкам программы (г)
Сложные форматы исполняемых файлов, такие как, .exe в Windows, а также почти все современные двоичные форматы в UNIX позволяют программам состоять из нескольких сегментов текста и данных, которые загрузчик собирает в памяти и выполняет настройку адресов на лету. В некоторых системах (например, Windows) размеры всех сегментов (секций) кратны 512 байт. Если сегмент заполнен не целиком, компоновщик дополняет секцию нулями. Вирус, знакомый с этим, может попытаться спрятаться в этих промежутках. Если ему удается целиком запихать себя в свободные участки исполняемого файла, размер этого файла остается неизменным. А это является большим преимуществом, так как такой вирус сложнее обнаружить. Вирусы, использующие этот принцип, называются полостными вирусами. Конечно, если загрузчик не загружает пустые области в память при запуске программы, вирусу понадобится какой-либо другой способ, чтобы запуститься.
До сих пор мы предполагали, что при запуске зараженной программы запускается вирус, который передает управление настоящей программе, а сам завершает свое существование в памяти. В отличие от подобных вирусов резидентные вирусы, будучи загруженными в память, остаются там навсегда, либо прячась на самом верху памяти, либо прижимаясь "к земле" среди векторов прерываний, в которых последние несколько сот байт, как правило, не используются. Очень умные вирусы даже могут модифицировать карту памяти операционной системы, чтобы она полагала, что эта область памяти занята. Таким образом удается избежать опасности загрузки поверх вируса какой-либо другой программы.
Типичный резидентный вирус перехватывает один из векторов прерываний, сохраняя старое значение в своей переменной, и подменяет его адресом своей процедуры. Это может быть прерывание от внешнего устройства ввода-вывода или эмулированное прерывание. Лучше всего для вируса перехватывать эмулированное прерывание системного вызова. Выполнив свои дела, вирус передает управление настоящему системному вызову.
3ачем вирусу работать при каждом системном вызове? Чтобы инфицировать программы. Вирус может подождать, пока не произойдет обращение к системному вызову exec, а затем, зная, что файл, к которому происходит обращение, исполняемый (и, вероятно, полезный), заражает его. При этом процессе не требуется значительной активности диска, как это было в случае, показанном в листинге 9.4, поэтому такой вирус имеет больше шансов остаться необнаруженным. Кроме того, перехват всех системных вызовов дает вирусу возможность шпионить за данными и выполнять самые разнообразные злодеяния.
Как описывалось в главе 5, при включении большинства компьютеров BIOS считывает главную загрузочную запись с начала загрузочного диска в оперативную память и исполняет ее. Эта программа находит активный раздел диска, считывает его первый (загрузочный) сектор и исполняет его. Затем эта программа загружает либо операционную систему, либо загрузчик операционной системы. К сожалению, уже много лет назад кому-то пришла в голову идея создать вирус, перезаписывающий главную загрузочную запись или загрузочный сектор, последствия реализации которой оказались разрушительными. Такие вирусы очень широко распространены.
Как правило, вирус, поражающий загрузочный сектор (или главную загрувочную запись), сначала копирует исходное содержимое загрузочного сектора в какое-либо безопасное место на диске, что позволяет ему загружать операционную систему после того, как он закончит свои дела. Программа форматирования диска фирмы Microsoft fdisk пропускает первую дорожку диска, поэтому эта дорожка на машинах с операционной системой Windows представляет собой хорошее укрытие. Еще один вариант состоит в том, чтобы пометить свободный сектор диска как дефектный. Если корневой каталог достаточно велик и располагается в фиксированном месте, как в системе Windows 98, вирус может использовать конец корневого каталога. По-настоящему агрессивный вирус может даже выделить себе нормальное свободное дисковое пространство и обновить состояние списка свободных блоков соответствующим образом. Это потребует знания интимных подробностей внутренних структур данных операционной системы, но у автора вируса был хороший преподаватель на курсе операционных систем, и создатель вируса был прилежным учеником.
При загрузке компьютера вирус копирует себя в оперативную память, либо в старшие адреса, либо в неиспользуемую область векторов прерываний, В этот момент машина находится в режиме ядра, ее блок управления памятью выключен, операционной системы нет, также нет и антивирусной программы. Самый удобный момент для вирусов. Когда все готово, вирус загружает операционную систему, как правило, оставаясь резидентным в памяти.
Однако проблема таких вирусов связана с тем, как затем снова получить управление. Обычный способ заключается в использовании специфических сведений о том, как операционная система управляет вектором прерываний. Например, система Windows не перезаписывает весь вектор за одну операцию. Вместо этого она загружает драйверы устройств один за другим, и каждый из них забирает при необходимости вектор прерывания. Этот процесс может занимать около минуты.
Такая схема дает вирусу возможность сохранить за собой управление. Он начинает с того, что перехватывает сразу все векторы прерываний (рис. 9.9, а). По мере загрузки драйверов некоторые векторы перезаписываются. Но если только драйвер часов не загрузится первым, у вируса будет много возможностей получить управление по прерыванию от таймера. Потеря вирусом прерывания от принтера показана на рис.9.9, б. Как только вирус замечает, что один из векторов прерываний у него отнят, он может захватить его снова, зная, что теперь это безопасно. (В действительности некоторые векторы прерываний перезаписываются во время загрузки операционной системы по нескольку раз, но последовательность этих действий является детерминированной, и автор вируса знает ее наизусть.) Повторный перехват прерывания принтера показан на рис. 9.9, в. Когда все загружено, вирус восстанавливает все векторы прерываний, а себе оставляет только вектор эмулированного прерывания, которым пользуются системные вызовы. В конце концов, управление системными вызовами значительно интереснее, чем контроль над каждой операцией гибкого диска, но во время загрузки вирус не может рисковать потерять управление навсегда. Итак, когда операционная система загрузилась, мы имеем резидентный вирус, контролирующий системные вызовы. Большинство резидентных вирусов именно так и загружаются.
Рис. 9.9. В начале вирус перехватывает все векторы прерываний (а); операционная система забрала себе вектор прерывания принтера (б); вирус заметил потерю вектора прерывания принтера и снова захватил его (в)
Описанный выше способ загрузки вируса в память напоминает спелеологию (исследование пещер) - вам нужно ползти, извиваясь в узком извилистом проходе, постоянно опасаясь, что что-то может упасть вам на голову. Было бы значительно проще, если бы операционная система была столь любезна, что грузила бы вирус законным образом. При небольших усилиях это достижимо. Трюк заключается в инфицировании драйвера устройства, чем занимаются вирусы драйверов устройств. В системе Windows и в некоторых UNIX-системах драйверы устройств представляют собой просто исполняемые файлы на диске, загружаемые вместе с операционной системой. Если один из них может быть заражен паразитическим вирусом, этот вирус всегда будет официально загружаться при загрузке системы. А еще при этом подходе хорошо то, что драйверы работают в режиме ядра, что позволяет вирусу перехватить вектор прерываний системных вызовов.
Многие программы, такие как Word и Excel, позволяют пользователям писать макросы, чтобы группировать некоторые команды, которые позднее можно будет выполнить одним нажатием клавиши. Макросы также вызываются из меню, в которые могут добавляться новые пункты. В Microsoft Office макросы могут содержать целые программы на языке Visual Basic, представляющем собой полноценный язык программирования. Макросы, как правило, не компилируются, а интерпретируются, что, конечно, значительно снижает их производительность, но не oграничивает их возможностей. Поскольку обычно макросы работают с неким конкретным документом. В Microsoft Office макросы для каждого документа хранятся вместе с самим документом (в том же файле).
Теперь рассмотрим проблему, связанную с макросами. Автор вируса создает в редакторе Word документ, а также создает макрос, который присоединяет к функции OPEN FILE (открыть файл). В этом макросе содержится макровирус. 3атем он посылает этот файл по электронной почте своей жертве, которая открытвает файл (если только программа электронной почты еще не открыла этот файл сама). Открытие документа вызывает исполнение макроса OPEN FILE. Поскольку макрос может содержать произвольную программу, он может выполнять любые действия, например заражать другие документы Word, удалять файлы и т.д. Будем честными по отношению к корпорации Microsoft: редактор Word делает предупреждение при попытке открыть файл с макросами, но большинство пользователей не понимает смысла этого предупреждения и продолжает открывать файл. Кроме того, вполне безобидные документы также могут содержать макросы. И наконец, существует множество программ, открывающих файлы безо всякого предупреждения, в результате чего обнаружение вируса значительно усложняется.
С распространением электронной почты отправка документов с вирусами, встроенными в макросы, стала представлять собой постоянную головную боль. Такие вирусы написать значительно легче, чем спрятать настоящий загрузочный сектор в списке дефектных блоков, скрыть вирус среди векторов прерываний и перехватить вектор прерываний системных вызовов. Это означает, что подобные вирусы могут быть написаны значительно менее образованными людьми, снижающими качество продукции и превращающими термин "писатель вирусов" в ругательство.
Паразитические вирусы и вирусы, заражающие загрузочные секторы, в высокой степени привязаны к определенной платформе. Документные вирусы в меньшей степени зависят от платформ. Самыми переносимыми вирусами являются вирусы, заражающие исходные тексты программ. Представьте себе вирус, показанный в листинге 9.4, но только вместо исполняемых двоичных файлов ищущий программы на языке C (для этого требуется изменить в листинге всего одну строку: обращение к процедуре access). Процедура infect должна вставлять в начале каждого заражаемого файла строку
#include <virus.h>
Кроме того, требуется поместить куда-либо в середину программы еще одну строку
run_virus();
чтобы активировать вирус. Для определения места, куда вставить эту строку, от вируса требуется способность понимать структуру программы на языке C, так как это место должно синтаксически позволять вызов процедуры, к тому же в это место программы должно передаваться управление (например, бессмысленно помещать вызов процедуры после оператора return). Бесполезно также вставлять вызов процедуры run_virus() в середину комментариев. Помещение этой процедуры в цикл может оказаться тоже не очень хорошим решением. Если удастся правильно поместить вызов процедуры (например, перед самым концом процедуры main или перед оператором return, если такой оператор есть в тексте), то после компиляции даная программа будет содержать вирус. Вероятно файл с именем prog.h вызовет меньше подозрений, чем virus.h.
При запуске программы произойдет обращение к вирусу. Вирус может выполнять при этом самые различные действия, например искать другие программы на языке C, чтобы их заразить. Если он найдет новый файл, он может заразить его, добавив всего две приведенные выше строки, но это будет работать только на локальной машине, на которой уже установлен файл virus.h. Чтобы вирус мог работать на удаленной машине, необходимо включить в программу весь исходный текст вируса, который может быть вставлен в виде инициализированной текстовой строки, желательно в виде списка 32-разрядных целых чисел, чтобы было труднее догадаться, что это такое. Эта строка может быть довольно длинной, но при сегодняшних многомегабайтных программах весьма вероятно, что никто не обратит на нее внимания.
Для неподготовленного читателя все описанные выше способы заражения системы вирусами могут показаться довольно сложными. Тем не менее все эти способы применяются на практике, в чем можно убедиться, открыв любую газету. У писателей вирусов неиссякаемая фантазия, часто превосходное знание компьютера и операционных систем, а также масса свободного времени.
Существует несколько сценариев распространения вирусов. Начнем наше обсуждение данной темы с классического варианта. Когда вирус создан, он помещается в какую-либо программу (как правило, чужую, хотя бывает, что автор вируса заражает им свою программу), после чего зараженная программа распространяется, например, помещается на web-сайте бесплатных или оплачиваемых после скачивания программ. Эту программу кто-нибудь скачивает и запускает. Далее может быть несколько вариантов. Во-первых, вирус может заразить несколько файлов на жестком диске в надежде, что жертва решит поделиться этими файлами со своими друзьями. Он также может попытаться заразить загрузочный сектор жесткого риска. Как только загрузочный сектор инфицирован, вирус сможет запускаться в резидентном режиме при каждой последующей загрузке компьютера.
Кроме этого, вирус может проверить наличие гибких дисков в дисководах и попытаться заразить их загрузочные секторы. Гибкие диски представляют собой удобную мишень, так как они перемещаются с машины на машину гораздо чаще, чем жесткие диски. Если загрузочный сектор гибкого диска инфицирован и такой диск используется для загрузки другого компьютера, вирус может заразить файлы и загрузочный сектор жесткого диска этого компьютера. В прошлом, когда гибкие диски представляли собой основное средство переноса программ, этот механизм был основным путем распространения вирусов.
Сегодня для распространения вирусов есть другие возможности. Вирус может проверять, подключена ли машина, на которой он работает, к локальной сети, вероятность чего очень высока для компьютеров университета или компании. Затем вирус может начать заражать незащищенные файлы на серверах этой локальной сети. На защищенные файлы эта инфекция распространиться не сможет, но часто вирусы используют специальный трюк, заключающийся в том, что намеренно вызывают странное поведение зараженных ими программ. Расчет делается на то, что пользователь, озадаченный ненормальным поведением программы, обратится за помощью к системному администратору. Системный администратор попробует сам запустить странно ведущую себя программу, чтобы посмотреть, что случилось, Если администратор выполнит это, обладая полномочиями суперпользователя, то вирус, содержащийся в программе, получит возможность заразить системные двоичные файлы, драйверы устройств, операционную систему и загрузочные секторы. Для этого потребуется всего лишь одна ошибка системного администратора, в результате которой зараженными могут оказаться все машины локальной сети.
Часто компьютеры в локальной сети имеют полномочия регистрироваться по Интернету на удаленных машинах или даже выполнять удаленно команды без регистрации. В данном случае вирусы получают еще больше возможностей для распространения. Таким образом, одна ошибка системного администратора может привести к инфицированию компьютеров всей компании. В большинстве компаний системным администраторам запрещается ошибаться.
Еще один способ распространения вирусов заключается в публикации зараженной программы в одной из конференций USENET или на BBS. Кроме того, автор вируса может создать web-страницу, для просмотра которой требуется специальный плагин (plug-in, сменный программный модуль), и тут же предложить загрузить этот плагин, который будет заражен вирусом.
В последнее время все большее распространение получают вирусы, распространяемые вместе с документами (например, редактора Word). Эти документы рассылаются по электронной почте или публикуются в конференциях USENET, BBS и на web-страницах Интернета, как правило, в виде файловых дополнений к письму. Даже люди, которым в голову не приходит запускать программу, присланную им незнакомым человеком, могут не понимать, что, открывая дополнение щелчком мыши, они могут впустить вирус в свою машину. Затем вирус может заглянуть в адресную книгу пользователя и разослать самого себя по всем адресам из этой книги. В строке Subject при этом, как правило, вирус указывает нечто интересное и правдоподобное, например:
Subject: Изменения планов Subject: Re: то последнее письмо Subject: Собака умерла прошлой ночью Subject: Я серьезно болен Subject: Я тебя люблю
Когда такое письмо приходит, получатель видит, что отправитель письма - его друг или коллега по работе, и ни о чем не подозревает. Когда письмо открыто, уже слишком поздно. Вирус "I LOVE YOU", распространившийся по всему миру в июне 2000 года, действовал именно этим способом и нанес ущерб в несколько миллиардов долларов.
Помимо самих вирусов, также распространяется технология их изготовления. Существуют группы писателей вирусов, активно обменивающихся информацией по Интернету и помогающих друг другу в разработке новых технологий, инструментов и вирусов. Для большинства из них создание вирусов представляет собой скорее хобби, чем профессиональную криминальную деятельность, но эффект от их действий от этого не становится менее разрушительным. Еще одну группу писателей вирусов представляют военные, рассматривающих вирусы как военное оружие, способное вывести из строя компьютерные системы противника.
С распространением вирусов связана проблема избежания обнаружения. Тюрьмы славятся плохим компьютерным оснащением, поэтому авторы вирусов предпочитают избегать этих мест. Опубликование вируса в сети со своего домашнего компьютера означает серьезный риск. Когда вирус будет, в конце концов, обнаружен, полиция сможет проследить путь его появления в сети, найдя по временному штампу самое первое сообщение, содержащее этот вирус, а по этому сообщению можно найти и его отправителя.
Чтобы минимизировать риск, автор вируса может отправить сообщение из какого-либо Интернет-кафе в другом городе. Он может принести вирус с собой на дискете и считать его самостоятельно или, если машины в Интернет-кафе не оборудованы устройствами чтения гибких дисков, попросить милую девушку за стойкой считать для него файл book.doc, чтобы он мог его распечатать. Получив его на свой жесткий диск, злоумышленник меняет расширение файла на .ехе и запускает его, заражая тем самым всю локальную сеть вирусом, который срабатывает не сразу, а две недели спустя (на тот случай, если полиция решит проверить списки всех авиапассажиров, посетивших этот город за последнюю неделю). Вместо гибкого риска можно использовать удаленный FTP-сайт или принести с собой лэптоп g подключить его к Ethernet или порту USB. Подобная услуга часто предоставляется в Интернет-кафе, чтобы туристы с лэптопами могли получать свою электронную почту каждый день.
Вирусы пытаются спрятаться, а пользователи пытаются их обнаружить, играя, таким образом, друг с другом в кошки-мышки. В данном разделе мы рассмотрим некоторые вопросы на эту тему. Чтобы вируса не было видно в каталоге, вирусы, хранящие свои данные в отдельном файле (вирусы-компаньоны, вирусы исходных текстов и т. д.), должны либо устанавливать у файла бит HIDDEN (скрытый) в системе Windows, либо имя файла должно начинаться с символа точки в системе UNIX. Более сложный подход состоит в модификации проводника системы Windows или программы ls в UNIX, чтобы они не отображали файлы, начинающиеся с определенной последовательности символов. Вирусы также могут прятаться в необычных и неожиданных местах, таких как дефектные секторы и списки дефектных секторов, а также реестре Windows (находящейся в памяти базе данных, в которой программы могут хранить различные текстовые строки). Флэш-ПЗУ и энергонезависимая память CMOS тоже могут использоваться, хотя механизм записи во флэш-ПЗУ достаточно сложен, а CMOS-память слишком мала. И конечно, основным местом, где прячутся вирусы, остаются исполняемые файлы и документы, хранящиеся на жестком диске.
Очевидно, среднестатистический пользователь вряд ли способен самостоятельно обнаружить вирусы, старающиеся изо всех сил спрятаться, поэтому на рынок постоянно поступает большое количество разнообразного антивирусного программного обеспечения. Ниже мы обсудим способы работы антивирусных программ. У компаний, занимающихся разработкой антивирусных программ, есть лаборатории, в которых ученые проводят долгие часы, выслеживая и исследуя новые вирусы. Первый шаг заключается в том, чтобы заразить вирусом программу, не выполняющую никаких функций, часто называемую козлом отпущения, и получить вирус в его чистейшей форме. Следующий шаг состоит в том, чтобы получить точный листинг кода вируса и поместить его в базу данных известных вирусов. Компании соревнуются друг с другом, пытаясь превзойти конкурента размерами базы данных. Изобретение новых вирусов просто с целью увеличения размеров базы данных считается неспортивным.
После установки на компьютере заказчика антивирусная программа сканирует все исполняемые файлы на диске, сравнивая их содержимое с хранящимися в ее базе данных штаммами известных вирусов. У большинства компаний, занимающихся разработкой антивирусных программ, есть свои web-сайты, с которых клиенты данных компаний могут скачать описания недавно обнаруженных вирусов в свои базы данных. Если у пользователя 10 000 файлов, а в базе данных хранятся данные о 10 000 вирусах, то чтобы такая программа работала быстро, требуется очень умное программирование.
Так как незначительные мутации уже известных вирусов появляются постоянно, антивирусная программа должна уметь распознавать вирус, несмотря на изменение в трех байтах. Однако такой способ поиска не только медленнее точного поиска, но он может привести к ложным тревогам, то есть антивирусная программа будет выдавать предупреждение о незараженных файлах, которые содержат кусок кода, смутно напоминающего вирус, обнаруженный в Пакистане 7 лет назад. Пользователь при этом получает сообщение типа
ВНИМАНИЕ! Файл xyz.exe, возможно, заражен вирусои lahore-9х. Удалить?
Чем больше вирусов в базе данных и чем шире критерии поиска, тем больше будет ложных тревог. Если их будет слишком много, пользователь просто перестанет запускать антивирусную программу. Но если сканирующая программа будет искать слишком точное соответствие, она может пропустить некоторые модифицированные вирусы. Найти золотую середину непросто. В идеальном случае лаборатория должна найти в вирусе некое неизменное ядро и использовать его для идентификации вируса.
Если антивирусная программа не нашла на диске вирусов на прошлой неделе, то это не означает, что их на нем нет сейчас, поэтому сканировать диск антивирусной программой следует регулярно. Поскольку процесс сканирования занимает много времени, существенно эффективнее проверять только те файлы, которые были изменены с момента последнего сканирования. Недостаток такого подхода в том, что умный вирус обязательно сохранит дату заражаемого им файла, чтобы избежать обнаружения. Антивирусная программа может проверить дату последнего изменения каталога, в котором хранится файл, Вирус может ответить на это сохранением также даты каталога. Игра в кошки-мышки продолжается.
Антивирусная программа для обнаружения изменения файлов может сохранять в своем файле на диске длины всех файлов. Если размер файла увеличился с момента последней проверки, это может означать, что он заражен, как показано на рис, 9.10, а и рис. 9.10, б. Однако умный вирус может перехитрить антивирусную программу, сжав инфицированный файл и добавив к сжатому файлу самого себя и дополнив длину файла до оригинального значения. Чтобы эта схема могла работать, вирус должен содержать процедуры сжатия и декомпрессии, как показано на рис, 9.10, в.
Рис. 9.10. Программа (а); инфицированная программа (б); сжатая инфицированная программа (в); зашифрованный вирус (г); сжатый вирус с зашифрованной программой компрессии (д)
Другой метод избежания обнаружения заключается в попытке сделать так, чтобы внешний вид вируса отличался от его представления в базе данных. Один из способов достижения этой цели заключается в том, что вирус, заражая файл, зашифровывает сам себя в этом файле, причем каждый раз используется новый ключ. Прежде чем создать новую копию, вирус формирует случайный 32-разрядный ключ шифрования, например складывая по модулю 2 текущее время с содержимым некоторых слов памяти, скажем, 72 008 и 319 992. Затем с этим ключом также по модулю 2 складывается, слово за словом, весь код вируса. (Зашифрованное тело вируса показано темно-серым цветом на рис. 9.10, г.) Ключ шифрации-дешифрации хранится в самом файле. С точки зрения секретности помещение ключа в тот же файл не является идеальным решением, но цель здесь заключается в том, чтобы обмануть антивирусную программу, а не скрыть от исследователей-вирусологов детали реализации вируса. Конечно, чтобы работать, вирус должен сначала расшифровать себя, поэтому он также должен хранить в файле и процедуру дешифрации.
Эта схема все еще не совершенна, так как во всех копиях вируса будут храниться одинаковые процедуры компрессии, декомпрессии, шифрации и дешифрации, так что антивирусная программа может искать вирус по этим процедурам. Скрыть процедуры компрессии, декомпрессии и шифрации несложно: их можно зашифровать вместе с телом самого вируса (рис. 9 10, д). Однако процедура дешифрации сама не может быть зашифрована. Она должна быть в готовом к употреблению виде, чтобы расшифровать все остальные части вируса. Антивирусные программы это знают, и поэтому они охотятся за процедурой дешифрации.
Однако борьба на этом не заканчивается, поэтому автор вируса поступает следующим образом. Предположим, что процедуре дешифрации требуется выполнить следующие вычисления:
X = (A + B + C - 4)
Один из простейших вариантов ассемблерной программы, реализующей эту формулу для некоего двухадресного компьютера, приведен в листинге 9.5, а, Первый адрес в команде процессора - источник, второй - приемник, так что команды MOV A, R1 загружает содержимое переменной A в регистр процессора R1. Программа в листинге 9.5, б выполняет те же действия, но не столь эффективно, так как между полезными операциями вставлена команда NOP (No OPeration - нет операции),
Листинг 9.5. Примеры полиморфного вируса
MOV A,R1 MOV A,R1 MOV A,R1 MOV A,R1 MOV A,R1 ADD B,R1 NOP ADD #0,R1 OR R1,R1 TST R1 ADD C,R1 ADD B,R1 ADD B,R1 ADD B,R1 ADD C,R1 SUB #4,R1 NOP OR R1,R1 MOV R1,R5 MOV R1,R5 MOV R1,X ADD C,R1 ADD C,R1 ADD C,R1 ADD B,R1 NOP SHL #0,R1 SHL R1,0 CMP R2,R5 SUB #4,R1 SUB #4,R1 SUB #4,R1 SUB #4,R1 NOP JMP .+1 ADD R5,R5 JMP .+1 MOV R1,X MOV R1,X MOV R1,X MOV R1,X MOV R5,Y MOV R5,Y (а) (б) (в) (г) (д)
Таким образом, существует масса способов сокрытия дешифрующей процедуры. Вместо команды NOP можно использовать самые разнообразные команды, не влияющие на ход вычислений. Например, можно прибавить 0 к какому-либо регистру, выполнить операцию логического ИЛИ для какого-либо регистра с самим собой; сдвинуть регистр влево на 0 разрядов, передать управление на следующую команду, сравнить содержимое регистров и т. д. Таким образом, программа в листинге 9.5, в функционально та же самая, что и в листинге 9.5, а. Копируя себя, вирус может использовать листинг 9.5, в вместо листинга 9.5, а и продолжать работать. Вирус, мутирующий при каждой операции копирования, называется полиморфным вирусом.
Теперь предположим, что регистр R1 не используется в данном участке программы. Тогда листинг 9.5, г также эквивалентен листингу 9.5, а. Наконец, во многих случаях команды могут выполняться в другом порядке, в результате чего мы получаем еще один вариант данной процедуры (листинг 9.5, д). Часть вируса, занимающаяся изменением внешнего вида последовательности команд процессора, не меняя при этом их функциональности, называется мутационным движущим механизмом. Подобная процедура обязательно содержится в сложных вирусах, что позволяет им успешно мимикрировать. Сам мутационный механизм может быть спрятан при помощи шифрации вместе с остальными частями вируса.
Пытаться научить антивирусную программу распознавать функционально эквивалентные процедуры теоретически возможно, но практически не реально, так как это очень сильно замедлит сканирование файлов. Следует помнить, что существует очень много вариантов функционально одной и той же процедуры и если даже антивирусная программа сможет анализировать участки кода и моделировать операции с регистрами, при тысячах типов вирусов и тысячах файлов на диске у программы будет очень мало времени на тестирование, или она будет работать страшно медленно.
Отметим, что сохранение содержимого регистра R5 в ячейке Y было добавлено к процедуре (см. листинг 9.5, д), чтобы анализирующей программе было труднее определить, что все операции с этим регистром представляют собой мертвую программу, то есть они не выполняют ничего полезного. Если в других участках программы есть обращения к переменной Y, тогда этот кусок программы будет выглядеть вполне правдоподобным. Хорошо написанный мутационный механизм, формирующий правдоподобный и разнообразный полиморфный код, может стать кошмаром для создателей антивирусного программного обеспечения. Единственное утешение состоит в том, что подобный механизм довольно трудно написать, поэтому создатели вирусов, как правило, используют уже кем-то написанный ранее мутационный механизм. А это означает, что в обороте различных механизмов не так уж и много.
До сих пор мы обсуждали тему обнаружения вирусов в инфицированных исполняемых файлах. Помимо этого антивирусный сканер должен проверить главную загрузочную запись, загрузочные секторы, список дефектных блоков, флэш-П3У, CMOS-память и т. д. Но что если в памяти находится резидентный вирус? Он не будет обнаружен. Будет еще хуже, если представить себе, что работающий резидентный вирус перехватывает все системные вызовы. Он легко сможет определить, что антивирусная программа считывает загрузочный сектор, проверяя его на вирусы. Чтобы обмануть антивирусную программу, вирусу нужно не обращаться к системному вызову. Вместо этого он считывает настоящий загрузочный сектор, хранящийся в укромном месте (например, в списке дефектных блоков). Он также завязывает себе узелок на память, чтобы не забыть снова заразить все файлы, когда антивирусный сканер завершит свою работу.
Чтобы не быть обманутой вирусом, антивирусная программа могла бы напрямую обращаться к диску, минуя системные вызовы операционной системы. Однако для этого потребуется наличие в антивирусной программе встроенных драйверов устройств для IDE, SCSI и других дисков, что снизит переносимость антивирусной программы с машины на машину. Более того, в то время как обойти операционную систему для чтения загрузочного сектора возможно, обойтись без нее для чтения всех исполняемых файлов нельзя. Возникает опасность, что вирус сможет также обманывать антивирусную программу, подавая ей искаженные сведения об исполняемых файлах [Эту проблему можно решить, загрузившись не с проверяемого жесткого диска, а, например, с CD-ROM или другого жесткого диска. Неясно только, что делать, если вирус заразит BIOS во флэш-ПЗУ. - Примеч. перев.].
Принципиально другой метод обнаружения вирусов заключается в проверке целостности. Антивирусная программа, работающая подобным образом, сначала сканирует жесткий диск в поисках вирусов. Убедившись, что диск чист, она считает контрольную сумму для каждого исполняемого файла и сохранит список контрольных сумм для всех исполняемых файлов каталога в том же каталоге в файле checksum. При следующем запуске она пересчитывает все контрольные суммы и проверяет их соответствие данным, хранящимся в файле checksum. Зараженный файл будет тут же обнаружен по несовпадению контрольной суммы.
Проблема данного подхода состоит в том, что авторы вирусов не собираются сидеть сложа руки. Они могут написать вирус, удаляющий файл с контрольными суммами. Что еще хуже, можно написать вирус, считающий такую контрольную сумму заново и заменяющий старое значение в файле checksum новым. Чтобы защититься от подобной атаки, антивирусная программа может попытаться спрятать файл контрольных сумм, но такой подход вряд ли будет долго работать, так как авторы вирусов обязательно тщательно изучат антивирусную программу. Лучший подход заключается в шифровании файла контрольных сумм. В идеале при шифровании должна использоваться смарт-карта с ключом, хранящимся вне компьютера, чтобы программы не могли до него добраться.
Другая стратегия, используемая антивирусным программным обеспечением, состоит в проверке поведения программ. При этом антивирусная программа резидентно находится в памяти во время работы компьютера и сама перехватывает все системные вызовы. Идея такого подхода состоит в том, что таким образом антивирусная программа может отслеживать всю активность системы и перехватывать все, что кажется ей подозрительным. Например, ни одна нормальная программа не должна пытаться перезаписать загрузочный сектор, поэтому такие попытки почти наверняка свидетельствуют о деятельности вируса. Изменения содержимого флэш-ПЗУ тоже являются крайне подозрительными.
Но есть множество случаев не столь очевидных. Например, перезапись исполняемого файла необычна, если только это делает не компилятор. Если антивирусная программа обнаруживает подобное действие, она может издать предупреждение в расчете на то, что пользователь знает, должен ли данный файл переписываться, Если редактор Word перезаписывает файл с расширением .doc новым документом, полным макросов, это не обязательно свидетельствует об активности вируса. В системе Windows программы могут отделяться от своих исполняемых файлов и становиться резидентными при помощи специального системного вызова. Опять же, зто действие может быть законным, но предупреждение стоит выдать.
Вирусы не обязательно должны спокойно сидеть и ждать, пока антивирусная программа их не убьет. Они могут сражаться. Особенно захватывающие сражения могут начаться при встрече резидентного вируса с резидентной антивирусной программой. Много лет назад программисты любили игру, называемую Core Wars (войны в памяти), в которой два программиста одновременно запускали по одной программе в общее свободное адресное пространство. Программы поочередно обращались к памяти, пытаясь определить местонахождение противника и уничтожить ero прежде, чем он сделает то же самое. Сражение между вирусом и антивирусной программой выглядит похоже на эту игру, с той разницей, что местом битвы является компьютер бедного пользователя, который совсем не желает, чтобы это происходило именно на его машине. Что еще хуже, у вирусов в этой схватке есть преимущество: антивирусные программы, в отличие от вирусов, распространяются открыто, и создатели вирусов могут приобрести любую антивирусную программу для ее изучения. Конечно, как только появляется новый вирус, команды создателей антивирусных программ тут же модифицируют свои программы, вынуждая авторов вирусов добывать новые копии антивирусных программ.
У каждой хорошей истории должна быть мораль. Мораль данной истории следующая:
Лучше предохраняться, чем потом сожалеть.
Постараться избежать заражения вирусом значительно проще, чем пытаться затем отыскать его на зараженном компьютере. Ниже приводится несколько советов, полезных для индивидуальных пользователей, а также обсуждаются действия, которые вся индустрия в целом может предпринять, чтобы значительно снизить остроту данной проблемы.
Что могут сделать пользователи, чтобы избежать заражения вирусом? Во-первых, выбрать операционную систему, предоставляющую определенный уровень защиты, со строгим разграничением режимов работы ядра и пользователя, а также раздельными паролями регистрации для каждого пользователя и системного администратора. При таких условиях, даже если какой-либо пользователь случайно занесет вирус в систему, этот вирус не сможет заразить системные двоичные файлы.
Во-вторых, устанавливайте только архивированное программное обеспечение, приобретенное у надежного производителя. Хотя даже это не гарантирует стопроцентного отсутствия вирусов, так как были случаи, когда рассерженные сотрудники фирмы распространяли вирусы в коммерческом программном обеспечении, тем не менее зто значительно помогает. Загрузка программного обеспечения с web-сайтов и BBS весьма рискованна.
В-третьих, приобретите хорошее антивирусное программное обеспечение и используйте его так, как написано в инструкции. Обязательно получайте регулярные обновления с web-сайтов производителя.
В-четвертых, не щелкайте мышью на присоединенных к электронным письмам файлах и скажите, чтобы вам не присылали такие файлы. Электронная почта в виде простого ASCII-текста всегда безопасна, но вложенные файлы могут быть опасны.
В-пятых, архивируйте почаще ключевые файлы на внешних носителях, таких как гибкие диски, CDR или на магнитной ленте. Храните несколько последовательных версий каждого файла на разных внешних дисках. Тогда, если вы обнаружите вирус, у вас появляется шанс восстановить файлы. Заархивированный вчера уже зараженный файл не поможет, а вот версия недельной давности может оказаться полезной.
Компьютерная промышленность также должна серьезно относиться к вирусной угрозе и изменить некоторые свои схемы поведения, представляющие опасность. Во-первых, следует производить простые операционные системы. Чем больше в операционной системе всяких прибамбасов, тем больше дыр в системе безопасности. Это медицинский факт.
Во-вторых, не применяйте активное содержимое документов. С точки зрения безопасности это катастрофа. Для просмотра присланного видеосервером документа не должна запускаться содержащаяся в документе программа. Например, JPEG-файлы не содержат программ и поэтому не могут содержать вирусов. Все документы должны работать подобным образом.
В-третьих, должен быть способ избирательно устанавливать защиту записи на цилиндры определенного диска, чтобы вирусы не могли заразить программы хранящиеся в этих цилиндрах. Подобная защита может быть реализована с помощью битового массива в контроллере, в котором перечисляются все защищенные цилиндры. Изменение содержимого этого битового массива должно разрешаться только тогда, когда пользователь переключил механический переключатель на передней панели компьютера.
В-четвертых, флэш-ПЗУ представляет собой прекрасную идею, но запись в него также должна разрешаться только при определенном положении механического переключателя, что может сделать пользователь, устанавливая новую версию BIOS. Само собой, ни одно из этих предложений не будет восприниматься всерьез, пока действительно большой жареный вирусный петух нас всех не клюнет. Например, обнулив все банковские счета во всем мире. Хотя тогда что-либо предпринимать будет уже поздно.
При обнаружении вируса компьютер следует немедленно остановить, так как резидентный вирус может все еще работать. Компьютер следует перезагрузить с CD-ROM или гибкого диска, на котором всегда должна быть установлена защита от записи. На этом диске должна содержаться полная операционная система, чтобы не использовать при загрузке жесткий диск с его загрузочным сектором, копией операционной системы и драйверами, которые могут быть инфицированы. Затем с оригинального CD-ROM следует запустить антивирусную программу, так как версия программы, хранящаяся на жестком диске, также может быть заражена.
Антивирусная программа может обнаружить некоторые вирусы и может даже устранить их, но нет никакой гарантии, что она найдет их все. Вероятно, самый надежный метод заключается в том, чтобы сохранить на внешнем носителе все файлы, которые не могут содержать вирусов (например, ASCII и JPEG-файлы). Те файлы, которые могут содержать вирусы (например, документы редактора Word), должны быть преобразованы в другой формат, который не может содержать вирусы, скажем, в текст ASCII (или, по крайней мере, следует удалить все макросы). 3атем жесткий диск следует переформатировать программой форматирования, загруженной с защищенного от записи гибкого диска или CD-ROM, чтобы гарантировать, что сама программа форматирования не заражена вирусом. Особенно важно, чтобы главная загрузочная запись и загрузочные секторы были полностью стерты. Затем следует переустановить операционную систему с оригинального CD-ROM. Когда вы имеете дело с вирусом, не бойтесь прослыть параноиком.
Первый случай масштабного прорыва системы безопасности компьютеров, подключенных к Интернету, произошел 2 ноября 1988 года, когда аспирант университета Корнелла в штате Нью-Йорк Роберт Таппан Моррис выпустил написанного им червя в Интернет. В результате этого действия были заражены тысячи компьютеров в университетах, корпорациях и правительственных лабораториях по всему миру, прежде чем эту программу удалось выследить и удалить. Кроме того, результатом этих событий явился спор, не стихающий до сих пор. Мы обсудим ниже подробности этих событий. Дополнительные технические подробности описаны в [310]. Та же история, но в жанре полицейского триллера рассказана в [141].
История началась с того, что 1988 году Моррис обнаружил две ошибки в операционной системе Berkley UNIX, позволяющие получить несанкционированный доступ к компьютерам по всему Интернету. В одиночку он написал саморазмножающуюся программу, называемую червем, использующую эти ошибки и в течение секунд реплицирующую себя на каждой машине, к которой ей удается получить доступ. Он работал над этой программой несколько месяцев, тщательно настраивая ее и пытаясь научить программу заметать следы.
Неизвестно, была ли версия от 2 ноября 1988 года тестовой или окончательной. В любом случае она поставила на колени большинство систем Sun и VAX по всему Интернету за какие-то несколько часов после попадания в сеть. Мотивация Moppиca не ясна, хотя он, возможно, предполагал всего лишь пошутить, но в результате программной ошибки ситуация вышла из-под контроля.
Технически червь состоял из двух программ: начального загрузчика и собственно червя. Начальный загрузчик представлял собой 99 строк на языке C (файл назывался l1.с). Этот загрузчик компилировался и исполнялся на атакуемом компьютере. Будучи запущенным, он связывался с машиной, с которой был загружен, загружал основного червя и запускал его. После некоторых действий, направленных на попытки скрыть свое существование, червь заглядывал в таблицы маршрутизации нового хоста, определяя компьютеры, с которыми был соединен хост, после чего пытался распространить начальный загрузчик на эти машины.
Для инфицирования новых машин применялись три метода. Метод 1 заключался в попытке запустить удаленную оболочку при помощи команды rsh. Некоторые компьютеры доверяют другим компьютерам и позволяют запускать rsh, не требуя никакой аутентификации. Если это срабатывало, удаленная оболочка загружала червя и продолжала заражать новые машины.
Метод 2 использовал программу, присутствующую на всех системах BSD, называемую finger. Она позволяет пользователю в Интернете ввести команду
finger name@site
чтобы отобразить информацию о владельце или администраторе конкретного компьютера. Эта информация обычно включает физическое имя, регистрационное имя, домашний адрес, телефон, имя и номер телефона секретаря, номер факса и т. д. То есть это электронный эквивалент телефонной книги.
Программа finger работает следующим образом. На каждом BSD-сайте работает фоновый процесс, называющийся finger daemon, отвечая на запросы, поступающие со всего Интернета. Червь обращался к программе finger со специально разработанной 536-байтовой строкой в качестве параметра. Эта строка вызывала переполнение буфера демона и попадала в его стек, как было показано на рис. 9.6, в. В данном случае использовалось отсутствие проверки на переполнение буфера. Когда процедура демона возвращала управление, она попадала не в головной модуль, а в процедуру, находящуюся внутри 536-байтовой строки в стеке. Эта процедура пыталась запустить программу sh. Если это ей удавалось, червь получал оболочку, работающую на атакуемой машине.
Метод 3 использовал ошибку в почтовой системе sendmail, позволявшей червю послать по почте копию начального загрузчика и запустить его.
Попав в систему, червь пытался взломать систему паролей. Для этого Моррису не понадобилось предпринимать собственных исследований. Все, что ему потребовалось, - это попросить у собственного отца, эксперта в области безопасности в Управлении национальной безопасности США, профессионально занимающемся взломом кодов, перепечатку классической статьи, написанной десятилетием раньше Моррисом старшим и Кеном Томпсоном в лаборатории Bell Labs [240], Каждый взломанный пароль позволял червю зарегистрироваться на любой машине, на которой у владельца пароля были учетные записи.
Каждый раз, когда червь получал доступ к новой машине, он проверял, есть ли уже другие активные копии червя на этой машине. Если червь уже был на этой машине, то новая копия прекращала свою деятельность, кроме одного случая ив семи, в котором она продолжал работать, чтобы червь мог продолжать распространяться, даже если системный администратор запустил свою версию червя, чтобы обмануть настоящего червя. Использование соотношения 1 к 7 оказалось слишком большим и привело к тому, что зараженные машины настолько заполнились червями, что просто не могли работать. Если бы Моррис не делал исключений для каждого седьмого случая, червь, возможно, до сих пор жил бы в Интернете, никем не обнаруженный.
Морриса поймали, когда один из его друзей разговаривал с репортером из компьютерной редакции Нью-Йорк Таймс, Джоном Марковым, и пытался убедить репортера, что все это лишь несчастный случай, что червь безобиден и автор весьма сожалеет. Друг по неосторожности упомянул, что регистрационное имя нарушителя rtm. Преобразовать rtm в физическое имя владельца было несложно - все, что Маркову надо было сделать, - это запустить процедуру finger. На следующий день эта история оказалась на первых полосах всех газет, вытеснив оттуда даже информацию о предстоящих через три дня президентских выборах.
Моррис предстал перед федеральным судом и был приговорен к штрафу в размере 10 000 долларов, трем годам испытательного срока и 400 часам общественных работ. Его судебные издержки, вероятно, превысили 150 000 долларов. Приговор породил множество разногласий. В компьютерном обществе многие считали, что Моррис был блестящим студентом, чья опасная шалость вышла из-под контроля. Написанная им программа не содержала ничего, что бы свидетельствовало о намерениях Морриса украсть какие-либо данные или причинить какой-либо намеренный ущерб. Другие считали его серьезным преступником, которому место в тюрьме.
Одним из результатов этого инцидента было создание группы компьютерной "скорой помощи" CERT (Computer Emergency Rresponse Team), основными задачами которой являются доклады о попытках взлома в Интернете, а также анализ проблем безопасности и разработка методов их решения. При необходимости эта группа рассылает свою информацию тысячам системных администраторов по Интернету. К сожалению, этой информацией, содержащей сообщения об ошибках в системах, могут воспользоваться также и злоумышленники (возможно, притворяющиеся системными администраторами) и использовать часы (или даже дни), требующиеся на устранение обнаруженных ошибок.
ББК 32.973-018.2 УДК 681.3.066 T18 T18 Современные операционные системы. 2-е изд. / Э. Таненбаум -- СПб.: Питер, 2004. -- 1040 с.: ил. ISBN 5-318-00299-4 Это с нетерпением ожидаемое, переработанное и исправленное издание всемирного бестселлера включает в себя сведения о последних достижениях в области технологий операционных систем. Книга построена на примерах и содержит информацию, необходимую для понимания функционирования современных операционных систем. Благодаря практическому опыту, приобретенному при разработке нескольких операционных систем, и высокому уровню знания предмета Эндрю Таненбаум смог ясно и увлеченно рассказать о сложных вещах. В книге приводится множество важных подробностей, которых нет ни в одном другом издании. ББК 32.973-018.2 УДК 681.3 Информация, содержащаяся в данной книге, получена из источников, расмматриваемых издательством как надежные. Тем не менее, имея в виду возможные человеческие или технические ошибки, издательство не может гарантировать абсолютную точность и полноту приводимых сведений и не несет ответственности за возможные ошибки, связанные с использованием книги. © Prentice Hall, Inc., 2001 ISBN 0-13-031358-0 (англ.) © Перевод на русский язык ЗАО Издательский дом "Питер", 2002 ISBN 5-318-00299-4 © Издание на русском языке, оформление, ЗАО Издательский дом "Питер", 2004 Перевел на русский язык А. Леонтьев Главный редактор Е. Строганова Заведующий редакцией И. Корнеев Руководитель проекта А. Васильев Литературный редактор Е. Ваулина Художник Н. Биржаков Иллюстрации В. Шендерова Корректор В. Листова Верстка Р. Гришанов[Вернуться к списку] [Комментарии (0)]