Обманчивый антивирус

Источник: Журнал "Хакер"
Крис Касперски

Любовь с эвристикой в непристойных позах

По каким критериям эвристики вершат свой суд? Разработчики антивирусов не разглашают алгоритмов, наивно полагая, что тем самым они усложняют жизнь хакерам, но стоит затащить эвристика в постель, как все тайное сразу же станет явным. Стратегию механизма принятия решений легко определить экспериментально. Для этого даже не потребуется брать в лапы дизассемблер, достаточно просто сравнить «честные» программы с «нечестными» и выяснить чем они отличаются.

Эвристические принципы

Эвристические анализаторы обладают поразительной способностью убивать ни в чем не повинные программы, пропуская деструктивную заразу ниже радаров. Убытки от ложных позитивных срабатываний на самом деле очень значительны. Никакой дилер не возьмется распространять программу, если антивирус ругается на нее матом. То же самое относится и к простым пользователям, скачавшим дистрибутив непосредственно с web- или ftp-сервера самого разработчика. Вот и докажи после этого, что ты не козел, или, говоря математическим языком, козел не ты. Требуется приложить большие усилия, убеждая производителя антивируса, что твоя компания в своем штате «левых» людей не держит и деструктивного кода здесь нет (кто не верит, может заглянуть в исходные тексты, естественно, под подписку о неразглашении). Если повезет, создатели антивируса пойдут на уступки и добавят в базу новое правило, устанавливающее для данного файла флаг исключения, но незапятнанной репутации это, увы, не вернет.

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

Антивирусные службы online

Антивирусы, как известно, стоят денег (причем немалых), и этих антивирусов достаточно много для того, чтобы оставить нас всех без штанов, если покупать весь этот арсенал за живую наличность. Можно, конечно, добыть их в осле или ином парнокопытном, но это будет нечестно, да и места они занимают не меньше, чем стадо слонопотамов, а уж как конфликтуют друг с другом - только бивни летят! Демонстрационные версии, распространяемые забесплатно, зачастую поставляются в урезанном виде, без эвристического анализатора (причем этот факт далеко не всегда отмечен в документации), так что для объективного тестирования они категорически не подходят.

К счастью, практически все крупные игроки, присутствующие на антивирусном рынке, поддерживают бесплатные online-сканеры, а некоторые (как, например, «Лаборатория Касперского», www.avp.ru) даже предоставляют полноценный антивирус в виде ActiveX-модуля с поддержкой автоматического обновления - просто фантастика!

Проблема в том, что антивирусных компаний очень много и плановый обход их служб занимает значительное время. Вот почему в Сети появились метаантивирусы, самостоятельно прогоняющие закачанный пользователем файл через все известные им online-сервисы. Одним из таких антивирусов является знаменитый virusscan.jotti.org. Единственными свойственными ему недостатками (за исключением обилия рекламы) являются чрезмерная загруженность (кстати говоря, косвенно свидетельствующая о его популярности) и вытекающая из нее необходимость подолгу простаивать в очередях, дожидаясь обслуживания.

Другой не менее знаменитый метаантивирус с громким именем VIRUS TOTAL (www.virustotal.com/en/indexf.html) намного более выносив в плане нагрузки, к тому же он автоматически ведет мониторинг вирусной активности, да и список поддерживаемых антивирусов у него шире.

Всякий уважающий себя программист просто обязательно должен проверить только что откомпилированный файл «на вшивость» - вдруг эвристикам захочется поругаться? К счастью, все эвристики, несмотря на их крутость, - довольно тупые создания, и их легко обмануть. Чуть позже я покажу как (для людей в погонах: речь идет о честных программах, созданных законопослушными программистами без мысли кому-то что-то оторвать или где-то навредить).

Приятный секс с эвристиком

Как известно, женская суть - есть точка схождения двух прямых - ее ног. Из этой точки на свет появляются антивирусы (ну, если не сами антивирусы, то их создатели - наверняка) :). Собственно говоря, живого вируса (то есть софта, паразитирующего на других программах) народ не видел уже давно, и сейчас все чаще встречаются черви, троянские компоненты и другие программы, копирующие свою тушу на компьютер и передающие на нее управление тем или иным путем. Ни в какие файлы они не внедряются, поскольку это довольно сложно запрограммировать (намного сложнее, чем написать троянскую лошадь). Да и какой смысл внедряться в файл? Это в эпоху ранней молодости MS-DOS и тотального отсутствия интернета пользователи менялись файлами, как любовницами, «опыляя» и «переопыляя» друг друга перекрестным способом. Скорость распространения вирусов определялась именно интенсивностью «опыления». Сейчас же основная масса файлов скачивается из Сети. Достаточно выложить программу, начиненную взрывчаткой, на какой-нибудь сервер, устроить массовую рассылку или забросить shell-код через дыру в системе…

