Jak se viry brání odhalení a zkoumání
Dnes jsem si ve volné chvíli četl knihu Počítačové viry – Analýza útoku a obrana od Petera Szora a velmi mě zaujala kapitola věnovaná základním obraným strategiím virů. Nikdy jsem o tom, jak se může program bránit disassemblování a debugování nepřemýšlel. A opravdu mě ohromilo, jak na to mají tvůrci virů vychytané postupy. Nebudu zde popisovat všechny postupy uvedené v knize, ale pouze ty z mého pohledu nejzajímavější.
Knihu jsem si vypůjčil v naší fakultní knihovně na FITu (na VUT). Jednak z důvodu, že jsem měl hodinu volno, než mi začnou cvičení a jednak z důvodu, že bych v knize mohl objevit zajímavé informace, které bych mohl zužitkovat při psaní své bakalářské práce. Pokud Vás článek zaujme, určitě doporučuji si zmíněnou knihu pořídit i přes fakt, že už je staršího data. To by bylo vše k tomu, jak jsem se k této výborné knize dostal a teď už se vrhnu na slibované obrané strategie.
1) Zabránění disassemblování
Když se vir dostane do rukou někomu povolanému, ten se ho zřejmě pokusí disassemblovat (podívat se jak vypadá jeho kód v assembleru), aby pochopil jak virus funguje, co dělá, jak se proti němu bránit a zjistit jak by bylo možné virus odhalit. Takovéto snahy tvůrce virů pochopitelně moc netěší a tak se tuto analýzu snaží výzkumníkům všemožně znesnadnit. Některé techniky jsou:
Zakódování dat
Tato technika spočívá v zakódování konstant použitých v programu. Takto můžou být zakódovány jak čísla, tak zejména textové konstanty, přičemž virus si před každým využitím konstanty musí zavolat funkci, která ji rozkóduje. Určitě Vás napadne: „Co to má za smysl, mít v kódu kódovaná data, když tam bude i funkce, která je může rozkódovat?“. Smysl kódování konstant je v tom, že to zdržuje analýzu a viry tak získávají cenný čas pro své šíření. Pro analýzu viru Vám tak nebude stačit pouhé disassemblování, ale aby jste se dostali k uloženým konstantám, tak budete muset vir buď debugovat nebo si vyextrahovat dekódovací funkci a data si dekódovat sami.
Matení kódu
Tato technika spočívá v tom, že jsou do kódu viru vložené zbytečné instrukce. Tyto instrukce můžou provádět různé těžko pochopitelné operace, které ale ve výsledku nemají na provádění viru žádný efekt. Jejich cíl je opět jediný a to zmást toho kdo zkoumá kód, zdržet jej co nejvíce a získat čas. Jednoduché a efektivní.
Používání kontrolních součtů
Tato technika mě velice ohromila svou jednoduchostí a přitom svou efektivitou.
Vše spočívá ve snaze omezit v kódu výskyt čitelných řetězců, k čemuž je uvnitř viru použit nějaký algoritmus pro výpočet kontrolního součtu. Takovým algoritmem může být třeba CRC. Výborně tuto techniku využil virus W95/Drill. Tento vir v sobě neměl napsané názvy API funkcí které volal, ale měl pouze jejich kontrolní součty. Pak procházel všechny dostupné funkce a zkoušel, která bude mít odpovídající kontrolní součet a tu pak použil. Zřejmě si dovedete představit, jak nepochopitelně musí vypadat disassemblovaný kód využívající tuto techniku.
Komprimovaný matoucí kód
Viry využívající tuto techniku mají své tělo komprimované a před jeho analýzou je nejprve tělo kódu rozpakovat, to opět prodlužuje analýzu a navíc to dělá virus polymorfním, protože každá kopie viru může použít mírně odlišnou kompresi a tak tělo viru bude mít pokaždé jiný otisk.
2) Obrana proti ladění
Kromě disassemblování je pro pochopení funkce viru, pro toho kdo jej zkoumá, velice užitečné i jeho debugování. Tvůrci virů a další havěti jsou si toho vědomi a rozhodně to nehodlají nikomu ulehčit. Tak jako v předchozím odstavci i tady zmíním pouze pár technik, které mě něčím zaujali.
Přepočítávání kontrolního součtu kódu kvůli detekci breakpointů
Debugger vkládá do laděného kódu breakpointy (většinou volání přerušení INT3). Některé viry proto vytvářejí kontrolní součet svého kódu a v případě, že během svého provádění zjistí, že byl jejich kód změněn (byl vložen breakpoint), tak na to zareagují (třeba tím, že se ukončí).
Kontrolování stavu zásobníku
Během debugování vkládá debugger trasovací záznamy na zásobník. Některé viry tedy kontrolují stav zásobníku aby odhalili jestli jsou debugovány.
Generování výjimky
Na 32bit systémech Windows lze generovat výjimku s obsluhou, která tuto výjimku zachytí. Princip je tedy následující. Virus vyvolá výjimku, pro kterou má obsluhu a tedy se z této výjimky snadno zotaví. Pokud je však virus debugován, tak debugování selže, protože debugger ztratí kontext. Výjimkou jsou totiž obsluhovány v režimu jádra.
Použití API funkce IsDebuggerPresent()
Tady asi není co vysvětlovat :)
Detekce debuggeru v registrech
Virus jednoduše prohledá registry Windows a pokud zjistí klíče patřící debuggeru, tak může nějak zareagovat.
Vypnutí klávesnice
Tato metoda je jedna z nejzajímavějších:)
Virus během svého provádění přenastaví obsah I/O portu, nebo se zavěsí na přerušení obsluhy klávesnice a zablokuje vstup z klávesnice. Při běžném provádění viru by se klávesnice zablokovala a hned uvolnila, takže by si nikdo ničeho nevšiml. Pokud ale virus krokujete v debuggeru a dojdete na instrukci, která zablokuje klávesnici, tak jste v tu ránu bez klávesnice:)
Kontrola obsahu video paměti
Možná, že tato metoda je ještě zajímavější než předešlá. Každopádně si ji nedokážu dost dobře představit pokud karta používá grafický mód a nikoli textový.
Tato technika spočívá v tom, že virus kontroluje obsah video paměti a hledá v ní svůj řetězec. Ten se tam může objevit například když se zrovna díváte v debuggeru na jeho obsah paměti apod.
Samoopravný kód pro vyřazení breakpointů
Toto je naprosto neuvěřitelná metoda.
Spočívá v tom, že virus používá korekci chyb s Hammingovým kódem, aby dokázali opravit svůj vlastní kód. Takže pokud bude do kódu vložen breakpoint, tak díky korekci chyb, bude kód opraven do původního stavu tj. breakpoint bude zrušen. Virus který toto použil byl Yankee_Doodle.
Závěr
Toto bylo několik nejzajímavějších technik, jak se viry brání disassemblování a debugování. Ve zmíněné knize (Počítačové viry – Analýza útoku a obrana) naleznete těchto technik více a detailněji popsaných. Kromě toho tam naleznete i techniky, jak se viry brání heuristické analýze (statické heuristické analýze) i jak se brání emulaci (dynamické heuristické analýze) a je to velice zajímavé čtení.