Жизненный цикл червей — HackZona.Ru

Жизненный цикл червей

Жизненный цикл червей

Тип статьи:
Со старой ХакЗоны.
Червь придет обязательно?
Обязательно.
Френк Херберт, «Дюна»

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

Чтобы одолеть червя, вы должны знать структуру его программного кода, основные повадки, наиболее вероятные алгоритмы внедрения и распространения. Сеть Интернет в целом и операционные системы в частности это настоящий лабиринт, и вам понадобится его подробная карта с отметками секретных троп и черных ходов, используемых червями для скрытого проникновения в нервные узлы жертвы. Все это и много другое вы найдете в статье
«Жизненный цикл червей»

инициализация, или несколько слов перед введением

В те минуты, когда пишутся эти строки, в левом нижнем углу компьютера лениво мигает глазок персонального брандмаузера, фильтрующего пакеты, приходящие по сотовому телефону через GPRS (между прочим, очень хорошая штука рекомендую!). Эпизодически не чаще чем три-пять раз в день — в систему пытается проникнуть червь Love San (или что-то очень на него похожее), и тогда брандмаузер выбрасывает на экран следующее окно (см. рис. 1). Та же самая картина наблюдается и у двух других моих провайдеров.

И хотя активность червя неуклонно снижается (пару месяцев назад атака происходила буквальные каждый час-полтора), до празднования победы еще далеко. Червь жил, живет и будет жить! Вызывает уважение тот факт, что автор червя не предусмотрел никаких деструктивных действий, в противном случае ущерб оказался невосполнимым, и всей земной цивилизации сильно поплохело бы.

А сколько дыр и червей появится завтра? Было бы наивно надеяться, что этой статьей можно хоть что-то исправить, поэтому после долгих колебаний, сомнений и размышлений я решил ориентировать ее не только на системных администраторов, но и на вирусописателей. А что, давал же Евгений Касперский советы авторам вирусов, предваряя свою статью такими словами: «Успокойтесь! Не надо готовить ругательства или, наоборот, потирать руки. Мы не хотим делиться своими идеями с авторами компьютерных вирусов. Все значительно проще через наши руки прошло несколько сотен образцов компьютерных животных, и слишком часто в них встречались одни и те же ошибки. С одной стороны, это хорошо такие вирусы часто оказываются „маложивущими“, но с другой стороны, малозаметная ошибка может привести к несовместимости вируса и используемого на компьютере программного обеспечения. В результате вирус „вешает“ систему, компьютер отдыхает, а пользователи мечутся в панике с криками: „Пусть хоть 100 вирусов, лишь бы компьютер работал!!!“ (завтра сдавать заказ, не запускается самая любимая игрушка, компилятор виснет при выходе в DOS и т. п.). И все это происходит при заражении довольно безобидным вирусом. По причине этого и возникло желание поделиться некоторой информацией о жизни вируса в компьютере, дабы облегчить жизнь и вам, и многочисленным „пользователям“ ваших вирусов»

Черви, если только в них не заложены деструктивные возможности, не только вредны, но и полезны. Вирусы — это вообще юношеская болезнь всех или практически всех программистов. Что ими движет? Желание навредить? Стремление самоутвердиться в чьих-то глазах? А может быть простой познавательный интерес? Разумеется, если червь положил весь Интернет, его создатель должен ответить. Данная статья не самоучитель по написанию червей. Скорее, это детальный анализ ошибок, допущенных вирусописателями.

Я не призываю вас писать червей. Напротив, я призываю одуматься и не делать этого. Но, если уж вам действительно невтерпеж, пишите тогда по крайней мере так, чтобы ваше творение не мешало жить и трудиться всем остальным. Аминь!

Рисунок 1 кто-то упорно ломиться на 135 порт, содержащий уязвимость

введение, или превратят ли черви сеть в компост?

А-а, черви. Я должен как-нибудь увидеть одного из них.
Может быть, вы и увидите его сегодня.

Френк Херберт, «Дюна»

