av-fools

как обмануть антивирус?

крис каспесрки, ака мыщъх, no-email

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

Малварь, написанная с нуля (from the scratch), не поддается детектированию в принципе (если, конечно, она не использует готовых компонентов, «свистнутых» из других вирусов, уже успевших «засветиться» в антивирусных базах). Теоретически, существуют определенные последовательности машинных инструкций/API-функций, характерных для малвари и практически не встречающихся в «честных» программах, по которым эвристический анализатор может выкупить «нечисть» и прихлопнуть ее одной левой. При условии, что антивирус получает управление первым, что вовсе не факт!

«Зловредные» последовательности легко зашифровать, разнести по разным частям программы, разбавить незначащим мусором, в результате чего практически все эвристики тихо кончают, дружно распевая мантру «в Багдаде все спокойно». Самые продвинутые (KAV, NOD32) упорно продолжают мочить заразу, поэтому хакерам приходится прибегать к другим трюкам. Но! Это в том случае, если антивирус получает управление первым, т. е. например, пользователь открывает исполняемый файл, проверяемый антивирусом перед запуском. А если малварь проникает через дыру в сетевом стеке (например), то она (при наличии достаточных прав) запросто прикончит антивирус и он _никак _ не сможет ей противостоять.

Антивирусы поддерживают обширную (и постоянно обновляемую) базу упаковщиков исполняемых файлов и прочих потекторов, разработчики которых прилагают титанические усилия, чтобы сделать упаковку однонаправленным процессом, то есть, чтобы максимально затруднить распаковку. «Разгрызть» навороченный протектор очень сложно и на это уходит от пары дней до нескольких недель рабочего времени, в течении которого любой древний вирус, обработанный новым протектором, будут проходить сквозь антивирусные заслоны со свистом навозной пули. Как вариант, можно слегка подправить код уже существующего протектора и антивирус вновь обломается с его распаковкой (если, конечно, протектор не распаковывается на эмуляторе ЦП, но в силу хлипкости эмулятора на нем распаковываются только простейшие крипторы).

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

Мыщъх'у не известен ни один антивирус, выполняющий периодическое сканирование памяти. Обычно эта операция осуществляется один-единственный раз при запуске антивируса. Но даже если бы она осуществлялась периодически — ну и что с того? Малварь, просочившаяся в компьютер сквозь переполняющийся буфер, может уничтожить антивирус, даже если она не обладает достаточным уровнем привилегий, поскольку, даже в Висле менее непривилегированные процессы могут посылать сообщения более привилегированным, имитируя клавиатурный/мышиный ввод, позволяющий выключить сканирование памяти через пользовательский интерфейс (естественно, при этом малварь должна знать всех антивирусов в лицо, но, учитывая, что популярных антивирусных пакетов не наберется и десятка — это не бог весь какая сложная задача).

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

При заражении программы вирус обычно внедряет в точку входа честной программы одну или несколько команд для передачи управления на вирусное тело, которое может быть расположено где угодно — в начале, середине, конце файла или даже «размазано» по всей его длине. Если эти команды неизвестны эмулятору ЦП, то антивирус просто пропускает такой файл, поскольку знает с какого адреса продолжать декодирование (неизвестные машинные команды имеют неизвестную длину), а неизвестных команд очень много. Реально эмуляторы поддерживают только базовые инструкции, не более 10% от общего набора x86 команд. Что же касается x86-64, то это вообще шаг и мат (во всяком случае сейчас).

Эмуляторы, встроенные в антивирусы, эмулируют лишь машинные инструкции (да и то не все), но не API-функции операционной системы, результат которых можно использовать для расшифровки кода. Самый распространенный трюк среди хакеров — берем некоторую API-функцию, передаем ей некорректные параметры, чтобы она возвратила определенный код ошибки (заранее известный хакеру) и использующийся для расшифровки основного вирусного тела. Антивирусы нервно курят в сторонке, но в драку не лезут, поскольку эмулировать все API-функции — задача практически нереальная, а если же использовать динамическую эмуляцию (т.е. выполнять API-функции на «живом» ЦП), то при этом существует риск, что вирус вырвется за пределы эмулятора и захватит управление.

Таким образом, обмануть антивирус не просто, а _очень_ просто, особенно, если использовать последние аппаратные достижения: наборы векторных команд, виртуализацию, 64-битные расширения и т. д.