Внедрение между файлом и заголовком
Фиксированный размер заголовка 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-файла, на платформе X86 (кстати, недавно переименованной в платформу Intel) имеет длину, равную 34 байтам. Другие значения в "честных" ELF-файлах мне видеть пока не доводилось (хотя я и не утверждаю, что таких файлов действительно нет – опыт работы с UNIX у меня небольшой). Только не пытайтесь загрузить зараженный файл в дизассемблер. Это бесполезно. Большинство из них (и IDA PRO в том числе) откажутся дизассемблировать область заголовка, и исследователь о факте заражения ничего не узнает!
Ниже приведен фрагмент файла, зараженного вирусом UNIX.inheader.6666. Обратите внимание на поле длины ELF-заголовка, обведенное квадратиком. Вирусное тело, начинающиеся с 34h байта, залито бордовым цветом. Сюда же направлена точка входа (в данном случае она равна 8048034h):
Рисунок 8 0x00D фрагмент HEX-дампа файла, зараженного вирусом UNIX.inheader.6666, внедряющимся в ELF-заголовок. Поля ELF-заголовка, модифицированные вирусом, взяты в рамку, а само тело вируса залито бордовым цветом
Как вариант, вирус может вклиниться между концом ELF-заголовка и началом Program Header Table.
Заражение происходит так же, как и предыдущем случае, однако длина ELF-заголовка остается неизменной. Вирус оказывается в "сумеречной" области памяти, формально принадлежащей одному из сегментов, но де-факто считающейся "ничейной" и потому игнорируемой многими отладчиками и дизассемблерами. Если только вирус не переустановит на себя точку входа, дизассемблер даже не сочтет нужным заругаться по этому поводу. Поэтому какой бы замечательной IDA PRO ни была, а просматривать исследуемые файлы в HIEW'е все-таки необходимо! Учитывая, что об этом догадываются далеко не все эксперты по безопасности, данный способ заражения рискует стать весьма перспективным. К борьбе с вирусами, внедряющимися в заголовок ELF-файлов, будьте готовы!