Рисунок 2 черви атакуют! и ни что не сможет ни остановить, ни сбить их с пути

Если кто и разбирается в червях, так это Херберт. Ужасные создания, блестяще описанные в «Дюне», и вызывающие у читателей смесь страха с уважением, они действительно во многом похожи на одноименных обитателей кибернетического мира. И пока специалисты по информационной безопасности ожесточенно спорят, являются ли черви одним из подклассов вирусных программ или же образуют вполне самостоятельную группу вредоносных «организмов», черви успели перепахать весь Интернет и продолжают зарываться в него с бешеной скоростью. Удалить же однажды зародившегося червя практически невозможно. Забудьте о Черве Морриса! Сейчас не то время, не те пропускные способности каналов и не та квалификация обслуживающего персонала. В далеких восьмидесятых с заразой удалось справиться лишь благодаря небольшой (по современным меркам!) численности узлов сети и централизованной организации структуры сетевого сообщества.

А что мы имеем сейчас? Количество узлов сети вплотную приближается к четырем миллиардам, причем подавляющим большинством узлом управляют совершенно безграмотные пользователи, и лишь незначительная часть сетевых ресурсах находится в руках администраторов, зачастую являющихся все теми же безграмотными пользователями, с трудом отличающими один протокол от другого и во всем полагающимися на Microsoft и NT, которая «все за них сделает». Что такое заплатки некоторые из них, возможно, и знают, но до их установки дело, так или иначе, сплошь и рядом не доходит.

Можно до потери пульса проклинать Святого Билла и его корявое программное обеспечение, но проблема вовсе не в дырах, а в халатном отношении к безопасности и откровенном разгильдяйстве администраторов. Что касается программистских ошибок, то в мире UNIX ситуация обстоит ничуть не лучшим образом. Здесь тоже водятся черви, пускай не впечатляющие численностью своих штаммов, зато отличающиеся большой изощренностью и разнообразием. Здесь также случаются вспышки эпидемий, насчитывающие тысячи и даже десятки тысяч жертв (достаточно вспомнить червей Scalper'а и Slapper'a, поражающих Apache-сервера, вращающиеся под управлением FreeBSD и Linux соответственно). Конечно, по сравнению с миллионами упавших Windows-систем эти цифры выглядят более чем умеренными, однако легендарная защищенность (точнее как раз таки незащищенность) UNIX'а тут совсем не причем. Просто UNIX-системы управляются намного более грамотными операторами, чем Windows NT.

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

структурная анатомия червя

Те экземпляры червей, которые мы изучали, заставили нас предполагать, что внутри них происходит сложный химический обмен.

Френк Херберт, «Дюна»

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

Нора, прорытая вирусом в системе, обычно оказывается слишком узка, чтобы вместить всего червяка целиком. Ну разве что это будет совсем крохотный и примитивный вирус, поскольку ширина типичной норы измеряется десятками или в лучшем случае сотнями байт. Поэтому сначала на атакуемую машину проникает лишь небольшая часть вируса, называемая головой или загрузчиком, которая и подтягивает основное тело червя. Собственно говоря, голов у вируса может быть и несколько. Так, достопочтенный вирус Морриса имел две головы, одна из которых пролезала через отладочный люк в sendmail, а другая проедала дыру в finger'е, поэтому создавалось обманчивое впечатление, что сеть атакуют два различных червя. Естественно, чем больше голов имеет вирус, тем он жизнеспособнее. Современные черви в своем подавляющем большинстве обладают одной-единственной головой, однако из этого правила случаются и исключения. Так, при дизассемблерном вскрытии червя Nimda (слово «admin», читаемое задом наперед) на его теле было обнаружено пять голов, атакующих клиентов электронной почты, shared-ресурсы, Web-браузеры, MS IIS-сервера и backdoor'ы, оставленные вирусом Code Red. Такие многоголовые монстры скорее напоминают сказочных драконов или гидр, поскольку червь с несколькими головами смотрится прямо так скажем жутковато, но в кибернетическим мире свои законы.

