Выбрать главу
Оперативная обстановка

Первые вирусы, поражающие ELF-файлы (основной формат исполняемых файлов под *nix), были зарегистрированы в конце 90-х, а теперь их популяция насчитывает свыше полусотни представителей (см. коллекцию вирусов на vx.netlux.org). Антивирусная Энциклопедия Евгения Касперского (www.viruslist.com/viruslist.html?id=3166) сообщает лишь о четырнадцати из них, что наводит на серьезные размышления о качестве AVP и добросовестности его создателей.

По умолчанию, UNIX запрещает модификацию исполняемых файлов, и успешное распространение вирусов возможно только на уровне root, который либо присваивается зараженному файлу администратором, либо самостоятельно захватывается вирусом через дыры в ядре системы. При правильной политике разграничения доступа и оперативном наложении заплаток угроза вирусного заражения сводится к минимуму. К тому же, времена тотального обмена софтом давно позади. Сейчас уже никто не копирует исполняемые файлы друг у друга, скачивая их напрямую из интернета. Даже если вирус ухитрится поразить центральный сервер, дальше первого поколения его распространение не пойдет и вторичные заражения будут носить единичный характер.

Файловые вирусы уже неактуальны, и отсутствие крупных эпидемий наглядно подтверждает этот факт. Тем не менее, накопленные методики внедрения отнюдь не стали бесполезными – без них жизнь троянов и систем удаленного администрирования была бы весьма недолгой. Захватить управление атакуемым компьютером и заполучить права root'а – все равно что бросить зернышко на раскаленный асфальт. Хакер должен укорениться в системе, цепляясь за все исполняемые файлы, что встретятся ему на пути. Но и тогда он не может быть ни в чем уверен, поскольку существует такое понятие, как резервное копирование, позволяющее восстановить пораженную систему, как бы глубоко вирус ни был внедрен.

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

То же самое относится и к вирусам, обитающим в интерпретируемых скриптах, таких, как sh, Perl, PHP. В *nix скрипты вездесущи и их модификация по умолчанию разрешена, что создает благоприятные условия для размножения вирусов. Если бы пользователи обменивались скриптами, юниксоидный мир погрузился бы в эпоху ранней MS-DOS, когда новые вирусы выходили едва ли не каждый день, а так вирусы остаются внутри пораженного компьютера, не в силах вырваться наружу.

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

Язык разработки

Настоящие хакеры признают только один, максимум, два языка – C и Ассемблер, причем последний из них стремительно утрачивает свои позиции, уступая место Бейсику, Delphi и прочей дряни, на которой элегантный вирус невозможно создать в принципе.

А что на счет Си? С эстетической точки зрения, это – чудовищный выбор, и вирусмэйкеры старой школы его не прощают (однако написать код на ассемблере сравнимый с тем, что выдают современные оптимизирующие C-компиляторы вроде Microsoft C Compiler, – дело для новичка не такое уж простое – прим. AvaLANche'а). С другой стороны, будучи низкоуровневым системно-ориентированным языком, Си неплохо походит для разработки вирусов, хотя от знания Ассемблера это все равно не освобождает.

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

Нельзя объявлять главную функцию программы как main: встретив такую, линкер внедрит в файл start-up код, который вирусу не нужен. Нельзя использовать глобальные или статические переменные: компилятор принудительно размещает их в сегменте данных, но у вирусного кода не может быть сегмента данных! Даже если вирус захочет воспользоваться сегментом пораженной программы, он будет должен, во-первых, самостоятельно определить адрес его «хвоста», а, во-вторых, растянуть сегмент до необходимых размера. Все это тривиально реализуется на Ассемблере, но для компилятора оказывается чересчур сложной задачей. Кроме того, нужно хранить все данные только в локальных переменных, задавая строковые константы в числовом виде. Если написать char x[] = «hello, world», коварный компилятор сбросит «hello, world» в сегмент данных, а затем динамически скопирует его в локальную переменную x. Можно сделать так: x[0]='h', x[1]='e', x[2]='l'… или преобразовать char в int, осуществлять присвоение двойными словами, не забывая о том, что младший байт должен располагаться по наименьшему адресу, что разворачивает строку задом наперед.

Нельзя использовать никакие библиотечные функции, если только не уверен в том, что они полностью удовлетворяют всем вышеперечисленным требованиям. Системные функции обычно вызываются через интерфейс native-API, также известный под именем sys-call (в Linux-подобных системах за это отвечает прерывание INT 80h, другие системы обычно используют дальний вызов по селектору семь, смещение ноль). Поскольку системные вызовы варьируются от одной системы к другой, это ограничивает среду обитания вируса и при желании он может прибегнуть к внедрению в таблицу импорта.

Откомпилировав полученный файл, мы получим объектник и ругательство компилятора по поводу отсутствия main. Остается только слинковать его в двоичный 32.64-разрядный файл. Естественно, внедрять его в жертву придется вручную, так как системный загрузчик откажется обрабатывать такой файл.

Средства анализа, отладки и плагиата

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

Если исходные тексты вируса отсутствуют (кривые дизассемблерные листинги, выдаваемые за божественное откровение, мы в расчет не берем), препарировать двоичный код вируса приходится самостоятельно. Тут-то нас и поджидает одна большая проблема. Дизассемблер всех времен и народов IDA PRO не приспособлен для работы с ELF-вирусами, поскольку отказывается загружать файлы с искаженным section header'ом (а большинство вирусов никак не корректируют его после заражения!). Других достойных дизассемблеров, переваривающих ELF-формат, мне обнаружить так и не удалось (а самому писать лень). За неимением лучших идей приходится возиться с HEX-редакторами (например, с тем же HIEW'ом), разбираясь со служебными структурами файла вручную.

С отладчиками дело обстоит еще хуже. Фактически под *nix существует всего один более или менее самостоятельный отладчик прикладного уровня – gdb (GNU Debugger), являющийся фундаментом для большинства остальных. Простейшие антиотладочные приемы, нарытые в хакерских мануалах времен первой молодости MS-DOS, пускают gdb в разнос или позволяют вирусу вырваться из-под его контроля, поэтому отлаживать вирусный код на рабочей машине категорически недопустимо и лучше использовать для этой цели эмулятор, такой, как BOCHS. Особенно предпочтительны эмуляторы, содержащие интегрированный отладчик, обойти который вирусу будет очень тяжело, а, в идеале, вообще невозможно (BOCHS такой отладчик содержит). Кстати говоря, совершенно необязательно для исследования ELF-вирусов устанавливать *nix. Эмулятора для этих целей будет более чем достаточно.