Касперски Крис
Шрифт:
Другой характерный признак: в том месте, где кончается вирус и начинается незатертая область оригинального тела программы, образуется своеобразный дефект. Скорее всего, даже наверняка, граница раздела двух сред пройдет посередине функции оригинальной программы, если еще не рассечет машинную команду. Дизассемблер покажет некоторое количество мусора и хвост функции с отсутствующим прологом.
Создание своей собственной секции
Наиболее честный (читай – «корректный») и наименее скрытный способ внедрения в файл состоит в создании своей собственной секции (сегмента), а то и двух секций – для кода и для данных соответственно. Разместить такую секцию можно где угодно. Хоть в начале файла, хоть в конце (вариант внедрения в сегмент с раздвижкой соседних секций мы уже рассматривали выше) (листинг 2.13).
Листинг 2.13. Карта файла, зараженного вирусом, внедряющимся в собственноручно созданную секцию и этим себя демаскирующим
Внедрение между файлом и заголовком
Фиксированный размер заголовка a.out-файлов существенно затруднял эволюцию этого в общем-то неплохого формата и в конечном счете привел к его гибели. В последующих форматах это ограничение было преодолено. Так, в elf-файлах длина заголовка хранится в двухбайтовом поле e_ehize, оккупировавшем 28h и 29h байты, считая от начала файла.
Увеличив заголовок заражаемого файла на величину, равную длине своего тела, и сместив оставшуюся часть файла вниз, вирус сможет безболезненно скопировать себя в образовавшееся пространство между концом настоящего заголовка и началом Program Header Table. Ему даже не придется увеличивать длину кодового сегмента, поскольку в большинстве случаев тот начинается с самого первого байта файла. Единственное, что будет вынужден сделать вирус – сдвинуть поля p_offset всех сегментов на соответствующую величину вниз. Сегмент, начинающийся с нулевого смещения, никуда перемещать не надо, иначе вирус не будет спроецирован в память. (Смещения сегментов в файле отсчитываются от начала файла, но не от конца заголовка, что нелогично и идеологически неправильно, зато упрощает программирование.) Поле e_phoff, задающее смещение Program Head Table, также должно быть скорректировано.
Аналогичную операцию следует проделать и со смещениями секций, в противном случае отладка/дизассемблирование зараженного файла станут невозможными (хотя файл будет нормально запускаться). Существующие вирусы забывают скорректировать содержимое полей sh_offset, чем и выдают себя, однако следует быть готовым к тому, что в следующих поколениях вирусов этот недостаток будет устранен.
Впрочем, в любом случае такой способ заражения слишком заметен. В нормальных программах исполняемый код никогда не попадает в elf-заголовок, и его наличие там красноречиво свидетельствует о вирусном заражении. Загрузите исследуемый файл в любой hex-редактор (например, HIEW) и проанализируйте значение поля e_ehize. Стандартный заголовок, соответствующий текущим версиям elf-файла, на платформе Х86 (кстати, недавно переименованной в платформу Intel) имеет длину, равную 34 байтам. Другие значения в «честных» elf-файлах мне видеть пока не доводилось (хотя я и не утверждаю, что таких файлов действительно нет – опыт работы с UNIX y меня небольшой). Только не пытайтесь загрузить зараженный файл в дизассемблер. Это бесполезно. Большинство из них (и IDA PRO в том числе) откажутся дизассемблировать область заголовка, и исследователь о факте заражения ничего не узнает!
Ниже приведен фрагмент файла, зараженного вирусом UNIX.inheader.6666 (рис. 2.8). Обратите внимание на поле длины elf-заголовка, обведенное квадратиком. Вирусное тело, начинающиеся с 34h байта, залито серым цветом. Сюда же направлена точка входа (в данном случае она равна 8048034b):
Рис. 2.8. Фрагмент НЕХ-дампа файла, зараженного вирусом UNIX.inheader.6666, внедряющимся в elf-заголовок. Поля elf – заголовка, модифицированные вирусом, взяты в рамку, а само тело вируса залито цветом
Как вариант, вирус может вклиниться между концом elf-заголовка и началом Program Header Table. Заражение происходит так же, как и в предыдущем случае, однако длина elf-заголовка остается неизменной. Вирус оказывается в «сумеречной» области памяти, формально принадлежащей одному из сегментов, но де-факто считающейся «ничейной» и потому игнорируемой многими отладчиками и дизассемблерами. Если только вирус не переустановит на себя точку входа, дизассемблер даже не сочтет нужным заругаться по этому поводу. Поэтому какой бы замечательной IDA PRO ни была, а просматривать исследуемые файлы в HIEW'e все-таки необходимо! С учетом того, что об этом догадываются далеко не все эксперты по безопасности, данный способ заражения рискует стать весьма перспективным. К борьбе с вирусами, внедряющимися в заголовок elf-файлов, будьте готовы!
Перехват управления путем коррекции точки входа
Успешно внедриться в файл – это только полдела. Для поддержки своей жизнедеятельности всякий вирус должен тем или иным способом перехватить на себя нить управления. Классический способ, активно использовавшийся еще во времена MS-DOS, сводится к коррекции точки входа – одного из полей elf/coff/a.out-заголовков файлов. В elf-заголовке эту роль играет поле e_entry, в a.out-заголовке – a_entry. Оба поля содержат виртуальный адрес (не смещение, отсчитываемое от начала файла) машинной инструкции, на которую должно быть передано управление.
При внедрении в файл вирус запоминает адрес оригинальной точки входа и переустанавливает ее на свое тело. Сделав все, что хотел сделать, он возвращает управление программе-носителю, используя сохраненный адрес. При всей видимой безупречности этой методики она не лишена изъянов, обеспечивающих быстрое разоблачение вируса.
Во-первых, точка входа большинства честных файлов указывает на начало кодовой секции файла. Внедриться сюда трудно, и все существующие способы внедрения связаны с риском необратимого искажения исполняемого файла, приводящего к его полной неработоспособности. Точка входа, «вылетающая» за пределы секции. text, – явный признак вирусного заражения.