Вирусный загрузчик (обычно отождествляемый с shell-кодом, хотя это не всегда так) решает по меньшей мере три основные задачи: во-первых, он адаптирует свое тело (и при необходимости основное тело червя) к анатомическим особенностям организма жертвы, определяя адреса необходимых ему системных вызовов, свой собственный адрес размещения в памяти, текущий уровень привилегий и т. д. Во-вторых, загрузчик устанавливает один или несколько каналов связи с внешним миром, необходимых для транспортировки основного тела червя. Чаще всего для этого используется TСP/IP-соединение, однако червь может воспользоваться услугами FTP- и/или POP3/SMTP-протоколов, что особенно актуально для червей, пытающихся проникнуть в локальные сети, со всех сторон огороженные сплошной стеной Firewall'ов. В-третьих, загрузчик забрасывает хвост вируса на зараженный компьютер, передавая ему бразды правления. Для сокрытия факта своего присутствия загрузчик может восстановить разрушенные структуры данных, удерживая систему от падения, а может поручить это основному телу червя. Выполнив свою миссию, загрузчик обычно погибает, поскольку включить в тело вируса копию загрузчика с инженерной точки зрения намного проще, чем собирать вируса по частям.

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

Впрочем, червь может вести и кочевую жизнь, автоматически удаляя себя из системы по прошествии некоторого времени это добавляет ему скрытности и значительно уменьшает нагрузку на сеть. При условии, что поражаемый сервис обрабатывает каждое TCP/IP соединение в отдельном потоке (а в большинстве случаев дело обстоит именно так), червю будет достаточно выделить блок памяти, присвоить ему атрибут исполняемого и скопировать туда свое тело (напрямую перебросить хвост в адресное пространство потока жертвы нельзя, т. к. сегмент кода по умолчанию защищен от записи, а сегмент данных по умолчанию запрещает исполнение{[1]}, остается стек и куча; стек чаще всего исполняем по дефлоту, а куча нет, и для установки атрибута Executable червю приходится химичить с системными функциями менеджера виртуальной памяти). Если же голова червя получает управление до того, как уязвимый сервис создаст новый поток или успеет расщепить процесс вызовом fork, червь должен обязательно возвратить управление программе-носителю, в противном случае та немедленно ляжет и получится самый натуральный DoS. При этом полный возврат управления предполагает потерю власти над машиной, а значит и смерть червя. Чтобы не уронить систему, но и не лишиться жизни самому, червь должен оставить свою резидентную копию или, в более общем случае, модифицировать систему так, чтобы хотя бы изредка получать управление. Это легко. Первое, не самое удачное, зато элементарно реализуемое решение заключается в создании нового файла с последующим добавлением его в список автоматически запускаемых программ. Более изощренные черви внедряют свое тело в подложную динамическую библиотеку и размещают ее в текущем каталоге уязвимого приложения (или просто в каталоге любого более или менее часто запускаемого приложения). Еще червь может изменить порядок загрузки динамических библиотек или даже назначить существующим динамическим библиотекам подложные псевдонимы (в ОС семейства Windows за это отвечает следующий раздел реестра: HKLMSYSTEMCurrentControlSetControlSession ManegerKnownDLLs). Сильно извращенные черви могут регистрировать в системе свои ловушки (hocks), модифицировать таблицу импорта процесса-носителя, вставлять в кодовый сегмент команду перехода на свое тело (разумеется, предварительно присвоив ему атрибут Writable), сканировать память в поисках таблиц виртуальных функций и модифицировать их по своему усмотрению (внимание: в мире UNIX большинство таблиц виртуальных функций располагаются в области памяти, доступной лишь на чтение, но не на запись).