Отказ от механизма внедрения в исполняемый файл на 90% упрощает конструкцию вируса, попутно открывая невиданные ранее перспективны. На смену изощренным полиморфным генераторам пришли упаковщики и протекторы. Троянская лошадь, обработанная новой версией крутого (или не крутого, но малоизвестного) протектора, уже не будет распознана. Сигнатурный поиск отдыхает. Сейчас троянские компоненты пишутся на языках высокого уровня всеми кому не лень, и их популяция увеличивается на пару десятков экземпляров ежедневно. А многие атакующие программы разрабатываются специально под конкретную жертву и в антивирусные базы никогда не попадают!

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

Внутри эвристика

Архитектурно эвристик состоит из следующих модулей: набор статических распаковщиков, эмулятор ЦП (а в некоторых случаях и операционной системы), реконструктор структур данных и поток управления (data and control flows). Поверх них «натянут» сам эвристический анализатор, представляющий собой совокупность детекторов правил. В чистом виде система правил совершенно бесполезна, и чтобы эвристический анализатор работал, как полагается, ему необходимы данные, собираемые остальными компонентами антивируса.

AVP славится своим арсеналом статических распаковщиков и оперативно обновляемой базой данных. Эмулятор (или то, что они называет этим словом) у них явно слабоват. Простая модификация кода упаковщика «ослепляет» AVP, и с протекторами уровня ASProtect эмулятор AVP уже не справляется. У NOD32, напротив, база статических упаковщиков так себе, на уровне слабого подобия левой руки, но зато эмулятор поддерживает практически полный набор инструкций процессора, в том числе MMX и FPU. Но Norman Virus Control в этом смысле еще круче. Помимо виртуального процессора, он создает своеобразною «песочницу» (sandbox), эмулирующую реестр и файловую систему, что позволяет ему запускать исследуемый файл и без всякой эвристики обнаруживать происходящие изменения.

Но все, что касается распаковщиков, - первая стадия анализа, за которой немедленно следует вторая - выявление совокупности признаков, характерных для троянских коней и практически никогда не встречающихся в честных программах. В общем виде поставленная задача решения не имеет, и потому приходится создавать так называемые «наборы правил». Например, если аргумент szFileName функции UrlDownloadToFile (равно как и FTPGetFileA) указывает на исполняемый файл, NOD32 выставляет флаг 142h, означающий «probably unknown NewHeur_PE virus». То же самое происходит, если вслед за UrlDownloadToFile идет вызов ShellExecute.

Сложнее всего разобраться в потоке вызовов: во вредоносном коде эти функции не всегда следуют непосредственно друг за другом, разделяясь мусорными инструкциями; аргументы функций перегоняются через несколько регистров/переменных и т.д. Вот тут-то анализатор потока управления и выручает. Вместо утомительной и совершенно бесперспективной трассировки (выполняемой, естественно, на виртуальном ЦП) эвристик просто хватает константные смещения, пытаясь преобразовать их в указатели, образующие паутину перекрестных ссылок (по такому же принципу, кстати говоря, работает и IDA Pro). Имея в своем распоряжении распакованный образ файла в памяти, эвристический анализатор находит все используемые переменные, затем по перекрестным ссылкам определяет места их инициализации, а также варианты использования этих переменных всеми возможными способами ('o' - offset, загрузка указателя; 'r' - read, чтение содержимого; 'w' - write, запись). Конечный результат работы представляет собой сложную структуру данных, в которой все переменные представлены теми значениями, какие они будут иметь на момент вызова соответствующих API-функций. Разумеется, без помощи эмулятора анализатор структур данных не обходится, поскольку в противном случае простейший XOR мог бы замаскировать всю нежелательную троянскую активность. Или вот, например, как без эмулятора определить, какие значения имеют переменные foo и pAPI в следующем коде:

Пример кода, требующего применения эмулятора ЦП

MOV [foo], offset text_file

XOR EAX,EAX

