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

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

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

Упаковка

Упаковка заключается в сжатии исполняемого файла и прикреплении к нему кода, необходимого для распаковки и исполнения. Упаковка как метод сокрытия представляет собой довольно грозное оружие. Достаточно привести пример: грамотно упакованный червь способен вызвать не менее серьезную, чем его первообраз, эпидемию — ведь такой червь распознается антивирусами как новый экземпляр. Не секрет, что большинство из ныне присутствующих в Сети вредоносных программ суть не что иное, как модификации посредством упаковки. Пример — широко известный троян 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) — v.1.4 lite final
ACProtect — v.1.32 Professional
Active PE Scrambler — v.1.0
AHTeam EP Protector — v.0.3 Private
AHTeam Punisher — v.1.5.Public
AHTeam UPX Mutanter — v.0.2 Private
Alex Protector — v.1.0 beta 2
Armadillo — v.4.00.0053 (Custom Build)
Armadillo — v.4.40 (Public Build)
Armadillo — v.4.40.0250 (Custom Build)
Armadillo — v.4.44 (Public Build)
Armadillo — v.4.48 (Public Build)
Armadillo — v.2.00
Armadillo SPS — v.1.90
ASPack — v.2.12
ASProtect — v.1.1
ASProtect — v.1.2
ASProtect — v.1.33 build 03.07 Release
ASProtect — v.1.35 build 04.25 Release
ASProtect — v.1.35 build 06.26 Release
ASProtect — v.1.35 build 06.26 Release (Purchased)
ASProtect — v.2.1 build 02.19 Release
ASProtect SKE — v.2.2 build 03.05
ASProtect SKE — v.2.3 build 03.19 Beta
ASProtect SKE — v.2.3 build 04.23 Beta
ASProtect SKE — v.2.3 build 06.26 Beta
aUS [Advanced UPX Scrambler] — v.0.5 beta
Beria — v.0.07 Public
DEF — v.1.0 + src
Enigma Protector — v.1.02
Exe Stealth — v.2.73
Exe32Pack — v.1.42
EXECryptor — v.2.2.6
EXERefactor — v.0.2
eXPressor — v.1.4.5.1
Fake Ninja — v.2.6
fileEncrypt — v.0.2a
FSG — v.2.0
FSG — v.2.0 Plus
GPcH Protect — v.1.0
Hide PE — v.1.1
HidePX — v.1.4
hyings PE-Armor — v.0.74
JDPack — v.1.01
KByS Packer — v.0.28 beta
kkrunchy — v.0.23 alpha
Krypton The Krypter — v.0.5
Mew 11 SE — v.1.1
MoleBox Pro — v.2.5.13.2201 Retail
MoleBox Pro — v.2.5.7.2164 Retail
Morphine — v.2.7
Morphine — v.3.3
mPack — v.0.0.2
MSLRH — v.0.31a
nPack — v.1.1.200.2006 Beta
NsPack — v.2.3
Obsidium — v.1.2.5.0
ORiEN — v.2.12 Registered
Packman — v.0.0.0.1
PC Guard — v.4.06
PE Diminisher — v.0.1
PECompact — v2.70 RC1
PELock — v.1.06
PEQuake — v.0.06
PESpin — v.1304
PeStubOEP — v.1.6
Petite — v.2.3
PeX — v.0.99
PoPa — Packer on Pascal
Private exe Protector — v.1.9.5
PseudoSigner — v.0.2
RLP — v.0.7.4 beta
SDProtector Pro — v.1.16
SEPP (Special EXE Password Protector) — v.1.0
SHProtector
ShrinkWrap — v.1.4
SLVc0deProtector — v.1.12
Spirits PE Crasher — v.2.1
Stealth PE — v.2.0
tElock — v.0.98 Special Build
tElock — v.0.99
Themida — v.1.5.0.0 (Custom Build)
Themida — v.1.7.3.0
TPPpack
TrueEP — v.0.1
Unopix — v.1.04 beta
UPX — v.1.93 beta
UPX — v.2.00
UPX — v.2.01 DOS
UPX — v.2.01 WIN
UPX-Scrambler +
VB AntiCrack — v.1.1
VMProtect — v.1.22.2
WinUpack — v.0.39 Final
WinUpack — v.0.399
yoda Crypter — v.1.3
yoda Protector — v.1.03.3
[G!X]s Protector — v.1.2

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

Полиморфизм

Полиморфизм (греч. ???v- — много + греч. ????? — форма, внешний вид) — техника, позволяющая затруднить обнаружение вируса с помощью скан- строк (сигнатурное сканирование) и, возможно, эвристики. Вирус, использующий такую технику, называется полиморфным. Говоря простым языком, под полиморфизмом вируса понимается существование одного вируса в нескольких формах. Полиморфизм заключается в формировании кода вируса на лету — уже во время исполнения, при этом сама процедура, формирующая код, также не должна быть постоянной и видоизменяется при каждом новом заражении. Обнаружение по-настоящему полиморфных вирусов с помощью скан-строк невозможно. После появления полиморфизма антивирусные продукты, в свою очередь, также освоили новые техники: эвристика и эмуляторы кода. Первый известный полиморфный вирус был написан Марком Вашберном (Mark Washburn). Вирус, который назывался 1260, был создан в 1990 году. Более известный полиморфный вирус был внедрен в 1992 году болгарским взломщиком Dark Avenger (псевдоним), создавшим MtE (Mutation Engine). Один из самых простых способов реализации полиморфизма — побайтное шифрование основной части вируса операцией xor:

mov cx, code_length
mov si, offset begin_code
mov al, xor_key
_loop:
xor [si+cx], al ;расшифровываем байт
loop _loop ;берем следующий байт
jmp si
;...
;...
begin_code:
;тут находится зашифрованная часть тела вируса
;именно она ответственна за заражение новых файлов
;и формирование новой процедуры расшифровки
;при этом эта же часть тела вируса в новом файле должна быть заново
;зашифрована, но уже с другим ключом

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

Обфускация

Обфускация (от лат. obfuscare, "затенять, затемнять") — запутывание кода программы, то есть приведение исходного текста или исполняемого кода к виду, сохраняющему функциональность программы, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции. "Запутывание" кода может осуществляться на уровне алгоритма, на уровне исходного текста или ассемблерного текста. Для создания запутанного ассемблерного текста могут использоваться специализированные компиляторы, использующие неочевидные или недокументированные возможности среды исполнения программы. Существуют также специальные программы, производящие обфускацию, называемые обфускаторами (англ. Obfuscator). В контексте сокрытия вирусного кода суть метода заключается в том, чтобы запутать программный код и устранить большинство логических связей в нем, делая код максимально неузнаваемым для антивирусного ПО. Пример абфускации кода:

Исходный текст:
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];}

И еще один пример(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 (точка входа в программу).
. Использование полиморфного варианта распаковки.

Продолжение следует

Олег Бойцев, boytsev_om@mail.ru, www.sinlab.3bb.ru


Компьютерная газета. Статья была опубликована в номере 21 за 2007 год в рубрике безопасность

©1997-2024 Компьютерная газета