Короче говоря, возможных путей здесь не по-детски много, и затеряться в гуще системных, исполняемых и конфигурационных файлов червю ничего не стоит. Попутно отметим, что только самые примитивные из червей могут позволить себе роскошь создания нового процесса, красноречиво свидетельствующего о наличии посторонних. Печально известный Love San, кстати, относится именно к этому классу. Между тем, используя межпроцессорные средства взаимодействия, внедриться в адресное пространство чужого процесса ничего не стоит, равно как ничего не стоит заразить любой исполняемый файл, в том числе и ядро системы. Кто там говорит, что операционные системы класса Windows NT блокируют доступ к запущенным исполняемым файлам? Выберете любой понравившийся вам файл (путь для определенности это будет iexplore.exe) и переименуйте его в iexplore.dll. При наличии достаточно уровня привилегий (по умолчанию это привилегии администратора) операция переименования завершается успешно, и активные копии Internet Explorer'а автоматически перенаправляются системой к новому имени. Теперь создайте подложный iexplore.exe-файл, записывающий какое-нибудь приветствие в системный журнал и загружающий оригинальный Internet Explorer. Разумеется, это только демонстрационная схема. В реальности все намного сложнее, но вместе с тем и интереснее! Впрочем, мы отвлеклись. Вернемся к нашему вирусу, в смысле — к червю.

Укрепившись в системе, червь переходит к самой главной фазе своей жизнедеятельности фазе размножения. При наличии полиморфного генератора, вирус создает совершенно видоизмененную копию своего тела, ну или, на худой конец, просто зашифровывает критические сегменты своего тела. Отсутствие всех этих механизмов оставляет червя вполне боевым и жизнеспособным, однако существенно сужает ареал его распространения. Судите сами, незашифрованный вирус легко убивается любым сетевым фильтром, как-то брандмаузером или маршрутизатором. А вот против полиморфных червей адекватных средств борьбы до сих пор нет, и сомнительно, чтобы они появились в обозримом будущем. Распознание полиморфного кода эта не та операция, которая может быть осуществлена в реальном времени на магистральных Интернет-каналах. Соотношение пропускной способности современных сетей к вычислительной мощности современных же процессоров явно не в пользу последних. И хотя ни один полиморфный червь до сих пор не замечен в «живой природе», нет никаких гарантий, что такие вирусов не появятся и впредь. Локальных полиморфных вирусов на платформе Intel IA-32 известен добрый десяток (речь идет о подлинном полиморфизме, а не тривиальном замусоривании кода незначащими машинными командами и иже с ними), как говориться — выбирай не хочу.

Но какой бы алгоритм червь не использовал для своего размножения, новорожденные экземпляры покидают родительское гнездо и расползаются по соседним машинам, если, конечно, им удастся эти самые машины найти. Существует несколько независимых стратегий распространения, среди которых в первую очередь следует выделить импорт данных из адресной книги Outlook Express или аналогичного почтового клиента, просмотр локальных файлов жертвы на предмет поиска сетевых адресов, сканирование IP-адресов текущей подсети и генерация случайного IP-адреса. Чтобы не парализовать сеть чрезмерной активностью и не отрезать себе пути к распространению, вирус должен использовать пропускные способности захваченных им информационных каналов максимум наполовину, а лучше десятую или даже сотую часть. Чем меньший вред вирус наносит сетевому сообществу, тем позже он оказывается обнаруженным и тем с меньшей поспешностью администраторы устанавливают соответствующие обновления.

Установив соединение с предполагаемой жертвой, червь должен убедиться в наличии необходимой ему версии программного обеспечения и проверить нет ли на этой системе другого червя. В простейшем случае идентификация осуществляется через рукопожатие. Жертве посылается определенное ключевое слово, внешне выглядящее как безобидный сетевой запрос. Червь, если он только там есть, перехватывает пакет, возвращая инициатору обмена другое ключевое слово, отличное от стандартного ответа незараженного сервера. Механизм рукопожатия это слабейшее звено обороны червя, конечно, при условии, что червь безоговорочно доверяет своему удаленному собрату. А вдруг это никакой не собрат, а его имитатор? Это обстоятельно очень беспокоило Роберта Морриса, и для борьбы с возможными имитаторами червь был снабжен механизмом, который по замыслу должен был в одном из семи случаев игнорировать признак червя, повторно внедрясь в уже захваченную машину. Однако выбранный коэффициент оказался чересчур параноическим, и уязвимые узлы инфицировались многократно, буквально киша червями, съедающими все процессорное время и всю пропускную способность сетевых каналов. В конечном счете, вирусная атака захлебнулась сама собой, и дальнейшее распространение червя стало невозможным.