JNZ init_aAPI

MOV [foo], offset exe_file

init_aAPI:

MOV [pAPI], offset CreateFileA

XOR ECX,ECX

JNZ call_pAPI

MOV [pAPI], offset GetVersion

call_pAPI:

Если учитывать только перекрестные ссылки, то антивирус увидит, что обе переменные инициализируются дважды, но какое из двух значений правильное? Без эмулятора, антивирус должен перебрать 4 комбинации, а в реальной программе этих комбинаций окажется сотни миллионов! А эмулятор ЦП тут же покажет, какие условные переходы выполняются, а какие нет. Однако, эмуляторы не всесильны. Например, они не понимают самомодифицирующегося кода, недокументированные инструкции, да и просто незнакомые им команды. Поскольку в x86 команды имеют разную длину, то продолжить декодирование и эмуляцию инструкций после встречи с неизвестной командой эмулятор не может. Но тут его выручают перекрестные ссылки на данные, и тогда вместо анализа всего кода программы от точки входа до многодетной матери происходит отрывочный анализ тех фрагментов, на которые указывает хотя бы одна перекрестная ссылка. Вывод: чтобы «ослепить» анализатор потоков данных следует исключить все константные смещения, заменив их сложными математическими преобразованиями, неподвластными эмулятору.

Впрочем, многие программы палятся и без всякой эмуляции. Антивирусу достаточно взглянуть на точку входа, и, если она указывает на последнюю загружаемую секцию файла или лежит внутри PE-заголовка, файл приговаривается к расстрелу без предупреждения. Если в оригинальной точке входа находится jump на вирусный код, эвристические анализаторы оставляют этот факт без внимания. Интересно почему. Ведь в честных программах такие трюки практически не встречаются.

Но это все была теория. Теперь самое время перейти к практике и продемонстрировать несколько совершенно безобидных программ, вызывающих недовольство эвристических анализаторов.

Не выносите точку входа за пределы .text

Утро начинается с зарядки (если не с тяжелого похмелья), ну а хакерство - с легкой разминки, которой в данном случае будут игры с точкой входа в PE-файл. Создадим простейшую программу, откомпилируем ее и будем пытать, прямо как немцы пленных в Гестапо:

Программа, предназначенная для экспериментов с точкой входа

#include <stdio.h>

main()

{

printf("hello!\n");

}

Убедившись, что все (до единого) антивирусы к ней благосклонны, загружаем файл в HIEW, нажимаем <ENTER> для перехода в hex-режим и давим <F8>, чтобы отобразить PE-заголовок. Смотрим на RVA-адрес точки входа (в моем случае он равен 1043h), складываем его с Image base (400000h) и получаем 401043h. Записываем полученное значение на бумажке и нажимаем <F6>, показывающую каталог секций. Подгоняем курсор к секции .data, давим <ENTER> и спускаем курсор на несколько строк вниз, где начинаются сплошные нули (в моем случае это 4060A0h). Нажимаем еще раз <ENTER> для перехода в ассемблерный режим и <F3> для разрешения редактирования. После чего вводим следующую последовательность команд: MOV EAX, 401043h/JMP EAX, где 401043h - адрес моей точки входа. Сохраняем изменения с помощью <F9>, двойным нажатием на <ENTER> возвращаемся в hex-режим, переходим в начало файла, находим сигнатуру «PE», отсчитываем от ее начала 28h байтов и записываем RVA-адрес новой точки входа, в нашем случае равный 60A0h (4060A0h - Image base). Естественно, записывать его надлежит в обратном порядке (A0h 60h). Сохраняем изменения, выходим из HIEW'а и загружаем файл в свой любимый метаантивирус, например в virusscan.jotti.org.

Все антивирусы отвечают гробовым молчанием, лишь sandbox emulation («эмуляция в песочнице») выбрасывает желтый флаг опасности, предупреждая, что это может быть malware.

А вот VIRUS TOTAL дает куда более суровый результат и довольно-таки здорово ворчит, выдавая нам замечательную табличку, которая представлена ниже:

А теперь слегка изменим тактику и передвинем точку входа в PE-заголовок (например, можно разместить MOV EAX, 401043h/JMP EAX за концом таблицы секций, следом за .text, .data). Товарищ virusscan.jotti.org сразу же взводит красный флаг: «INFECTED/MALWARE», а антивирус ArcaVir говорит: «Heur.Win95». Очевидно, «Heur» - сокращение от «heuristic» - «эвристика».

