Записки исследователя компьютерных вирусов
Шрифт:
Забавно, но вирусы этого типа достаточно трудно обнаружить. Действительно, наличие «нечитабельных» ASCII-символов между текстовыми строками – явление вполне нормальное. Может быть, это смещения или еще какие-то структуры данных, на худой конец – мусор, оставленный линкером (рис. 2.5)!
Рис. 2.5. Так выглядел файл cat до (вверху) и после (внизу) его заражения. Согласитесь, что факт зараженности файла вовсе не так очевиден
Исследователи, имеющие некоторый опыт работы с IDA, здесь, возможно, возразят: мол, какие проблемы? Подогнал курсор к первому символу, следующему за концом ASCIIZ-строки, нажал на С и… дизассемблер мгновенно
Листинг 2.8. Фрагмент файла, зараженного вирусом UNIX.NuxBe.jullet, «размазывающим» себя по секции данных
Увы! Какой бы могучей IDA ни была – она все-таки не всесильна, и над всяким полученным листингом вам еще предстоит поработать. Впрочем, при некотором опыте дизассемблирования многие машинные команды распознаются в hex-дампе с первого взгляда. Пользуясь случаем, отсылаю вас к «Технике и философии хакерских атак/дизассемблирование в уме», ставшей уже библиографической редкостью, так как ее дальнейших переизданий не планируется, а появившаяся в продаже «Техника и философия хакерских атак II – записки мыщъх'а» представляет собой совсем другую книгу.
Однако требуемого количества междустрочных байт удается наскрести далеко не во всех исполняемых файлах, и тогда вирус может прибегнуть к поиску более или менее регулярной области с последующим ее сжатием. В простейшем случае ищется цепочка, состоящая из одинаковых байт, сжимаемая по алгоритму RLE. При этом вирус должен следить за тем, чтобы не нарваться на мину перемещаемых элементов (впрочем, ни один из известных автору вирусов этого не делал). Получив управление и совершив все, что он хотел совершить, вирус забрасывает на стек распаковщик сжатого кода, отвечающий за приведение файла в исходное состояние. Легко видеть, что таким способом заражаются лишь секции, доступные как для записи, так и для чтения (то есть наиболее соблазнительные секции. rodata и. text уже не подходят, ну разве что вирус отважится изменить их атрибуты, выдавая факт заражения с головой).
Наиболее настырные вирусы могут поражать и секции неинициализированных данных. Нет, это не ошибка, такие вирусы действительно есть. Их появление объясняется тем обстоятельством, что полноценный вирус в «дырах», оставшихся от выравнивания, разместить все-таки трудно, но вот вирусный загрузчик туда влезает вполне. Секции неинициализированных данных, строго говоря, не только не обязаны загружаться с диска в память (хотя некоторые UNIX'bi их все-таки загружают), но могут вообще отсутствовать в файле, динамически создаваясь системным загрузчиком на лету. Однако вирус и не собирается искать их в памяти! Вместо этого он вручную считывает их непосредственно с самого зараженного файла. Правда, в некоторых случаях доступ к текущему выполняемому файлу предусмотрительно блокируется операционной системой, но этот запрет достаточно легко обойти, и тот же чувак ZOmbie не раз писал, как.
На первый взгляд, помещение вирусом своего тела в секции неинициализированных данных ничего не меняет (если даже не демаскирует вирус), но при попытке поимки такого вируса за хвост он выскользнет из рук. Секция неинициализированных данных визуально ничем не отличается от всех остальных секций файла, и содержать она может все что угодно: от длинной серии нулей до копирайтов разработчика. В частности, создатели дистрибутива FreeBSD 4.5 именно так и поступают (листинг 2.9).
Листинг 2.9. Так выглядит секция. bss большинства файлов из комплекта поставки Free BSD
Ряд дизассемблеров (и IDA Pro в том числе) по вполне логичным соображениям не загружает содержимое секций неинициализированных данных, явно отмечая это обстоятельство двойным знаком вопроса (листинг 2.10). Приходится исследовать файл непосредственно в HIEW'e или любом другом hex-редакторе, разбирая a.out/elf-формат «вручную», так как популярные hex-редакторы его не поддерживают. Скажите честно: готовы ли вы этим реально заниматься? Так что, как ни крути, а вирусы этого типа имеют все шансы на выживание, пусть массовых эпидемий им никогда не видать.
Листинг 2.10. Так выглядит секция. bss в дизассемблере IDA Pro и большинстве других дизассемблеров
Заражение посредством расширения кодовой секции файла
Наибольшую скрытность вирусу обеспечивает внедрение в кодовую секцию заражаемого файла, находящуюся глубоко в середине последнего. Тело вируса, сливаясь с исходным машинным кодом, виртуально становится совершенно неотличимым от «нормальной» программы, и обнаружить такую заразу можно лишь анализом ее алгоритма (см. далее раздел «Основные признаки вирусов»).
Безболезненное расширение кодовой секции возможно лишь в elf– и coff-файлах (под «безболезненностью» здесь понимается отсутствие необходимости в перекомпиляции файла-жертвы), и достигается оно за счет того замечательного обстоятельства, что стартовые виртуальные адреса сегментов/секций отделены от их физических смещений, отсчитываемых от начала файла.
Алгоритм заражения elf-файла в общем виде выглядит так (внедрение в coff-файлы осуществляется аналогичным образом):
1. Вирус открывает файл и, считав его заголовок, убеждается, что это действительно elf-файл.
2. Заголовок таблицы секций (Section Header Table) перемещается вниз на величину, равную длине тела вируса. Для этого вирус увеличивает содержимое поля e_shoff, оккупирующего 20h-23h байты elf-заголовка.
ПРИМЕЧАНИЕ
Заголовок таблицы секций, равно как и сами секции, имеет значение только для компоновочных файлов, загрузчик исполняемых файлов их игнорирует, независимо от того, присутствуют они в файле или нет.
3. Просматривая Program Header Table, вирус находит сегмент, наиболее предпочтительный для заражения (то есть тот сегмент, в который указывает точка входа).
4. Длина найденного сегмента увеличивается на величину, равную размеру тела вируса. Это осуществляется путем синхронной коррекции полей p_filez и pjnemz.
5. Все остальные сегменты смещаются вниз, при этом поле p_of fset каждого из них увеличивается на длину тела вируса.
6. Анализируя заголовок таблицы секций (если только он присутствует в файле), вирус находит секцию, наиболее предпочтительную для заражения (как правило, заражается секция, находящаяся в сегменте последней: это избавляет вирус от необходимости перемещения всех остальных секций вниз).