Чтобы этого не произошло, всякий червь должен иметь внутренний счетчик, уменьшающийся при каждом успешном расщеплении и при достижении нуля подрывающий червя изнутри. Так или приблизительно так устроен любой живой организм, в противном случае нашей биосфере давно бы наступил конец. А сеть Интернет как раз и представляет собой великолепную модель биосферы в натуральную величину. Поэтому — хотим ли мы того или нет программный код должен подчинятся объективным законам природы, не пытаясь идти ей наперекор. Это все равно бесполезно.

Кстати говоря, анатомическая схема червя, описанная выше, не является ни общепринятой, ни единственной. Мы выделили в черве два основных компонента голову и хвост. Другие же исследователи склонны рассматривать червя как организм, состоящий из пасти, именуемой непереводимым термином enablingexploitcode (отпирающий эксплоитный код); механизма распространения (propagationmechanism) и полезной нагрузки (payload), ответственной за выполнение тех или иных деструктивных действий. Принципиальной разницы между различными изображениями червя, разумеется, нет, но вот терминологической путаницы предостаточно.


switch(Iptr->h_port)
{
case 80: //web hole
Handle_Port_80(sock,inet_ntoa(sin.sin_addr),Iptr);
break;

case 21: // ftp hole
if (Handle_Port_21(sock,inet_ntoa(sin.sin_addr),Iptr))
{
pthread_mutex_lock(&ndone;_mutex);
wuftp260_vuln(sock, inet_ntoa(sin.sin_addr), Iptr);
pthread_mutex_unlock(&ndone;_mutex);
} break;

case 111: //rpc hole
if (Handle_Port_STATUS(sock,inet_ntoa(sin.sin_addr),Iptr))
{
pthread_mutex_lock(&ndone;_mutex);
// rpcSTATUS_vuln( inet_ntoa(sin.sin_addr), Iptr);
pthread_mutex_unlock(&ndone;_mutex);
} break;

case 53: //linux bind hole
// Check_Linux86_Bind(sock,inet_ntoa(sin.sin_addr),Iptr->h_network);
break;

case 515: //linux lpd hole
// Get_OS_Type(Iptr->h_network, inet_ntoa(sin.sin_addr));
// Check_lpd(sock,inet_ntoa(sin.sin_addr),Iptr->h_network);
break;

default: break;
}
Листинг 1 пять голов червя MWORM, поражающие множество уязвимых сервисов. Перед нами «шея» червя, которая, собственно, все эти головы и держит, совершающая ими вращательные движения и при необходимости изрыгающая огонь и пламя


/* break chroot and exec /bin/sh — dont use on an unbreakable host like 4.0 */
unsigned char x86_fbsd_shell_chroot[] =
«x31xc0x50x50x50xb0x7excdx80»
«x31xc0x99»
«x6ax68x89xe3x50x53x53xb0x88xcd»
«x80x54x6ax3dx58xcdx80x66x68x2ex2ex88x54»
«x24x02x89xe3x6ax0cx59x89xe3x6ax0cx58x53»
«x53xcdx80xe2xf7x88x54x24x01x54x6ax3dx58»
«xcdx80x52x68x6ex2fx73x68x44x68x2fx62x69»
«x6ex89xe3x52x89xe2x53x89xe1x52x51x53x53»
«x6ax3bx58xcdx80x31xc0xfexc0xcdx80»;
Листинг 2 одна из голов червя и ее дизассемблерный листинг ниже.