VIRUS TOTAL тоже ругается, но как-то невнятно. Тем не менее, сразу 2 антивируса - CAT-QuickHeal и Fortinet - предупреждают нас о грозящей опасности.

Не пользуйся полиморфными упаковщиками

Упаковывая свой файл крутым полиморфным протектором, ты серьезно рискуешь нарваться на крупные неприятности. Возьмем, к примеру, одну из поздних версий популярного hex-редактора HIEW (со штампом времени 3EDAFCCFh), упакованную ASPack'ом и для надежности еще и Viogen Crypt'ом, что PEiD замечательно подтверждает.

А теперь пропустим этот HIEW (в котором ничего деструктивного нет) через строй антивирусов. Батюшки! Какой шухер поднимается! Несмотря на то что virusscan.jotti.org успешно распознает упаковщик, антивирусы от этого не успокаиваются и вопят, как свиньи, заживо смываемые в унитаз. AntiVir категорично классифицирует его (HIEW) как «Backdoor-Server/Bifrose.B backdoor». Avast, чуть более деликатный в своих суждениях, видит в нем типичный троянский компонент, неизвестный науке: «Win32:Trojan-gen. {Other}». Norman Virus Control без эвристики выдает конкретное имя - «W32/Bifrose.CRL», ну а VBA32 просто говорит, что это «Backdoor.Win32.Rbot.on». Вот так, без всяких церемоний, опустили HIEW'а! Раньше на него ругался и AVP на пару с Dr. WEB'ом, но теперь они чего-то притихли. Наверное, стыдно стало. Или Сусликов их запинал.

VIRUS TOTAL, использующий другую версию антивируса AntiVir, говорит, что это «BDS/Bifrose.B», к нему присоединяются и другие ругающиеся, представленные для наглядности в следующей таблице:

Отсюда следует 2 вывода и оба неутешительные: первый - никаким антивирусам доверять нельзя, второй - прежде чем релизить продукт, надо обязательно прогонять его через VIRUS TOTAL.

Инсталляторы и троянские лошади

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

Вот только одна из таких последовательностей, детектируемая антивирусом NOD32:

Псевдокод последовательности API-вызовов, классифицируемый эвристическим анализатором NOD32 как потенциально вредоносный

; // создаем dll в системной директории

call [GetSystemDirectory] ; // получаем путь к системной директории Windiws

call [CreateFile] ; // создаем там файл типа dll

call [WriteFile] ; // пишем в этот файл все что угодно

; // копируем в системную директорию самого себя

call [GetSystemDirectory] ; // получаем путь к системной директории Windiws

call [GetModuleFileName] ; // узнаем, как нас зовут

call [CopyFile] ; // копируем себя в системную директорию

А вот конкретный пример ее программного воплощения на языке Си:

Код, копирующий в системную директорию фиктивную динамическую библиотеку вместе со своей тушей

// based on animaTOR's and Bill_Prisoner's code from www.wasm.ru

#include <windows.h>

int main(int argc, char* argv[])

{

// объявляем необходимые переменные

char buf[255];char buf2[255]; int len; HANDLE hFile; DWORD N;

// получаем имя системной директории и добавляем к нему имя нашей dll

GetSystemDirectory(buf,255);len=lstrlen(buf);lstrcat(buf,"\\nezumi.dll");

// открываем файл на запись

hFile = CreateFile(Buffer,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,0);

// записываем туда что-нибудь (хотя бы даже и мусор)

WriteFile(hFile,"matrix has you", sizeof("matrix has you"),&N,0);

// закрываем файл

CloseHandle(hFile);

// получаем имя системной директории и добавляем к ней имя нашего exe-файла

GetSystemDirectory(buf,255); lstrcat(buf,"\\nezumi.exe");

// копируем самого себя в системную директорию под новым именем

GetModuleFileName(0,buf2,255);CopyFile(buf2,buf,0);

return 0;

}

И хотя из всех антивирусов один лишь NOD32 невнятно выругается на «probably unknown NewHeur_PE», создателям инсталляторов это оптимизма не добавляет и вполне может стоить им карьеры.

Правда если между вызовом GetSystemDirectory и CreateFile вставить холостой цикл, то эмулятор отвалится по тайм-ауту и NOD32 ничего не скажет. Но это крайне ненадежный прием и никаких гарантий облома эвристика он не дает.

