27.02.2000 Способы инфекции РЕ файлов [meza]

Просмотрев множество win32 вирусов я заметил , что практически все используют один метод заражения РЕ файлов , а ведь их есть немало. Я решил изложить свои мысли на эту тему.
Итак , какие есть варианты?

1 создаем секцию и пишем ее в конец , либо дописка в последнюю секцию жертвы , этот способ используют сейчас 90% вирусов (РЕ инфекторов)

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

2 в свободное место в существующих секциях

+ эвристически лучше , иногда размер файла не меняется
- сложнее реализовать , заразить можно далеко не каждый файл , т.к. не всегда это свободное место есть , особенно это касается файлов из поставки win98

3 HLL метод , когда вирь записывает жертву в свое тело , например в отдельную секцию , при старте распаковывает во временный файл и запускает отдельным процессом

+ довольно легко пишется, часто размер файла после заражения даже меньше
- после появления троянов все следят за процессами , текущая директория для процесса меняется... и вообще , ламерский способ ))

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

+ достаточно легко написать , СОВРЕМЕННЫЕ эвристики нифига не видят , размер виря не волнует , заражается любой РЕ файл , размер файла может уменьшиться (например , упаковать кодовую секцию жертвы)
- эвристически легко обнаружить нынешний вариант - virtualaddress для первой секции != imagebase + PEheadersize (можно обойти)

4.1 вариация , предложенная Deviator-ом. подробности ниже.

5 на мой взгляд , самый перспективный - это аналог того же UPX , только с размножением :)

+ заражается почти все , никаких левых процессов , размер уменьшается , эвристически ОЧЕНЬ надежен (см ниже)
- сложность , это уже серьезная вещь

Теперь пояснения. Насчет п.4 - можно секции жертвы смещать не только в файле , но и в памяти , т.е. для зараженного файла imagebase = old_imagebase + old_imagesize , первой идет наша секция ,а дальше остальные по порядку . Как оно будет работать? Вирь , перед тем , как передать управление жертве копирует все секции жертвы в область памяти , выделенную начиная с old_imagebase - по идее должно сработать. Эвристически тогда этот файл невинен , но есть минус - imagebase меняется , а для dll это может быть существенно.
Deviator предлагает немного другой вариант - для зараженного файла imagebase = old_imagebase - size_of_virus_section и секция виря грузится ПЕРЕД образом жертвы . Это весьма хороший вариант , т.к. по виртуальным адресам ничего подозрительного не обнаружить. Но есть и минус , я где-то читал , что для ЕХЕ imagebase не может быть меньше 0x400000 , т.е. многие файлы таким методом нельзя заразить.Хотя можно применить мой способ в этом случае , а когда возможно - Deviator-а.

В общем , я серьезно подумываю над 5-ым вариантом. Т.к. размер кодовой секции виря в этом случае не очень важен (в разумных пределах), можно хоть 7 полиморфиков туда впихнуть , всякие антидебагги и т.д. По секциям тоже все эвристически ок - по идее их хватило бы всего 2-х - кодовая и данные (ну и ресурсы , для иконки , когда надо). Более того , SMT предложил классную идею - попытаться подделать сигнатуру под какой-нибудь известный РЕ пакер , типа UPX , Petite, Aspack .Ну , в общем , любой поймет, насколько хорош это метод , я серьезно считаю , что это будущее для РЕ инфекторов.
Но вот как это сделать?
Для начала я рассмотрел упрощенные варианты :

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

+ достаточно легко , эвристика молчит , размер
- только для dll

5.2 похожий вариант для ехе - пакуем жертву в себя , ее иконку - себе , свой imagebase должен быть больше , например , как у dll. при старте тоже загружаем жертву через LoadLibrary. В MSDN написано , что для ехе при этом происходит то же , что и для dll , только не вызывается entrypoint , а ее мы сами находим и вызываем

+ тоже , что и в пред. вар-те
- только для ехе

У обоих вариантов есть минус - все-таки создается временный файл , и виден загруженный модуль. Это можно обойти , применяя свою LoadLibrary . . 2-й вариант я пробовал , почему-то не получилось пока... Но если вдуматься , то нам по силам реализовать 5-й вариант в полной мере. Написать свой UPX :) Импорты мы уже умеем обрабатывать , надо всего лишь еще научиться тоже самое делать с экспортами и релокейшинами. Хотя я в этом не уверен , есть еще sharedsegments в dll ... Знаете , что прикольно? Если этот вариант написать и опубликовать - появится просто куча потомков!! Ведь достаточно будет встроить другой полиморфик или просто слегка переписать начало виря , чтоб получить новый , с точки зрения аверов , вирь...И вообще , плюс вирей на с/с++ - легко модифицировать

P.S. почему мне понадобился новый способ вообще? Вовсе не потому , что хотелось что-то СВОЕ придумать. Когда это возможно , я без сомнений использую готовые решения , т.к для меня важнее эффективность написания и работы программы , нежели ее оригинальность. Но в данном случае первый метод уже неэффективен - ловится любым эвристиком , а писать вирус , который определяется еще не родившись - это только для каких-то экспериментов , но не для серьезных дел :)