.data:0804F7E0 x86_fbsd_shell_chroot:
.data:0804F7E0 xor eax, eax
.data:0804F7E2 push eax
.data:0804F7E3 push eax
.data:0804F7E4 push eax
.data:0804F7E5 mov al, 7Eh
.data:0804F7E7 int 80h; LINUX — sys_sigprocmask
.data:0804F7E9 xor eax, eax
.data:0804F7EB cdq
.data:0804F7EC push 68h
.data:0804F7EE mov ebx, esp
.data:0804F7F0 push eax
.data:0804F7F1 push ebx
.data:0804F7F2 push ebx
.data:0804F7F3 mov al, 88h
.data:0804F7F5 int 80h; LINUX — sys_personality
.data:0804F7F7 push esp
.data:0804F7F8 push 3Dh
.data:0804F7FA pop eax
.data:0804F7FB int 80h; LINUX — sys_chroot
.data:0804F7FD push small 2E2Eh
.data:0804F801 mov [esp+2], dl
.data:0804F805 mov ebx, esp
.data:0804F807 push 0Ch
.data:0804F809 pop ecx
.data:0804F80A mov ebx, esp
.data:0804F80C
.data:0804F80C loc_804F80C:; CODE XREF: .data:0804F813 j
.data:0804F80C push 0Ch
.data:0804F80E pop eax
.data:0804F80F push ebx
.data:0804F810 push ebx
.data:0804F811 int 80h; LINUX — sys_chdir
.data:0804F813 loop loc_804F80C
.data:0804F815 mov [esp+1], dl
.data:0804F819 push esp
.data:0804F81A push 3Dh
.data:0804F81C pop eax
.data:0804F81D int 80h; LINUX — sys_chroot
.data:0804F81F push edx
.data:0804F820 push 68732F6Eh
.data:0804F825 inc esp
.data:0804F826 push 6E69622Fh
.data:0804F82B mov ebx, esp
.data:0804F82D push edx
.data:0804F82E mov edx, esp
.data:0804F830 push ebx
.data:0804F831 mov ecx, esp
.data:0804F833 push edx
.data:0804F834 push ecx
.data:0804F835 push ebx
.data:0804F836 push ebx
.data:0804F837 push 3Bh
.data:0804F839 pop eax
.data:0804F83A int 80h; LINUX — sys_olduname
.data:0804F83C xor eax, eax
.data:0804F83E inc al
.data:0804F840 int 80h; LINUX — sys_exit
Листинг 3 дизассемблерный листинг одной из голов червя MWORM

>>>> врезка механизмы распространения червей

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

И хотя теоретики от безопасности упорно отмахиваются от дыр, как от досадных случайностей, нарушающих стройность воздушных замков абстрактных защитных систем, даже поверхностный анализ ситуации показывает, что ошибки проектирования и реализации носят сугубо закономерный характер, удачно обыгранный хакерами в пословице: «Программ без ошибок не бывает. Бывает плохо искали». Особенно коварны ошибки переполнения, вызываемые (или даже можно сказать провоцируемые) идеологией господствующих языков и парадигм программирования. Подробнее об этом мы поговорим в следующей статье этого цикла; пока же отметим, что ни одна коммерческая программа, насчитывающая более десяти-ста тысяч строк исходного текста, не смогла избежать ошибок переполнения. Через ошибки переполнения распространялись Червь Морриса, Linux.Ramen, MWorm, Code Red, Slapper, Slammer, Love San и огромное множество остальных менее известных вирусов.

Список свежих дыр регулярно публикуется на ряде сайтов, посвященных информационной безопасности (крупнейший из которых www.bugtraq.org) и на web-страничках отдельных хакеров. Заплатки на дыры обычно выходят спустя неделю или даже месяц после появления открытых публикаций, однако в некоторых случаях выход заплатки опережает публикацию, т. к. правила хорошего тона диктуют воздерживаться от распространения информации вплоть до того, пока противоядие не будет найдено. Разумеется, вирусописатели ведут поиск дыр и самостоятельно, однако за все время существования Интернета ни одной дыры ими найдено не было.