Холостой цикл, «ослепляющий» эвристический анализатор антивируса NOD32

_asm

{

mov ecx,144440

next:

mov eax,edx

loop next

}

Искусство скачивания файлов

При использовании API-функций семейства URLDownloadToFile никогда не запускай только что полученный файл (чем пользуются некоторые программы с функцией автоматического обновления). Антивирусы начинают материться так, что уши вянут, причем на основе своих подозрений выдвигают прямые обвинения! Действительно, среди троянских программ такой прием весьма популярен, но… это еще не повод, чтобы хвостом махать! Как минимум следует убедиться, что скачивается что-то реально вредоносное и весьма деструктивное.

Ниже приведен фрагмент программы (впервые опубликованной на форуме WASM'а), которая загружает из сети графический файл формата gif и запускает его на выполнение через API-функцию ShellExecute, вызывающую ассоциированное с ним приложение:

Фрагмент программы, считывающий header.gif с WASM'а и запускающий ассоциированное с ним приложение (полный исходный текст лежит по адресу www.wasm.ru/forum/viewtopic.php?id=15667)

; // based on Brutaller's example

GetTempDir: ; // получаем путь к каталогу %TEMP%

invoke GetTempPath, 256, WinTempDir

; // копируем имя каталога %TEMP% в буфер FullPath,

; // добавляя туда его имя, под которым он будет записан на диск

invoke lstrcpy, FullPath, WinTempDir

invoke lstrcat, FullPath, FileNameToSave

Down: ; // скачиваем файл из сети

invoke URLDownloadToFile, 0, UrlOfFile, FullPath, 0, 0

Exec: ; // запускаем скачанный файл

invoke ShellExecute, NULL, NULL, FullPath, NULL, NULL,1

...

section '.data' data readable writeable

UrlOfFile db 'http://wasm.ru/pic/header.gif',0 ; // url файла

FileNameToSave db 'header.gif',0 ; // имя файла на диске

WinTempDir rb 256 ; // буфер для %TEMP%

FullPath rb 256 ; // буфер для FullPath

После трансляции FASM'ом, мы получаем вполне безобидный exe-файл, результатом работы которого (конечно, при наличии доступа к сети и молчании всех брандмауэров) будет логотип WASM'а отображающийся в MS Paint'е или другой графической программе.

А вот что произойдет, если прогнать этот exe-файл через VIRUS TOTAL. Для удобства восприятия все ругательства объединены в одну таблицу.

Впечатляет, не правда ли? А вот Norman Virus Control с virusscan.jotti.org, воспользовавшись могуществом своего эмулятора, даже показал, какие изменения произошли в файловой системе.

Антивирус Norman Virus Control отчитывается об изменениях, произошедших в виртуальной файловой системе после запуска downloader'а

Sandbox: W32/Downloader; [ General information ]

* File length: 2048 bytes.

[ Changes to filesystem ]

* Creates file C:\WINDOWS\TEMP\header.gif.

[ Network services ]

* Downloads file from http://wasm.ru/pic/header.gif as C:\WINDOWS\TEMP\header.gif.

[ Security issues ]

* Starting downloaded file - potential security problem.

[ Process/window information ]

* Attemps to NULL C:\WINDOWS\TEMP\header.gif NULL.

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

Заключение

Эвристические анализаторы не спасают от вредоносного кода (и массовые эпидемии - лучшее тому подтверждение), но высаживают на измену честных программистов, продукция которых ся ни за что, ни про что. Так что, борьба с эвристическими анализаторами приобретает коллективный характер, и ей начинают интересоваться не только хакеры, но и вполне респектабельные производители программного обеспечения, особенно коммерческого, поскольку в этом случае перепуганный клиент может и в суд подать. А суд - дело такое… его исход никогда не ясен, а вот с opensource-продуктов взятки гладки - как бы там ни визжал антивирус, недовольных пользователей всегда можно ткнуть носом в исходный код и попросить найти то «деструктивное» место, которое антивирусу так не понравилось.

INFO

Я благодарю Broken'а Sword'а, supersonic'а, slow'a, Dr. Golov'a и Brutaller'а за тактико-техническую стратегическую поддержку и прицельный артиллерийский огонь.


Страница сайта http://www.interface.ru
Оригинал находится по адресу http://www.interface.ru/home.asp?artId=5389