Слабые пароли это настоящий бич всякой системы безопасности. Помните анекдот: " Скажи пароль! — Пароль!"? Шутки шутками, но пароль типа «password» не так уж и оригинален. Сколько пользователей доверяют защиту системы популярным словарным словам (в стиле Супер-Ниндзя, Шварценеггер-Разбушевался и Шварценеггер-Продолжает-Бушевать) или выбирают пароль, представляющий собой слегка модифицированный логин (например логин с одной-двумя цифрами на конце)? Про короткие пароли, пароли состоящие из одних цифр и пароли, полностью совпадающие с логином, мы вообще умолчим. А ведь немалое количество систем вообще не имеют никакого пароля! Существуют даже специальные программы для поиска открытых (или слабо защищенных) сетевых ресурсов, львиная доля которых приходится на локальные сети мелких фирм и государственных организаций. В силу ограниченных финансов содержать более или менее квалифицированного администратора они не могут и о необходимости выбора надежных паролей, судя по всему, даже и не догадываются (а может быть просто ленятся кто знает).

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

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

Конечно, со времен Морриса многое изменилось, и в мире наблюдается тенденция к усложнению паролей и выбору случайных, бессмысленных последовательностей. Но вместе с этим растет и число пользователей, администраторы оказываются просто не в состоянии за всеми уследить и проконтролировать правильность выбора пароля. Поэтому атака по словарю по-прежнему остается актуальной угрозой.

Открытые системы: открытыми мы будем называть такие системы, которые беспрепятственно позволяют всем желающим исполнять на сервере свой собственный код. К этой категории преимущественно относятся службы бесплатного хостинга, предоставляющие telnet, perl и возможность установки исходящих TCP-соединений. Существует гипотетический вирус, который поражает такие системы одну за одной и использует их в качестве плацдарма для атаки на другие системы.

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

Человеческий фактор: о пресловутом человеческом факторе можно говорить много. Но не буду. Это вообще не техническая, а сугубо организационная проблема. Как бы не старалась Microsoft и конкурирующие с нею компании защитить пользователя от себя самого, не урезав при этом функциональность системы до уровня бытового видеомагнитофона, еще никому это не удалось. И никогда не удастся. Паскаль, известным тем, что не позволяет вам выстрелить себе в ногу, значительно уступает по популярности языкам Си и Си++, тем, которые отстреливают вам обе ноги вместе с головой в придачу, даже когда вы этого не планировали.

борьба за территорию на выживание

Какой величины территорию должен контролировать каждый червь?
Это зависит от размеров червя.

Френк Херберт, «Дюна»

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

Влияние фактора скорости размножения на жизнеспособность вируса исследовалось еще в пионерских работах Ральфа Бургера. Уже тогда было ясно, что в принципе вирус может заразить все файлы локальной машины за один присест (про сетевых червей, в силу отсутствия последних, речь тогда попросту не шла), однако это сделало бы факт заражения слишком заметным, и тогда судьба вируса оказалась бы предрешена (паническое форматирование жесткого диска «на низком уровне», полная переустановка всего программного обеспечения, ну, в общем, вы меня понимаете). Кроме того, на чувственном уровне такой вирус попросту неинтересен.

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

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

При условии, что выбор IP-адреса заражаемой жертвы происходит по более или менее случайному закону (а большинство червей распространяются именно так), по мере насыщения сети червем скорость его распространения будет неуклонно снижается и вовсе не потому, что магистральные каналы окажутся перегруженными! Попробуйте сгенерировать последовательность случайных байт и подсчитайте количество шагов, требующихся для полного покрытия всей области от 00h до FFh. Очевидно, что за 100h шагов осуществить задуманное нам ни за что не удастся. Если только вы не будете жульничать, одни и те же байты будут выпадать многократно, в то время как другие останутся не выпавшими ни разу! И чем больше байт будет покрыто, тем чаще станут встречаться повторные выпадения! Аналогичным образом дело обстоит и с размножением вируса. На финальной стадии размножения полчища червей все чаще будут стучаться в уже захваченные компьютеры, и гигабайты сгенерированного ими трафика окажутся сгенерированными впустую.

Для решения этой проблемы Червь Морриса использовал несколько независимых механизмов. Во-первых, из каждой зараженной машины он извлекал список доверенных узлов, содержащихся в файлах /etc/hosts.equiv и /.rhosts, а также файлы .forward, содержащие адреса электронной почты. То есть целевые адреса уже не были случайными это раз. Отпадало большое количество несуществующих узлов это два. Количество попыток повторного инфицирования сводилось к разумному минимуму и это три. Подобную тактику используют многие почтовые черви, обращающиеся к адресной книге Outlook Express'a. И эта тактика очень неплохо работает! На сайте корпорации Symantec имеется любопытная утилита VBSim (Virus and Worm Simulation System), выполняющая сравнительный анализ эффективности червей различных типов.

Во-вторых, различные экземпляры Червя Морриса периодически обменивались друг с другом списком уже зараженных узлов, ходить на которые не нужно. Конечно, наличие каких бы то ни было средств межвирусной синхронизации существенно увеличивает сетевой трафик, однако если к этому вопросу подойти с умом, то перегрузку сети можно легко предотвратить. Заразив все уязвимые узлы, червь впадет в глубокую спячку, уменьшая свою активность до минимума. Можно пойти и дальше, выделив каждому из червей определенное пространство IP-адресов для заражения, автоматически наследуемое новорожденным потомством. Тогда процесс заражения сети займет рекордно короткое время, и при этом ни один из IP-адресов не будет проверен дважды. Исчерпав запас IP-адресов, червь обратит свои внутренние счетчики в исходное положение, вызывая вторую волну заражения. Часть ранее инфицированных узлов к этому моменту уже будет исцелена (но не залатана), а часть может быть инфицирована повторно.

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

В этом свете весьма показателен процесс распространения вируса Code Red, в пике своей эпидемии заразившего свыше 359.000 узлов в течении 24 часов. Как были получены эти цифры? Программа-монитор, установленная в локальной сети Лаборатории Беркли, перехватывала все проходящие через нее IP-пакеты и анализировала их заголовки. Пакеты, адресованные несуществующим узлам и направляющиеся на 80-й порт, были очевидно отправлены зараженным узлом (Code Red распространялся через уязвимость в MS IIS-сервере). Подсчет уникальных IP-адресов узлов-отправителей позволил надежно установить нижнюю границу численности популяции вируса. При желании процесс расползания вируса по всемирной сети можно увидеть и в динамике www.caida.org/analysis/security/code-red/newframes-small-log.mov. Там же, на странице www.caida.org/analysis/security/code-red/coderedv2_analysis.xml, содержится текст, комментирующий происходящее зрелище. А зрелище и впрямь получилось впечатляющим и поучительным. Всем, особенно разработчикам вирусов, настоятельно рекомендую посмотреть. Быть может это научит кое-кого не ронять сеть своим очередным ммм творением.

Рисунок 3 зависимость удельной скорости распространения червя от времени. Сначал?
Нравится
Не нравится

2 комментария

21:00
Крис Касперски, на мой взгляд, один из самых выдающихся специалистов в сфере IT. Его статьи и книги всегда отличаются высоким профессионализмом и глубоким знанием темы. Я всегда уважал Криса и буду с удовольствием читать его публикации.
Насчёт этой статьи моё мнение таково:
вся проблема заключается, на мой взгляд, в несовершенстве современных языков программирования, компиляторов, архитектуры процессоров и т.д. и т.п.
Как я считаю, современный мир IT нуждается в специализированных компаниях, деятельность которых будет заключаться в даче рекомендаций по безопасному программированию, обработке исходных кодов, дизассемблированию и проверке кода.
22:41
несовершенство нельзя преодолеть вот в чем проблема.
Крису респект это точно, поистине великий человек