E N C Y K L O P E D I E
Z O N E R
P R E S S
ENCYKLOPEDIE ZONER PRESS
analýza útoku a obrana Tato unikátní kniha o počítačových virech vám přiblíží stav v oboru počítačových virů a vývoje antivirů. Klade si za cíl naučit vás metodám analýzy počítačových virů a ochraně proti nim. Autor knihy, Peter Szor, zde podrobně popisuje techniky infekce počítačovými viry ze širokého úhlu pohledu – od infekce souborů, paměti až po napadení počítačové sítě. Dozvíte se spoustu zajímavých věcí o špinavých tricích počítačových virů, které byly v posledních dvou desetiletích vytvořeny těmi na „druhé straně“, a také o tom, jak pracovat se složitostmi polymorfního kódu a exploitů. Kniha se věnuje téměř všem oblastem této problematiky – od popisu prostředí škodlivého kódu a rozdělení metod infekce, přes obranné strategie virů, pokročilé techniky vývoje kódu, exploity a útoky založené na přetečení bufferu k technikám antivirové obrany, skenování paměti, postupům pro blokování červů či způsobům obrany na síťové úrovni a mnoha dalším věcem.
ZONER software, s.r.o. významný producent software v oblasti digitální fotografie, počítačové grafiky a multimédií, poskytovatel internetových služeb, souvisejících s prezentací na internetu a e-komercí a nakladatelství odborné literatury.
O autorovi Peter Szor je světově proslulý odborník na počítačové viry a bezpečnost. Aktivní výzkum počítačových virů vede více než 15 let – na viry a ochranu proti nim se zaměřil už ve své diplomové práci v roce 1991. Během své kariéry Peter pracoval s nejznámějšími antivirovými produkty, jako jsou AVP, F-PROT nebo Symantec Norton AntiVirus. Je autorem více než 70 článků na téma počítačových virů a bezpečnosti.
Z O N E R
P R E S S
Pod tímto logem vycházejí publikace určené pro každého vážného zájemce o práci s počítačem. Od ryze praktických příruček a průvodců až po komplexní publikace o všem, co potřebuje grafik, webdesignér, vývojář či programátor při každodenní práci. Na slevy, které můžete získat, a vydavatelský plán, v němž vedle knih domácích odborníků najdete celou řadu titulů světově uznávaných autorů, se informujte na adrese vydavatelství. Věrným čtenářům je určen výhodný PRÉMIOVÝ PLUS PROGRAM.
www.zoner.cz © Foto: Jiří Heller, www.heller.cz Fotografie z nabídky fotobanky HELLER.CZ
E N C Y K L O P E D I E
analýza útoku a obrana
Počítačové viry
Počítačové viry
Peter Szor
Poč očítačové ítačové viry analýza útoku a obrana
• Analýza škodlivého kódu • Klasifikace metod infekce • Základní obranné strategie virů • Pokročilé techniky vývoje kódu • Techniky antivirové obrany • Skenování paměti a dezinfekce • Strategie obrany na síťové úrovni • Způsoby blokování červů
Peter Szor
© Foto: Jiří Heller
KATALOGOVÉ ČÍSLO: ZR505
ISBN 80-86815-04-8
Zoner Press tel.: 532 190 883 fax: 543 257 245 e-mail: knihy@zoner.cz http://www.zonerpress.cz ZONER software, s.r.o., Nové sady 18/583, 602 00 Brno
z0253_pocitacove_viry OK.indd 1
P e t e r 9 7 8 8 0 8 6
S z o r
8 1 5 0 4 6
20.3.2006 11:23:53
Počítačové viry analýza útoku a obrana
Peter Szor
Art of Computer Virus Research and Defense by Peter Szor. Authorized translation from the English language edition, entitled ART OF COMPUTER VIRUS RESEARCH AND DEFEN SE, THE, 1st Edition, 0321304543, by SZOR, PETER, published by Pearson Education, Inc, publishing as Addison Wesley Professional, Copyright © 2005 by Symatec Corporation. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. CZECH language edition published by ZONER SOFTWARE, s.r.o., Copyright © 2006. Autorizovaný překlad anglického vydání nazvaného ART OF COMPUTER VIRUS RESEARCH AND DEFENSE, první vydání, 0321304543, autor SZOR, PETER, vydal Pearson Education, Inc. ve vydavatelství Addison Wesley Professional, Copyright © 2005 Symatec Corporation. Všechna práva vyhrazena. Žádná část této publikace nesmí být reprodukována nebo předávána žádnou formou nebo způsobem, elektronicky ani mechanicky, včetně fotokopií, natáčení ani žádnými jinými systémy pro ukládání bez výslovného svolení Pearson Education, Inc. České vydání vydal ZONER SOFTWARE, s.r.o., Copyright © 2006.
Počítačové viry – analýza útoku a obrana Autor: Peter Szor Copyright © ZONER software s.r.o. Vydání první v roce 2006. Všechna práva vyhrazena. Zoner Press Katalogové íslo: ZR505 ZONER software s.r.o. Nové sady 18, 602 00 Brno Překlad: Ing. Lukáš Pelikán, Ing. Roman Skřivánek Odpovědný redaktor: Miroslav Kučera Šéfredaktor: Ing. Pavel Kristián DTP: Miroslav Kučera © Cover foto: Jiří Heller, HELLER.CZ s.r.o, www.heller.cz © Cover: PYRAMIDE, s.r.o. Informace, které jsou v této knize zveřejněny, mohou byt chráněny jako patent. Jména produktů byla uvedena bez záruky jejich volného použití. Při tvorbě textů a vyobrazení bylo sice postupováno s maximální péčí, ale přesto nelze zcela vyloučit možnost výskytu chyb. Vydavatelé a autoři nepřebírají právní odpovědnost ani žádnou jinou záruku za použití chybných údajů a z toho vyplývajících důsledků. Všechna práva vyhrazena. Žádná část této publikace nesmí být reprodukována ani distribuována žádným způsobem ani prostředkem, ani reprodukována v databázi či na jiném záznamovém prostředku či v jiném systému bez výslovného svolení vydavatele, s výjimkou zveřejnění krátkých částí textu pro potřeby recenzí. Veškeré dotazy týkající se distribuce směřujte na: Zoner Press ZONER software s.r.o. Nové sady 18, 602 00 Brno tel.: 532 190 883, fax: 543 257 245 e-mail: knihy@zoner.cz http://www.zonerpress.cz
ISBN 80-86815-04-8
Vฤ novรกno Natรกlii
5
Obsah O autorovi Předmluva Poděkování
18 19 21
Část I – Strategie útočníka Kapitola 1
Úvod do her přírody
1.1 Rané modely sebereplikujících struktur 1.1.1 John von Neumann: Teorie automatů schopných vlastní reprodukce 1.1.2 Fredkin: Reprodukční struktury 1.1.3 Conway: Hra života 1.1.4 Války o jádro: bojující programy 1.2 Geneze počítačových virů 1.3 Automaticky se replikující kód: teorie a definice počítačových virů Odkazy
Kapitola 2
Fascinující analýza škodlivého kódu
2.1 Obvyklé vzorce výzkumu v oblasti virů 2.2 Vývoj antivirové obrany 2.3 Terminologie škodlivých programů 2.3.1 Viry 2.3.2 Počítačoví červi 2.3.3 Logické bomby 2.3.4 Trojští koně 2.3.5 Zárodky 2.3.6 Exploity 2.3.7 Stahovače 2.3.8 Dialery 2.3.9 Droppery 2.3.10 Injektory 2.3.11 Auto-Rootery 2.3.12 Kity (generátory virů) 2.3.13 Programy pro spam 2.3.14 Floodery
25 26 27 28 29 33 37 38 40
41 43 44 45 45 45 46 47 48 48 49 49 49 49 50 50 50 51
6 2.3.15 Snímače stisku kláves 2.3.16 Rootkity 2.4 Další kategorie 2.4.1 Zábavné programy 2.4.2 Poplašné zprávy: řetězové dopisy 2.4.3 Další hmyz: adware a spyware 2.5 Schéma pojmenování počítačových škodlivých programů 2.5.1 <jméno_rodiny> 2.5.2 <typ_škodlivého_programu>:// 2.5.3 <platforma>/ 2.5.4 <jméno_skupiny> 2.5.5 <infekční_délka> 2.5.6 <varianta> 2.5.7 [<<převod >] 2.5.8 <modifikátory> 2.5.9 :<specifikátor_lokace> 2.5.10 #<způsob_komprimace> 2.5.11 @m nebo @mm 2.5.12 !<výrobce_speciální komentář > 2.6 Komentovaný seznam oficiálně rozpoznávaných platforem Odkazy
Kapitola 3
Prostředí škodlivého kódu
3.1 Závislost na počítačové architektuře 3.2 Závislost na procesoru 3.3 Závislost na operačním systému 3.4 Závislost na verzi operačního systému 3.5 Závislost na souborovém systému 3.5.1 Cluster viry 3.5.2 Viry pro NTFS Stream 3.5.3 Viry využívající kompresi NTFS 3.5.4 Infekce ISO obrazů 3.6 Závislost na formátu souboru 3.6.1 COM viry v prostředí DOSu 3.6.2 EXE viry v prostředí DOSu 3.6.3 NE (New Executable) viry pro 16bitová Windows a OS/2 3.6.4 LX viry na OS/2 3.6.5 Viry napadající soubory PE prostředí 32bitových Windows
51 51 51 51 52 52 53 54 54 54 55 55 55 55 55 55 56 56 56 56 60
61 63 64 65 66 66 66 68 68 69 69 69 69 69 70 70
7 3.6.6 Viry infikující soubory ELF v prostředí systému UNIX 3.6.7 Viry napadající ovladače zařízení 3.6.8 Viry infikující objekty a LIB 3.7 Závislost na překladači 3.7.1 Makro viry v produktech firmy Microsoft 3.7.2 REXX viry na systémech IBM 3.7.3 DCL viry na DEC/VMS 3.7.4 Shell skripty na UNIXu (csh, ksh a bash) 3.7.5 VBScript viry na systémech Windows 3.7.6 Dávkové viry 3.7.7 Viry ve skriptech programů mIRC, PIRCH 3.7.8 SuperLogo Viry 3.7.9 JScriptové viry 3.7.10 Perlovské viry 3.7.11 Červi WebTV napsaní v JellyScriptu a vložení do HTML e-mailů 3.7.12 Viry pro Python 3.7.13 VIM viry 3.7.14 EMACS viry 3.7.15 TCL viry 3.7.16 PHP viry 3.7.17 MapInfo viry 3.7.18 ABAP viry na SAPu 3.7.19 Viry pro soubory nápovědy Windows – když zmáčknete F1... 3.7.20 JScriptové hrozby v souborech Adobe PDF 3.7.21 Závislost na AppleScript 3.7.22 Závislost na ANSI 3.7.23 Hrozby v ActionScriptu 3.7.24 Hrozby skriptů HyperTalk 3.7.25 Skriptovací viry pro AutoLisp 3.7.26 Závislost na registru 3.7.27 Závislost na PIF a LNK 3.7.28 Makro viry programu Lotus Word Pro 3.7.29 Viry dokumentů AmiPro 3.7.30 Viry pro Corel Script 3.7.31 Závislost na makrech produktů Lotus 1-2-3 3.7.32 Závislost na instalačních skriptech systému Windows 3.7.33 Závislost na AUTORUN.INF a souborech INI systému Windows 3.7.34 Závislost na HTML (Hypertext Markup Language)
73 73 74 75 75 84 85 86 87 87 88 88 90 91 91 91 92 92 92 92 93 93 93 94 94 94 95 95 96 97 97 98 98 98 99 99 99 100
8 3.8 Závislost na zranitelnosti 3.9 Závislost na času a datu 3.10 JIT závislost – viry Microsoft .NET 3.11 Závislost na archivovaných formátech 3.12 Závislost na příponě souboru 3.13 Závislost na síťovém protokolu 3.14 Závislost na zdrojových kódech 3.14.1 Zdrojové kódy trojských koní 3.15 Závislosti na zdrojích v platformách Mac a Palm 3.16 Závislost na velikosti hostitele 3.17 Závislost na debbuggerech 3.17.1 Zamýšlené hrozby spoléhající na debugger 3.18 Závislost na kompilátoru a linkeru 3.19 Závislost na vrstvě překladači zařízení 3.20 Závislost na vkládaných objektech 3.21 Závislost na vlastním prostředí 3.22 Multipartitní viry 3.23 Závěr Odkazy
Kapitola 4
Klasifikace metod infekce
4.1 Boot viry 4.1.1 Techniky infekce Master Boot Recordu (MBR) 4.1.2 Techniky infekce DOS BOOT Recordu (DBR 4.1.3 Boot viry, které dovedou pracovat s Windows 95 4.1.4 Možné útoky boot virů v síťovém prostředí 4.2 Techniky infekce souborů 4.2.1 Přepisující viry 4.2.2 Náhodně přepisující viry 4.2.3 Připojující viry 4.2.4 Viry připojující se na začátek souboru 4.2.5 Klasické parazitické viry 4.2.6 Dutinové viry 4.2.7 Dělené dutinové viry 4.2.8 Komprimující viry 4.2.9 Infekce typu Amoeba 4.2.10 Technika přidání decryptoru 4.2.11 Technika vložení decryptoru a virového těla
100 101 101 102 103 104 104 105 106 107 107 108 109 109 111 112 114 115 115
119 120 121 123 125 125 126 126 128 128 129 131 132 133 134 134 135 136
9 4.2.12 Technika matoucího odskoku 4.2.13 Technika utajení vstupního bodu (EPO) 4.2.14 Možné budoucí techniky infekce: stavitelé kódu 4.3 Důkladný pohled na Win32 viry 4.3.1 Win32 API a platformy, které je podporují 4.3.2 Techniky infekce na 32bitových Windows 4.3.3 Win32 a Win64 viry: navržené pro Microsoft Windows? 4.4 Závěr Odkazy
Kapitola 5
137 139 148 149 150 152 168 170 170
Klasifikace metod infekce paměti
173
5.1 Viry přímé akce 5.2 Paměťově rezidentní viry 5.2.1 Obsluha a zavěšování na přerušení 5.2.2 Závěsné rutiny na INT 13h (boot viry) 5.2.3 Závěsné rutiny na INT 21h (souborové viry) 5.2.4 Obvyklé techniky instalace do paměti pod DOSem 5.2.5 Stealth viry 5.2.6 Infekce diskové cache a systémového bufferu 5.3 Dočasné paměťové rezidentní viry 5.4 Swapovací viry 5.5 Viry v procesech (v uživatelském režimu) 5.6 Viry v režimu jádra (Windows 9x/Me) 5.7 Viry v režimu jádra (Windows NT/2000/XP) 5.8 Viry vkládající se do paměti přes síť Odkazy
174 174 175 179 180 183 185 194 195 196 196 197 197 199 200
Kapitola 6
Základní obranné strategie virů
6.1 Tunelující viry 6.1.1 Skenování v paměti původní obsluhy 6.1.2 Trasování s pomocí ladících rozhraní 6.1.3 Tunelování na bázi emulace kódu 6.1.4 Přístup k disku přes I/O porty 6.1.5 Použití nedokumentovaných funkcí 6.2 Obrněné viry 6.2.1 Obrana proti disassemblování 6.2.2 Zakódovaná data
201 202 202 202 203 203 203 203 204 204
10 6.2.3 Matení kódu pro znesnadnění analýzy 6.2.4 Matení kódu založené na míchání operačních kódů 6.2.5 Používání kontrolních součtů 6.2.6 Komprimovaný matoucí kód 6.2.7 Obrana proti ladění 6.2.8 Obrana proti heuristické analýze 6.2.9 Obrana proti emulaci 6.2.10 Viry vyhýbající se návnadám 6.3 Agresivní retroviry Odkazy
Kapitola 7 Pokročilé techniky vývoje kódu a generátory počítačových virů 7.1 Úvod 7.2 Vývoj virového kódu 7.3 Zakódované viry 7.4 Oligomorfní viry 7.5 Polymorfní viry 7.5.1 Virus 1260 7.5.2 Dark Avengerův mutovací engine (MtE) 7.5.3 32bitové polymorfní viry 7.6 Metamorfní viry 7.6.1 Co je metamorfní virus? 7.6.2 Jednoduché metamorfní viry 7.6.3 Složitější metamorfní viry a permutační techniky 7.6.4 Mutování dalších aplikací: definitivní generátor virů? 7.6.5 Pokročilé metamorfní viry: Zmist 7.6.6 {W32,Linux}/Simile: metamorfní engine napříč systémy 7.6.7 Temná budoucnost – metamorfní MSIL viry 7.7 Generátory počítačových virů 7.7.1 VCS (Virus Construction Set) 7.7.2 GenVir 7.7.3 VCL (Virus Creation Laboratory) 7.7.4 PS-MPC (Phalcon-Skism Mass-Produced Code Generator) 7.7.5 NGVCK (Next Generation Virus Creation Kit) 7.7.6 Další nástroje a mutační enginy 7.7.7 Jak testovat generátory počítačových virů? Odkazy
205 206 207 207 208 215 222 225 226 228
229 230 230 231 235 237 237 238 240 244 245 246 247 250 251 254 258 260 260 260 261 261 262 262 263 264
11 Kapitola 8
Klasifikace podle payloadu
8.1 Bez payloadu 8.2 Náhodně destruktivní payload 8.3 Nedestruktivní payload 8.4 Příležitostně destruktivní payload 8.5 Velmi destruktivní payload 8.5.1 Viry přepisující data 8.5.2 Data Diddlers 8.5.3 Viry šifrující data: dobří, zlí a oškliví 8.5.4 Ničení hardware 8.6 Útoky DoS – odmítnutí služby 8.7 Získávání peněz pomocí virů 8.7.1 Phishing 8.7.2 Vlastnosti zadních vrátek 8.8 Závěr Odkazy
Kapitola 9
Strategie počítačových červů
9.1 Úvod 9.2 Generická struktura počítačových červů 9.2.1 Vyhledávač obětí 9.2.2 Modul pro šíření infekce 9.2.3 Vzdálené ovládání a rozhraní pro aktualizaci 9.2.4 Plánovač životního cyklu 9.2.5 Payload 9.2.6 Sledování počtu infikovaných systémů 9.3 Vyhledávač obětí 9.3.1 Sklízení e-mailových adres 9.3.2 Útoky založené na prohledávání sdílených prostředků 9.3.3 Skenování sítě a označení cíle 9.4 Šíření infekce 9.4.1 Útok na systémy kompromitované pomocí zadních vrátek 9.4.2 Útoky na peer-to-peer sítě 9.4.3 Útoky pomocí systémů pro okamžitý přenos zpráv 9.4.4 Útoky pomocí e-mailů a klamavých technik 9.4.5 Útoky pomocí přímého vkládání e-mailů do schránky 9.4.6 Útoky založené na SMTP Proxy
265 266 267 267 269 270 270 271 272 273 274 276 276 276 278 279
281 282 283 283 283 283 284 285 286 286 286 290 291 295 296 297 297 298 298 299
12 9.4.7 Útoky přes SMTP 9.4.8 Použití MX dotazů pro zrychlené šíření pomocí SMTP 9.4.9 Útoky pomocí NNTP (Network News Transfer Protocol) 9.5 Běžný kód červa a spouštěcí techniky 9.5.1 Útoky založené na spustitelném kódu 9.5.2 Odkazy na webové stránky nebo webové proxy 9.5.3 E-mail založený na HTML kódu 9.5.4 Útoky založené na vzdáleném přihlašování 9.5.5 Útoky injektáží kódu 9.5.6 Útoky založené na interpretech příkazů 9.6 Aktualizační strategie počítačových červů 9.6.1 Autentizované aktualizace z webu 9.6.2 Aktualizace založené na zadních vrátkách 9.7 Vzdálené ovládání pomocí signalizace 9.7.1 Kontrola nad Peer-to-Peer sítěmi 9.8 Úmyslné a náhodné interakce 9.8.1 Spolupráce 9.8.2 Soutěžení 9.8.3 Budoucnost – jednoduchý komunikační protokol pro červy? 9.9 Červi pro bezdrátová mobilní zařízení Odkazy
Kapitola 10 Exploity, zranitelná místa, útoky založené na přetečení bufferu 10.1 Úvod 10.1.1 Definice smíšeného útoku 10.1.2 Hrozba 10.2 Pozadí 10.3 Typy zranitelností 10.3.1 Přetečení bufferu 10.3.2 První generace útoků 10.3.3 Útoky druhé generace 10.3.4 Útoky třetí generace 10.4 Současné a dřívější hrozby 10.4.1 Internetový červ Morris, 1988(přetečení bufferu ke spuštění kódu shellu) 10.4.2 Linux/ADM, 1998 (napodobenina červa Morris) 10.4.3 Vypuknutí epidemie červa CodeRed, 2001 (injektování kódu) 10.4.4 Červ Linux/Slapper, 2002 (příklad přetečení heapu)
299 301 302 302 302 302 303 304 304 305 307 308 312 313 314 315 315 317 318 319 320
323 324 324 324 325 326 326 326 328 335 348 348 350 351 353
13 10.4.5 Červ W32/Slammer, leden 2003 (miničerv) 10.4.6 Červ Blaster, srpen 2003 (útok pomocí shellkódu na Win32) 10.4.7 Obecné použití přetečení bufferu v počítačových virech 10.4.8 Popis W32/Badtrans.B@mm 10.4.9 Exploity v W32/Nimda.A@mm 10.4.10 Popis W32/Bolzano 10.4.11 Popis VBS/Bubbleboy 10.4.12 Popis W32/Blebla 10.5 Shrnutí Odkazy
358 361 363 363 364 364 366 366 367 368
Část II – Strategie obránce Kapitola 11 Techniky antivirové obrany 11.1 Skenery první generace 11.1.1 Skenování řetězců 11.1.2 Zástupné znaky 11.1.3 Neshody 11.1.4 Generická detekce 11.1.5 Hašování 11.1.6 Záložky 11.1.7 Skenování začátku a konce 11.1.8 Skenování vstupních a fixních bodů 11.1.9 Hyper-rychlý přístup k disku 11.2 Skenery druhé generace 11.2.1 Chytré skenování 11.2.2 Detekce struktury 11.2.3 Téměř přesná identifikace 11.2.4 Přesná identifikace 11.3 Algoritmické skenovací metody 11.3.1 Filtrování 11.3.2 Statická detekce decryptoru 11.3.3 Rentgenová metoda (X-raying) 11.4 Emulace kódu 11.4.1 Detekce zakódovaných a polymorfních virů s použitím emulace 11.4.2 Dynamická detekce decryptoru 11.5 Příklady detekce metamorfních virů
373 375 376 377 378 379 379 379 380 381 381 382 382 382 382 383 385 386 388 389 393 397 400 401
14 11.5.1 Geometrická detekce 11.5.2 Disassemblovací techniky 11.5.3 Použití emulátorů pro trasování 11.6 Heuristická analýza 32bitových virů pro Windows 11.6.1 Vykonávání kódu začíná v poslední sekci 11.6.2 Podezřelé příznaky sekce 11.6.3 Nesprávná virtuální velikost v PE hlavičce 11.6.4 Možné "díry" mezi sekcemi 11.6.5 Podezřelé přesměrování kódu 11.6.6 Podezřelé jméno kódové sekce 11.6.7 Možná infekce hlavičky 11.6.8 Podezřelé importy z KERNEL32.DLL přes pořadová čísla 11.6.9 Tabulka importovaných adres je přepsaná 11.6.10 Vícenásobné PE hlavičky 11.6.11 Vícenásobné hlavičky Windows a podezřelé importy z KERNEL32.DLL 11.6.12 Podezřelé relokace 11.6.13 Pevné ukazatele na systémové oblasti 11.6.14 Nekonzistence knihovny KERNEL32.DLL 11.6.15 Načítání sekce do adresního prostoru VMM 11.6.16 Nesprávná velikost kódu v hlavičce 11.6.17 Příklady kombinací podezřelých příznaků 11.7 Heuristická analýza používající neuronové sítě 11.8 Obyčejné a generické metody dezinfekce 11.8.1 Standardní dezinfekce 11.8.2 Generické decryptory 11.8.3 Jak generický dezinfektor funguje? 11.8.4 Jak si může být dezinfektor jistý, že je soubor infikován? 11.8.5 Kde je původní konec hostitelského souboru? 11.8.6 Kolik druhů virů můžeme takto odstranit? 11.8.7 Příklady heuristiky pro generické léčení 11.8.8 Příklady generické dezinfekce 11.9 Očkování 11.10 Systémy řízení přístupu 11.11 Kontrola integrity 11.11.1 Falešné poplachy 11.11.2 Prvotní čistý stav 11.11.3 Rychlost 11.11.4 Speciální objekty
402 402 403 406 407 407 407 407 408 408 408 408 408 408 408 409 409 409 409 410 410 411 412 413 414 414 415 415 415 416 417 418 419 420 420 421 421 421
15 11.11.5 Nezbytné změny v objektech 11.11.6 Možná řešení 11.12 Monitory podezřelého chování 11.13 Sand-Boxing 11.14 Závěr Odkazy
Kapitola 12 Skenování paměti a dezinfekce 12.1 Úvod 12.2 Systém virtuální paměti ve Windows NT 12.3 Virtuální adresovací prostor 12.4 Skenování paměti v uživatelském režimu 12.4.1 Tajemství funkce NtQuerySystemInformation() 12.4.2 Obecné procesy a speciální systémová práva 12.4.3 Viry v subsystému Win32 12.4.4 Viry Win32 alokující privátní stránky 12.4.5 Viry nativních služeb Windows NT 12.4.6 Viry Win32, které používají proceduru skrytého okna 12.4.7 Viry Win32, které jsou součástí spustitelného obrazu 12.5 Skenování paměti a stránkování 12.5.1 Vyhodnocení procesů a skenování obrazů v souborech 12.6 Dezinfekce paměti 12.6.1 Ukončení procesu, který obsahuje kód viru 12.6.2 Detekce a ukončování threadů virů 12.6.3 Záplatování virového kódu v aktivních stránkách 12.6.4 Postup dezinfekce zavedených DLL a běžících aplikací 12.7 Skenování paměti v režimu jádra 12.7.1 Skenování uživatelského adresovacího prostoru procesů 12.7.2 Rozlišení vstupních bodů API služeb NT 12.7.3 Důležité funkce NT pro skenování paměti v režimu jádra 12.7.4 Kontext procesu 12.7.5 Skenování horních 2 GB adresovacího prostoru 12.7.6 Jak lze deaktivovat virus ve filtrovacím ovladači? 12.7.7 Paměť jádra, která je pouze pro čtení 12.7.8 Skenování paměti v režimu jádra na 64bitových platformách 12.8 Možné útoky proti skenování paměti 12.9 Shrnutí a budoucnost Odkazy
422 422 422 424 425 425
429 431 432 434 438 438 439 440 441 443 443 443 446 448 448 448 448 451 452 453 453 453 454 455 455 456 458 458 461 462 463
16 Kapitola 13 Techniky blokování červů a ochrany před pronikáním na bázi hostitele 465 13.1 Úvod 13.1.1 Blokování skriptů a SMTP červů 13.1.2 Blokování nových útoků – CodeRed a Slammer 13.2 Techniky blokování útoků využívající přetečení bufferu 13.2.1 Přezkoumání kódu 13.2.2 Řešení na úrovni kompilátoru 13.2.3 Řešení na úrovni operačního systému a rozšíření run-time 13.2.4 Rozšíření subsystému – Libsafe 13.2.5 Rozšíření režimu jádra 13.2.6 Doprovázení programů 13.3 Techniky blokování červů 13.3.1 Detekce injektovaného kódu 13.3.2 Blokování posílání: blokování kódu, který se sám rozesílá 13.3.3. Validace ovladačů výjimek 13.3.4 Techniky zmírňování útoků "return-to-LIBC" 13.3.5 Atributy stránky "GOT" a "IAT" 13.3.6 Velký počet spojení a chyby spojení 13.4 Možné budoucí útoky červů 13.4.1 Možné zvýšení počtu retro-červů 13.4.2 "Pomalí" červi pod radarem 13.4.3 Polymorfní a metamorfní červi 13.4.4 Škody velkého rozsahu 13.4.5 Automatizovaná detekce exploitů – učení se z prostředí 13.5 Závěr Odkazy
Kapitola 14 Strategie obrany na síťové úrovni 14.1 Úvod 14.2 Použití přístupových seznamů routerů 14.3 Ochrana firewally 14.4 Systémy pro detekci průniku do sítě 14.5 Systémy honeypotů
466 467 470 470 471 472 479 480 480 482 482 483 487 489 493 496 497 498 498 498 498 499 499 500 501
503 504 505 507 509 511
17 14.6 Protiútoky 14.7 Systémy včasného varování 14.8 Vzory chování červů v síti 14.8.1 Zachycení červa Blaster 14.8.2 Zachycení červa Linux/Slapper 14.8.3 Zachycení červa W32/Sasser.D 14.8.4 Zachycení požadavku ping červa W32/Welchia 14.8.5 Detekce červa W32/Slammer a souvisejících možností exploitace 14.9 Závěr Odkazy
Kapitola 15 Techniky analýzy škodlivého kódu 15.1 Vaše osobní laboratoř pro analýzu virů 15.1.1 Jak získat potřebný software? 15.2 Informace, informace, informace 15.2.1 Průvodci architekturami 15.2.2 Báze znalostí 15.3 Dedikovaná analýza virů pomocí VMWARE 15.4 Proces analýzy počítačového viru 15.4.1 Příprava 15.4.2 Dekomprese 15.4.3 Disassemblování a dešifrování 15.4.4 Techniky dynamické analýzy 15.5 Udržování sbírky škodlivého kódu 15.6 Automatizovaná analýza: Digital Immune System Odkazy
Kapitola 16 Shrnutí Doporučené čtení Informace o bezpečnosti a včasných varováních Bezpečnostní aktualizace Statistiky vypuknutí počítačových červů Dokumenty o výzkumu počítačových virů Kontaktní informace na prodejce antivirů Testeři antivirů a příbuzné stránky
Rejstřík
513 514 515 515 516 518 520 521 523 523
525 526 528 528 528 528 529 531 531 536 537 543 564 565 567
569 570 570 571 571 571 572 573
576
18
O autorovi Peter Szor je světově proslulý odborník na počítačové viry a bezpečnost. Aktivní výzkum počítačových virů vede více než než 15 let – na viry a ochranu proti nim se zaměřil už ve své diplomové práci v roce 1991. Během své kariéry Peter pracoval s nejznámějšími antivirovými produkty, jako jsou AVP, F-PROT a Symantec Norton AntiVirus. V letech 1990 až 1995 v Maďarsku vytvořil svůj vlastní antivirový program Pasteur. Kromě vývoje počítačových antivirů se Peter už roky zabývá vývojem systémů odolných proti chybám a systémům pro bezpečné finanční transakce. V roce 1997 byl pozván do organizace CARO (Computer Antivirus Researchers Organization). Peter je také v dozorčí radě magazínu Virus Bulletin a je zakládajícím členem sítě AVED (AntiVirus Emergency Discussion). Více než pět let byl vedoucím výzkumníkem ve firmě Symantec v Santa Monice v Kalifornii. Peter je autorem více než 70 článků na téma počítačových virů a bezpečnosti pro magazíny Virus Bulletin, Chip, Source, Windows NT Magazine, Information Security Bulletin a další. Je častým přednášejícím na konferencích, jako jsou Virus Bulletin, EICAR, ICSA nebo RSA a byl přizván i na takové bezpečnostní konference, jako je USENIX Security Symposium. Snaží se sdílet výsledky svého výzkumu a předávat své znalosti o počítačových virech a bezpečnosti ostatním.
19
Předmluva Komu je tato kniha určena V posledních dvou desetiletích se objevilo větší množství publikací na téma počítačových virů, ale pouze několik z nich bylo napsáno profesionály ("znalci") v oboru. Existuje mnoho knih, které se zabývají problematikou počítačových virů, a které se obvykle zaměřují na nováčky – z tohoto důvodu pak nejsou příliš zajímavé pro technické odborníky. Existuje pouze několik knih, které se zabývají technickými detaily, jejichž pochopení je nezbytné pro efektivní obranu proti počítačovým virům. Součástí problému je i to, že existující knihy obsahují jen málo komplexních informací o aktuálních počítačových virech. Postrádají například důležité technické informace o rychle se šířících počítačových červech, které k napadení cílových systémů exploitují jejich zranitelnosti, nebo se nezabývají posledními technikami v oblasti evoluce kódu, jako je třeba metamorfismus. Pokud byste chtěli získat všechny informace, které jsou obsaženy v této knize, museli byste strávit mnoho času čtením článků, které lze jen obtížně vyhledávat v konferencích, zabývajících se počítačovými viry a bezpečností. K získání důležitých detailů byste se museli také roky zabývat zkoumáním škodlivého kódu. Věřím, že tato kniha bude velice užitečná IT odborníkům a bezpečnostním profesionálům, kteří každodenně bojují proti počítačovým virům. V současné době musí systémoví administrátoři, stejně jako domácí uživatelé, bojovat s počítačovými červi a dalšími škodlivými programy ve svých sítích. Různé bezpečnostní kurzy se velmi málo věnují tématu ochrany proti počítačovým virům, přičemž široká veřejnost toho ví ještě méně o analýze a ochraně sítí proti takovým útokům. Faktem ovšem je, že techniky analýzy počítačových virů zatím ještě nebyly v žádné práci popsány v dostatečné míře. Myslím si, že pro každého, kdo se zabývá počítačovou bezpečností, je důležité vědět, čeho všeho již autoři počítačových virů dosáhli. Po mnoho let se výzkumníci počítačových virů soustředili na "soubory" nebo "infikované objekty". Na druhé straně jsou bezpečnostní profesionálové více než znepokojeni podezřelými událostmi probíhajícími na úrovni počítačové sítě. Hrozby typu červa CodeRed pracují tak, že prostřednictvím počítačové sítě injektují svůj kód do paměti zranitelných procesů, ale "neinfikují" soubory na disku. Z toho vyplývá, že dnes je důležité rozumět všem těmto perspektivám (jak samotným souborům a ukládání informací do nich, tak i obsahu paměti a počítačové síti) a pomocí technik analýzy škodlivého kódu hledat souvislosti mezi vzniklými událostmi. Během let jsem trénoval mnoho bezpečnostních analytiků, aby dokázali efektivně pracovat s nebezpečími plynoucími ze škodlivého kódu, a reagovat na ně. V této knize jsou obsaženy informace o všem, s čím jsem kdy pracoval. Uvádím například důležité informace o starých hrozbách, jako jsou 8-bitové viry pro počítač Commodore 64. Uvidíte, že techniky, jako je například technika stealth, se objevovaly už v dřívějších počítačových virech a na mnoha platformách. Tím si uvědomíte, že současné rootkity rozhodně nepředstavují nic nového! V knize naleznete dostatečně pokrytá témata, která se věnují nejenom hrozbám 32-bitových a 64-bitových červů pro Windows, ale i nebezpečím číhajícím na mobilních zařízeních, společně s obsáhlým popisem souvisejících exploitů. Mým cílem je nejenom ilustrovat, jak
20 se mnoho starých technik "reinkarnováno" do nových hrozeb, ale také předvést moderní útoky s uvedením technických detailů. Jsem si jist, že mnoho z vás se připojí k boji proti škodlivému kódu a stejně jako já vyvinou nové techniky obrany. Přitom je však potřeba si uvědomovat i nebezpečí a výzvy v tomto oboru!
O čem je tato kniha Účelem této knihy je demonstrovat současný stav oboru počítačových virů a vývoje antivirů a naučit vás metodám analýzy počítačových virů a ochraně proti nim. Popisuji zde techniky infekce počítačovými viry ze všech možných perspektiv – souborů (ve smyslu uložení obsahu), paměti a počítačové sítě. Dozvíte se všechno o špinavých tricích počítačových virů, které byly v posledních dvou desetiletích vytvořeny těmi na druhé straně, a také o tom, jak pracovat se složitostmi polymorfního kódu a exploitů. Nejjednodušší cestou, jak číst tuto knihu, je postupovat od jedné kapitole ke druhé. Některé kapitoly popisující útok ovšem mohou získat na své důležitosti poté, co si přečtete kapitoly, pojednávající o příslušných způsobech obrany. Pokud cítíte, že vám některá kapitola není po chuti nebo je příliš dlouhá nebo obtížná, můžete ji přeskočit. Jsem si jistý, že každý čtenář podle svých zkušeností shledá některé části jako jednoduché a jiné jako obtížnější. Předpokládám, že čtenář této knihy je na jisté úrovni obeznámen s technologiemi a programováním. Je zde popsáno tolik věcí, že je naprosto nemožné, aby se kniha zabývala všemi tématy do nejmenších detailů. Vše, co budete potřebovat k úspěšnému boji proti počítačovým virům, se však určitě dozvíte jinde. A abych vám v tomto ohledu pomohl, přidal jsem ke každé kapitole obsáhlý seznam odkazů, který vás navede k podrobnějším informacím. Tato kniha určitě mohla mít více než 1000 stran. Jak jsem však řekl – nejsem Shakespeare. Mám znalosti počítačových virů, nikoliv angličtiny. Pokud by kniha byla psána jinak, neměli byste z ní velký užitek.
O čem tato kniha není V knize nepíšu nic o programech trojských koňů, a v celém rozsahu se nevěnují "zadním vrátkám" v programech. Tato kniha je v prvé řadě o škodlivém kódu, který se sám replikuje. O škodlivých programech jako takových existuje spousta dobrých knih (narozdíl od tématu počítačových virů). V této knize neuvádím žádný zdrojový kód, který by mohl být přímo použit k vytvoření jiného viru. Tato kniha není o tom, jak vytvářet viry. Rozumím však tomu, že autoři virů zpravidla znají většinu technik, které uvádím v této knize. Aby vyvinuli svoje vlastní techniky obrany, musí se "ti dobří" dozvědět více a začít přemýšlet (nikoliv však jednat) jako skuteční útočníci! Je zajímavé, že se mnoho univerzit snaží vyučovat výzkum počítačových virů tak, že nabízí kurzy jejich psaní. Může opravdu pomoci to, že je student schopen napsat virus, který infikuje miliony systémů po celém světě? Budou mít takoví studenti lepší znalosti vývoje lepších technik obrany? Odpověď na tuto otázku je pochopitelně záporná. Výuka by raději měla zaměřit na analýzu existujícího škodlivého kódu. Existuje mnoho hrozeb, které čekají na svůj rozbor a na to, až bude proti nim něco podniknuto. Znalost počítačových virů je něco jako "Síla" ve Hvězdných válkách. Podle způsobu použití "Síly" může tato znalost působit dobro nebo zlo. Nemůžu vás ovšem přimět zůstat mimo Temnou stranu...
21
Poděkování Nejdříve bych chtěl poděkovat své ženě Natalii za to, že mě v mé práci více než 15 let povzbuzovala! Také bych jí chtěl poděkovat za to, že tolerovala všechen čas, který jsem věnoval psaní knihy o víkendech, místo toho, abych se věnoval jí samotné. Chtěl bych poděkovat všem, kteří umožnili vznik této knihy. Ta vzešla ze série článků o počítačových virech, z nichž jsem některé během let sepsal já, společně s dalšími výzkumníky. Nemohu proto dostatečně poděkovat Ericu Chienovi, Peterovi Ferriemu, Bruce McCorkendaleovi a Fredericu Perriotovi za jejich velký přínos ke kapitolám 7 a 10. Tato kniha by nemohla být napsána bez pomocí mnoha přátel, antivirových odborníků a kolegů. Na prvním místě bych chtěl poděkovat Dr. Vesselinu Bontchevovi za to, že mě během mnoha let spolupráce naučil spoustu věci o terminologii škodlivých programů. Vesselin je známý svou pečlivostí a můj výzkum velmi ovlivnil a podpořil. Velký dík patří těmto lidem, kteří mě povzbudili při psaní této knihy, předali mi hodně svých znalostí a během let ovlivňovali můj výzkum: Oliver Beke, Zoltan Hornak, Frans Veldman, Eugene Kaspersky, Istvan Farmosi, Jim Bates, Dr. Frederick Cohen, Fridrik Skulason, David Ferbrache, Dr. Klaus Brunnstein, Mikko Hypponen, Dr. Steve White, a Dr. Alan Solomon. Velký dík dlužím svým technickým recenzentům, kterými jsou Dr. Vesselin Bontchev, Peter Ferrie, Nick FitzGerald, Halvar Flake, Mikko Hypponen, Dr. Jose Nazario a Jason V. Miller. Vaše podpora, kritika, porozumění a recenzování první verze rukopisu byly opravdu neocenitelné. Chtěl bych poděkovat Janosi Kisovi a Zsoltu Szoboszlaymu, kteří mi poskytli přístup k virovým kódům v době, kdy centrem počítačového světa byla BBS. Také chci poděkovat Gunter May za největší dárek, který může dítě z východní Evropy dostat – C64. Velký dík patří všem lidem v Symantecu, zejména však Lindě A. McCarthyové a Vincentu Weaferovi, kteří mě při psaní této knihy velice povzbudili. Chtěl bych poděkovat také Nancy Connerové a Chrisu Andrymu za jejich vynikající práci při editaci knihy. Bez jejich pomoci by tento projekt nebyl nikdy dokončen. Velký dík dlužím i Jessice Goldsteinové, Kristy Hartové a Christy Hackerdové, kteří mi pomáhali s procesem publikování. Velký dík rovněž patří všem bývalým a současným členům CARO (Computer Antivirus Researchers Organization), VFORUM a AVED (AntiVirus Emergency Discussion) za zajímavé diskuse nejenom o počítačových virech a jiných škodlivých programech, ale také o systémech obrany. Chtěl bych poděkovat všem lidem ve Virus Bulletinu za to, že po více než 10 let mezinárodně publikovali mé články, a že mi umožnili použít tento materiál pro tuto knihu. Chtěl bych poděkovat svým rodičům a prarodičům za velké "domácí vzdělání" v matematice, fyzice, hudbě a historii.
22
Kontakt na autora Naleznete-li v této knize chyby, nebo pokud máte náměty na to, co by nemělo chybět v případném v budoucím vydání, velmi rád se o tom dozvím. Na své webové stránce plánuji uvádět podrobnější vysvětlení, případné korekce knihy, a také nové informace, které se vztahují k obsahu této knihy. Ačkoliv jsem vynaložil veškeré úsilí, abych vám poskytnul "důvěryhodné" informace podle mých nejlepších znalostí, myslím si, že práce takového rozsahu a složitosti nemůže existovat bez jakýchkoliv nedostatků. Věřím, že na tyto eventuální nedostatky budete pohlížet s porozuměním. Peter Szor Santa Monica, CA pszor@acm.org http://www.peterszor.com
KAPITOLA 4 Klasifikace metod infekce
„Veškeré umění je imitací přírody." – Seneca
120
Kapitola 4 – Klasifikace metod infekce
V této kapitole se dozvíte o běžných technikách infekce počítačových virů, které se zaměřují na různé formáty souborů a systémové oblasti.
4.1 Boot viry První známé úspěšné počítačové viry napadaly tzv. boot sektory disků. V roce 1986 vytvořili na IBM PC dva pakistánští bratři první takový virus pojmenovaný jako Brain. V dnešní době se technika infekce boot sektoru téměř nepoužívá. S bootovacími viry byste se nicméně měli seznámit, protože dovedou infikovat počítače bez ohledu na operační systém, který je na nich nainstalovaný. Boot viry zneužívají procesu startování osobních počítačů typu PC. Protože většina počítačů neobsahuje operační systém v paměti ROM (Read-Only Memory, paměť pouze pro čtení), potřebují nahrát systém odněkud odjinud – například z disku nebo z lokální počítačové sítě. Typický disk IBM PC je organizován do čtyř oblastí (tzv. partitions), které mají na některých operačních systémech, jako je třeba MS-DOS a Windows NT, přiřazená jednotlivá písmena abecedy, většinou C:, D: atd. Písmena disků jsou specifikem jednotlivých operačních systémů – například UNIXové systémy místo nich používají tzv. přípojné body (mount points). Většina počítačů používá pouze dvě oblasti, které jsou být uživatelům zpřístupněny. Někteří dodavatelé počítačů, jako například COMPAQ a IBM, často používají skryté diskové oblasti k uložení dodatečných nástrojů BIOSu. Skryté oblasti nemají přiřazeno žádné písmeno abecedy, čímž je přístup k nim více ztížen. Dobré nástroje, jako třeba Norton Disk Editor, ale umí takové oblasti na disku odhalit (diskové nástroje používejte velmi opatrně – můžete si s nimi nechtěně poškodit vaše data!). Počítače typu PC obvykle načítají OS z pevného disku. U dřívějších systémů ovšem nebylo pořadí zavádění definováno, a proto se počítač pokusil vždy bootovat z disketové mechaniky, což vytvářelo vhodné prostředí pro aktivaci počítačových virů ještě před startem samotného operačního systému. ROM-BIOS tedy přečte první sektor zaváděcích disků dle jejich pořadí specifikovaného v BIOSu a v případě úspěchu jej uloží do paměti na adresu 0:0x7C00 a spustí1. Na novějších systémech je každá disková oblast rozdělena na další oblasti. Disk se vždy adresuje přes hlavu, stopu a sektor. Master Boot Record (MBR) je vždy umístěn na hlavě 0, stopě 0, sektoru 1, což je první sektor na pevném disku. MBR obsahuje generický kód určený pro konkrétní procesor, který vybere aktivní bootovací oblast z tabulky rozdělení disku (tzv. partition table, PT), která se nachází v datové oblasti MBR. Na začátku MBR je krátký kód, kterému se říká zavaděč (boot strap loader). Každá položka v PT obsahuje:
Adresu prvního a posledního sektoru oblasti.
Příznak, zda-li je oblast bootovatelná.
Typ oblasti.
Offset prvního sektoru oblasti od začátku disku v sektorech.
Velikost oblasti v sektorech.
Počítačové viry – analýza útoku a obrana
121
Zavaděč najde aktivní oblast a nahraje její první logický sektor jako boot sektor, který obsahuje kód specifický pro konkrétní operační systém, narozdíl od MBR, který je určen pro obecné použití nezávisle na OS. Takto IBM PC jednoduše podporují více oblastí s různými souborovými a operačními systémy, nicméně tím rovněž usnadňují práci počítačovým virům. Kód z MBR je možné jednoduše nahradit virovým kódem, který použije originální MBR poté, co nahraje sám sebe a dále zůstává v paměti (v závislosti na nainstalovaném operačním systému). V případě MS-DOSu mohou boot viry zůstat v paměti a infikovat za běhu další média. Pár šikovných boot virů, jako například Exebug, vždy donutí počítač, aby je nahrál do paměti a pak dokončí bootovací proces. Exebug mění nastavení BIOSu v paměti CMOS takovým způsobem, aby zmátl počítač a on předpokládal, že systém neobsahuje žádnou disketovou mechaniku – počítač tedy prvně nabootuje z MBR a jakmile je virus aktivován, zjistí, zdali je disku A: disketa. Pokud ano, pak nahraje boot sektor z diskety a předá mu řízení. Pokud se pokusíte nabootovat z diskety, virus se vás pokusí oklamat, abyste si mysleli, že jste z ní skutečně nabootovali, ačkoliv se tak nestalo. V případě disket je boot sektor prvním sektorem, ve kterém je uvedeno, jaké soubory operačního systému se mají nahrát, jako například IBMBIO.COM a IBMDOS.COM. Proto se doporučuje nastavit proces bootování tak, aby se prvně bootovalo z pevného disku. V prvních generacích IBM PC nebyl takto bootovací proces navržen, takže pokud byla disketa v jednotce A:, počítač se pokusil nabootovat z ní. Boot viry využívají právě tuto chybu v návrhu, která se dá omezit správným nastavením bootovacího procesu.
Poznámka Pokud máte v počítači připojený SCSI disk, systém nemusí být schopen z něj nabootovat, protože k těmto diskům není možné přistupovat přímo z BIOSu.
Následující části podrobně rozebírají druhy technik infekce MBR a boot sektorů.
4.1.1 Techniky infekce Master Boot Recordu (MBR) Infekce MBR je pro viry relativně jednoduchou úlohou. Velikost MBR je 512 bajtů, takže se do něj vejde jen malý kousek kódu, ale pro malé viry je to stále více než dost místa. Obvykle se MBR infikuje okamžitě po nabootování z infikované diskety z jednotky A:.
4.1.1.1 Infekce MBR nahrazením zavaděče Klasický druh MBR virů používá k přístupu k diskům pro čtení a zápis službu BIOSu INT 13h. Většina MBR infektorů nahrazuje zavaděč umístěný na začátku disku svojí vlastní kopií a nezasahují do tabulky rozdělení disku. To je velmi důležité, protože když se bootuje z diskety, je pevný disk přístupný pouze tehdy, pokud je tabulka rozdělení disku svém na místě. V opačném případě pak nemá DOS žádnou možnost najít data na disku. Virus Stoned je typickým představitelem používání této techniky. Virus uloží původní MBR na sektor 7 (viz obrázek 4.1). Jakmile se virus aktivuje díky nahrazení MBR, přečte původní uložený MBR ze sekto-
122
Kapitola 4 – Klasifikace metod infekce
ru 7 do paměti a předá mu řízení. Těsně za MBR bývá většinou k dispozici pár prázdných sektorů a právě toho využívá virus Stoned. Na tuto výchozí podmínku se nicméně nedá stoprocentně spolehnout a to je přesně ten případ, kdy MBR viry po infekci znemožní korektní nabootování systému.
Obrázek 4.1
Typické rozmístění disku před a po infekci virem Stoned.
4.1.1.2 Nahrazení MBR kódu bez jeho uložení Další virovou technikou k infekci MBR je ponechání tabulky rozdělení a přepsání zavaděče bez jeho úschovy. Takové viry potřebují zachovat funkčnost původního MBR – musí najít aktivní diskovou oblast, nahrát ji a posléze ji předat řízení. Jedním z prvních virů, který začal používat tuto techniku, byl virus Azusa2, který byl objeven v lednu 1991 v kanadském Ontariu. Takové viry nemohou být odstraněny běžnými metodami, protože není nikde zachována původní kopie MBR. Antivirové programy rychle zareagovaly na toto nebezpečí přidáním standardního MBR kódu do svých produktů. Napadený počítač se pak vyléčil přepsáním virového kódu tímto kódem.
Počítačové viry – analýza útoku a obrana
123
4.1.1.3 Infekce MBR změnou záznamu v tabulce rozdělení disku Snadným cílem MBR infektorů je tabulka rozdělení disku. Změnou záznamu v této tabulce virus zajistí nahrání původního boot sektoru. MBR tedy nahraje zavirovaný boot sektor místo původního, přičemž původní boot sektor je nahrán virem ihned po jeho aktivaci. Virus StarShip je představitelem takové techniky. Některé viry, jako například někteří členové rodiny Ginger, mění záznamy v tabulce rozdělení disku tak, že dojde k zacyklení oblasti3,4, což v případě MS-DOSu verze 4.0 až 7.0 způsobí, že počítač po nabootování skončí v nekonečné smyčce. Ke správnému nabootování z diskety je pak zapotřebí MS-DOS verze 3.3x nebo DOS systém jiný než od Microsoftu, jako například PC DOS.
4.1.1.4 Uložení MBR na konec pevného disku Běžnou metodou infekce MBR je kompletní nahrazení MBR a uložení původní kopie na konec pevného disku, v naději, že jej nic nepřepíše. Některé opatrnější viry ještě zmenší velikost diskové oblasti a zabrání tím přepsání původního MBR. Tuto techniku například používá multipartivní (multipartite) virus Tequila.
4.1.2 Techniky infekce DOS BOOT Recordu (DBR) Boot sektorové viry infikují první sektor disket, a případně i boot sektory pevných disků. Technik infekce boot sektoru je více než technik infekce MBR.
4.1.2.1 Standardní technika infekce boot sektoru Jednou z nejpoužívanějších technik infekce boot sektoru vynalezly viry typu Stoned. Stoned infikuje boot sektor diskety nahrazením 512-bajtového boot sektoru svojí kopií a uložením původní kopie boot sektoru na konec kořenového adresáře. V praxi je tato technika bezpečná jen do té doby, dokud není na disketě příliš mnoho souborů. Pak vede spuštění příkazu DIR k vypsání smetí na obrazovce.
4.1.2.2 Boot viry, které formátují dodatečné sektory Některé boot viry jsou příliš velké na to, aby se vešly do jednoho sektoru. Většina disket se dá ovšem naformátovat tak, že se na ně vejde více dat, než je obvyklé při klasickém běžném formátování. Ne všechny disketové mechaniky umožňují formátování dodatečných sektorů, většina však ano. Například disketová mechanika mého prvního klonu IBM PC nepodporovala přístup na takto zformátované diskety. Výsledkem bylo to, že na mém systému nefungoval některý software s ochranou proti kopírování. Některé ochrany proti kopírování totiž často využívají možnosti naformátovat na disketě dodatečné sektory umístěné mimo obvyklý rozsah. Proto obyčejné nástroje na kopírování disket, jako třeba DISKCOPY, nedokáží vytvořit identickou kopii dat.
124
Kapitola 4 – Klasifikace metod infekce
Některé viry speciálně naformátují několik sektorů na disketě, aby znemožnily antivirovým programům přístup k původní kopii boot sektoru. Hlavním důvodem používání této techniky je nicméně hlavně to, že virus je příliš velký. Indonéský virus Denzuko je představitelem této techniky. Denzuko byl vypuštěn během jara roku 1988 a narozdíl od jiných virů je znám jeho autor – napsal jej Denny Yanuar Ramdhani. Přezdívka autora byla Denny Zuko, která pochází ze jména "Danny Zuko", což byl hlavní hrdina oblíbeného filmového muzikálu Pomáda, kterého hrát John Travolta5. Tento boot virus byl mezi prvními, který začal útočit na jiné počítačové viry. Denzuko odstraňoval virus Brain, pokud jej našel v počítači. Denzuko se také uměl projevovat (rutinám starajícím se o cílený projev viru říkáme payload) – po stisku kláves Ctrl-Alt-Del na zlomek sekundy zobrazil tento obrázek a poté provedl restart počítače, přičemž nadále zůstal v paměti6.
Obrázek 4.2
Payload viru Denzuko.
Tuto techniku používá také velmi složitý a nebezpečný maďarský stealth BOOT/MBR virus Töltögetö (známý též jako Filler). Vytvořil jej jeden student výpočetní techniky na střední škole v Székesfehérváru v Maďarsku v roce 1991. Filler formátuje diskety o kapacitě 360 kB a 1.2 MB – konkrétně sektory na stopě 40 nebo 80. Tyto oblasti disket obvykle nebývají naformátované. Výhodou tohoto druhu techniky infekce je možnost oživení mrtvého virového kódu. První oživovací pokusy byly u virů objeveny na počátku 90. let. Například některé COM infektory se pokoušely umístit sama sebe k těsnému konci disku mimo obvykle formátované oblasti a pak předaly řízení nahranému sektoru. Většina prvních antivirových řešení při procesu léčení nepřepisovala celý virový kód, zejména ne ten kód, který byl umístěn na disku mimo obvyklý rozsah. Antivirové programy opravily pouze boot sektor, přičemž odstřihnutý virový kód byl považován za mrtvý. Ovšem, někteří autoři virů toho využili a mrtvý kód viru oživili prostřednictvím jiného viru.
4.1.2.3 Boot viry, které označují sektory za vadné Zajímavou metodou některých boot virů je nahrazení původního boot sektoru virovým kódem a uložení původní kopie nebo další části viru do prázdného clusteru, který se poté ve FAT tabulce označil jako vadný. Představitelem této virové techniky je nebezpečný Disk Killer, který byl vytvořen v dubnu v roce 19897.
Počítačové viry – analýza útoku a obrana
125
4.1.2.4 Boot viry, které neukládají původní boot sektor Některé boot viry vůbec neukládají původní boot sektor diskety a místo toho napadají aktivní boot sektor nebo MBR pevného disku, aby pak předaly řízení uloženým boot sektorům na pevném disku. Infekce na disketě tak nemůže být opravena standardními technikami, neboť virus nepotřebuje ukládat původní boot sektor. Protože je boot sektor specifický pro konkrétní operační systém, není proces léčení tak jednoduchý, jako v případě nahrazení MBR kódu – pro jednotlivé OS totiž existuje mnoho odlišných boot sektorů OS. Většina antivirových řešení řeší tento problém tak, že přepíší virový kód kódem standardního boot sektoru, který zobrazí výzvu uživateli, zda-li se má nabootovat z pevného disku. Výsledkem je, že se disketa nedá uvést stoprocentně do původního stavu. Druhou, méně obvyklou metodou je přepsání boot sektoru diskety virovým kódem, který napadne MBR nebo boot sektor pevného disku. Virus potom zobrazí falešnou hlášku, něco ve stylu "Non-system disk or disk error" a nechá uživatele načíst virus z pevného disku. Tuto techniku například využívá virus Strike. Další metodou infekce boot sektoru disket bez uložení originálu je předstírání funkčnosti boot sektoru a načtení některých systémových souborů, což ovšem funguje pouze za předpokladu, že se virus strefí do správného operačního systému. Takhle to například dělá virus Lucifer.
4.1.2.5 Boot viry, které ukládají původní boot sektor na konec disku Další kategorie boot virů nahrazuje původní boot sektor přepsáním virovým kódem a uložení jeho kopie na konec pevného disku. Slavným představitelem této techniky je virus Form, který ukládá originální boot sektor na těsný konec disku. Form předpokládá, že se tento sektor téměř vůbec nepoužívá, a může tak sloužit jako vhodné místo na uložení kopie s nízkým rizikem pozdějšího přepsání. Virus tedy nepotřebuje nijak označovat tento sektor, a ani měnit velikost diskové oblasti. Jiné boot viry také ukládají boot sektor na konec aktivní diskové oblasti a navíc zmenšují její velikost tak, že sektor s původní kopií se nebude pro systém tvářit jako volný – nedojde tedy k jeho nechtěnému přemazání. Eventuálně je možné ze stejného důvodu pozměnit datovou oblast boot sektoru.
4.1.3 Boot viry, které dovedou pracovat s Windows 95 Několik boot virů, obvykle multipartitního charakteru, útočí na ovladač disketové mechaniky, který je uložený v \SYSTEM\IOSUBSYS\HSFLOP.PDR. Tato technika se prvně objevila ve slovinské rodině virů nazvané jako Hare (nebo také Krishna) v květnu roku 1996, kterou napsal Demon Emperor. Viry odstraňují tento soubor z toho důvodu, aby získaly přístup k obsluze služby BIOSu INT 13h, pokud systém obsahuje aktivní Windows 95. Bez tohoto triku by totiž boot viry nemohly infikovat diskety prostřednictvím volání INT 13h, protože by pro ně nebylo toto volání dostupné.
4.1.4 Možné útoky boot virů v síťovém prostředí Bezdiskové pracovní stanice bootují prostřednictvím souboru uloženého na serveru. Například na serverech Novell NetWare existuje příkaz DOSGEN.EXE, který dovede vytvořit obraz bootovací diskety
126
Kapitola 4 – Klasifikace metod infekce
NET$DOS.SYS pro použití na terminálech. Ty mají speciální EPROM čip, který umí na síti najít bootovací image. To nabízí útočníkovi dvě možnosti. Ta první je infekce nebo nahrazení souboru NET$DOS.SYS na serveru v okamžiku, kdy je k němu umožněn přístup. Druhou možností je simulace funkčnosti serverového kódu a hostování falešných virtuálních serverů prostřednictvím virového kódu umístěného na síti. Takové viry zatím nejsou známy, nicméně soubor NET$DOS.SYS bývá často infikován a zůstává nepostřehnut mnoha antivirovými skenery.
4.2 Techniky infekce souborů V této části se dozvíte o běžných metodách infekce souborů, které autoři8 virů léta používali k nabourání se do hostitelských systémů.
4.2.1 Přepisující viry Některé viry jednoduše najdou vhodný soubor na disku a přepíší ho vlastní kopií. Jedná se o velmi primitivní techniku, která se však nejsnadněji implementuje. Takové jednoduché viry dovedou napáchat velkou škodu, pokud přepíší soubory na celém disku. Soubory napadené přepisujícími viry nemohou být vyléčeny a musí být smazány z disku a následně obnoveny ze záloh. Následující obrázek 4.3 ukazuje, jak se změní obsah hostitelského programu po napadení takovým virem.
Obrázek 4.3
Přepisující virus, který mění velikost hostitele.
Přepisující viry nejsou obvykle příliš úspěšné, protože vedlejší efekty jejich činnosti uživatelé rychle objeví. Takové viry mají nicméně větší šířící potenciál, zejména tehdy, pokud se tato technika zkombinuje s technikou šíření po síti. Například virus VBS/LoveLetter.A@mm odesílá sebe sama na jiné systémy prostřednictvím elektronické pošty. Po své aktivaci přepíše svojí kopií všechny soubory s těmito příponami: .vbs, .vbe, .js, .jse, .css, .wsh, .sct, .hta, .jpg, .jpeg, .wav, .txt, .gif, .doc, .htm, .html, .xls, .ini, .bat, .com, .avi, .qt, .mpg, .mpeg, .cpp, .c, .h, .swd, .psd, .wri, .mp3 a .mp2.
Počítačové viry – analýza útoku a obrana
127
Jinou metodou infekce přepisem používají takzvané "mrňavé" (tiny) viry. Typickou rodinou tohoto typu infektorů je rodina Trivial pro operační systém DOS. Během počátku 90. let se mnoho autorů počítačových virů pokoušelo napsat co nejmenší možný virus. Není tedy překvapením, že existuje mnoho variant viru Trivial. Některé z nich jsou dlouhé pouhých 22 bajtů (Trivial.22). Algoritmus takových virů je velmi jednoduchý: 1. Vyhledat libovolný soubor (*.*) v aktuálním adresáři. 2. Otevřít soubor pro zápis. 3. Zapsat tělo viru na začátek hostitelského souboru. Tyto nejkratší viry často nedovedou infikovat více než jeden soubor v aktuálním adresáři – z toho důvodu, že kód na vyhledání dalšího hostitelského souboru by zabral o pár bajtů víc. Takové viry nejsou dostatečně vyvinuty na to, aby byly schopny infikovat soubory určené pouze pro čtení – opět proto, že by to vyžadovalo pár instrukcí navíc. Virový kód bývá často optimalizován tak, aby využíval nastavení registrů dle konkrétního operačního systému – virus tedy nemusí inicializovat registry, jejichž obsah je předem známý. Díky tomu mohou autoři ještě více zkrátit délku svých virů. Takové optimalizace mohou nicméně způsobit fatální chyby, pokud se virus spustí na platformě, která registry inicializuje na jiné hodnoty, než jaké virus očekával. Některé šikovné přepisující viry také používají služeb BIOSu pro zápis sektorů místo DOSových souborových funkcí. Nejprimitivnější forma takového viru byla implementována na 15 bajtů. Virus přepíše každý sektor na disku sebe samým. Poškození systému, ke kterému dojde, je tak závažné, že svou aktivitou velmi záhy zlikviduje hostitelský systém. Obrázek 4.4 názorně ukazuje přepisující virus, který jednoduše přepíše svým tělem začátek hostitele, přičemž nijak nezmění jeho velikost.
Obrázek 4.4
Přepisující virus, který nemění velikost hostitelského programu.
Kapitola 4 – Klasifikace metod infekce
128
4.2.2 Náhodně přepisující viry Další neobvyklá varianta přepisovací techniky nemění kód programu na jeho začátku – místo toho si náhodně vybere oblast uprostřed souboru, na kterou se zapíše. Virový kód se nemusí za každou cenu aktivovat během spouštění hostitele, ten je ale každopádně nenávratně poškozen a může havarovat už před samotnou aktivací viru. Příkladem takového viru je Omud9, zobrazený na obrázku 4.5.
Obrázek 4.5
Náhodně přepisující virus.
Pro vylepšení výkonu omezením I/O operací jsou moderní antivirové programy optimalizovány tak, aby byly schopny nalézt viry na známých místech. Náhodně přepisující viry jsou problémem pro skenery, protože ty pak potřebují zanalyzovat kompletní obsah hostitele, což je časově a výkonově náročné.
4.2.3 Připojující viry Typickou technikou infekce DOSových COM souborů je vložení instrukce skoku (JMP) na začátek hostitele, která směřuje přesně na jeho konec. Příkladem může být virus Vienna, jehož lehce upravená varianta byla publikována v knize o počítačových virech Ralfa Burgera společně se zdrojovými kódy v letech 1986-87. Tato technika má své pojmenování podle umístění virového těla, které se připojí na konec hostitele. Je zajímavé, že některé viry infikují EXE soubory tak, že je nejprve převedou na COM. Tuto techniku například používá rodina viru Vacsina. Instrukce skoku je někdy nahrazena instrukcemi se stejnou funkčností, jako například těmito: a.) CALL zacatek_viru b.) PUSH offset zacatek_viru RET
První tři přepsané bajty na začátku hostitelského programu jsou uloženy ve virovém těle. Jakmile dojde ke spuštění infikovaného programu, virus načte hostitele do paměti, instrukce skoku přesměruje vykonávání do těla viru, kde typicky dojde k replikaci vyhledáním dalších vhodných souborů k infekci nebo ke spuštění aktivační rutiny a konečně k obnovení hostitele zkopírováním původních bajtů na začátek programu (offset CS:0x100, což je paměťová adresa, na kterou systém nahrává COM soubory) a skokem
Počítačové viry – analýza útoku a obrana
129
zpět na CS:0x100. Soubory COM se nahrávají na tuto adresu proto, že prefix segmentu programu (program segment prefix, PSP) je umístěn na CS:0 - CS:0xFF. Obrázek 4.6 znázorňuje, jak připojující COM virus infikuje hostitelský program.
Obrázek 4.6
Typický způsob infekce připojujícím virem.
Technika připojení na konec souboru se dá implementovat pro libovolný typ spustitelného souboru, například pro EXE, NE, PE, ELF atd. Takové soubory mají hlavičku, která obsahuje adresu hlavního vstupního bodu, který je většinou nahrazena novým vstupním bodem, kterým je začátek virového kódu, připojeného na konec hostitele. Část 4.3 je věnovaná technikám infekce systému Win32 a demonstruje principy technik infekce moderních souborových formátů. Tyto formáty mají obvykle složité interní struktury a nabízející útočníkům více možností.
4.2.4 Viry připojující se na začátek souboru Tato častá technika infekce je založena na principu vložení virového kódu na začátek hostitele. Takové viry nazýváme jako viry připojující se na začátek hostitele, neboli prependery. Jedná se o jednoduchý, avšak úspěšný způsob infekce, který autoři virů implementovali na různých operačních systémech. Příkladem takového viru je maďarský virus Polimer.512.A, který na začátek hostitele připojuje svůj 512 bajtů dlouhý kód, a který posune obsah hostitelského souboru tak, aby jej následoval. Podívejme se na začátek tohoto viru v DOSovém DEBUGu. Polimer je vhodným příkladem, protože začátek viru obsahuje neškodnou datovou oblast se zprávou, která se zobrazí během spuštění infikovaných programů. >DEBUG polimer.com -d 142F:0100
E9 80 00 00 3F 3F 3F 3F-3F 3F 3F 3F 43 4F 4D 00
....????????COM.
130
Kapitola 4 – Klasifikace metod infekce
142F:0110
05 00 00 00 2E 8B 26 68-01 00 00 00 00 00 00 00
......&h........
142F:0120
00 00 00 00 00 00 00 00-41 20 6C 65 27 6A 6F 62
........A le’job
142F:0130
62 20 6B 61 7A 65 74 74-61 20 61 20 50 4F 4C 49
b kazetta a POLI
142F:0140
4D 45 52 20 6B 61 7A 65-74 74 61 20 21 20 20 20
MER kazetta !
142F:0150
56 65 67 79 65 20 65 7A-74 20 21 20 20 20 20 0A
Vegye ezt ! .
Virové tělo se nahraje do paměti na offset 0x100. Kód začíná instrukcí skoku (0xe9), která předá řízení virovému kódu, jenž následuje za datovou oblastí. Protože je Polimer 512 bajtů (0x200) dlouhý, bude offset hostitelského programu v paměti tento: 0x300 (0x100+0x200=0x300). A skutečně, v naší ukázce je infikovaný program Free Memory Query. COM prependery mohou jednoduše spustit hostitelský program tak, že zkopírují původní obsah programu na offset 0x100 a předají mu řízení. -d300 142F:0300
E9 9E 00 0D 46 72 65 65-20 4D 65 6D 6F 72 79 20
....Free Memory
142F:0310
51 75 65 72 79 20 50 72-6F 67 72 61 6D 2C 20 56
Query Program, V
142F:0320
65 72 73 69 6F 6E 20 34-2E 30 33 0D 0A 53 4D 47
ersion 4.03..SMG
142F:0330
20 53 6F 66 74 77 61 72-65 0D 0A 28 43 29 20 43
Software..(C) C
142F:0340
6F 70 79 72 69 67 68 74-20 31 39 38 36 2C 31 39
opyright 1986,19
142F:0350
38 37 20 53 74 65 76 65-6E 20 4D 2E 20 47 65 6F
87 Steven M. Geo
142F:0360
72 67 69 61 64 65 73 0D-0A 1A 00 00 00 00 00 00
rgiades.........
Obrázek 4.7 demonstruje, jak se prepender vkládá na začátek programu.
Obrázek 4.7
Typický virus, který se připojuje na začátek hostitele.
Prependery bývají obvykle napsány v pokročilých programovacích jazycích, jakým je třeba jazyk C, Pascal nebo Delphi. V závislosti na aktuální struktuře spustitelného souboru nemusí být infekce programu tak triviální, jako v případě COM souborů. Přesně z tohoto důvodu viry na disku vytváří dočasný soubor, který obsahuje původní hostitelský program, přičemž pro jeho spuštění se použije funkce typu system(). Takové viry obvykle předají parametry příkazové řádky původnímu programu a tím zachovají funkčnost aplikace, která by mohla být narušena chybějícími parametry.
Počítačové viry – analýza útoku a obrana
131
4.2.5 Klasické parazitické viry Variantou techniky připojení na začátek souboru je technika známá jako klasická parazitická infekce, znázorněná na obrázku 4.8. Takové viry přepíší začátek hostitele vlastním kódem a uloží jej na jeho úplný konec, obvykle na offset délky viru. První takový virus byl Virdem, napsaný Ralfem Burgerem. Ve skutečnosti je Virdem jedním z prvních příkladů souborových virů, který byl zaznamenán; Burgerova kniha nikdy neobsahovala informace o jiných než souborových virech. Burger rozšířil svůj výtvor na konferenci Chaos Computer Clubu v prosinci roku 1986. Často se po vyléčení takto zavirovaných souborů objeví obvyklé problémy. V mnoha případech se oprava provede tak, že se zkopíruje N bajtů na začátek souboru a soubor se zkrátí o velikost souboru mínus N, kde N je typicky velikost viru (ovšem délka souboru se může měnit). Nejčastější příčinou nekorektního léčení je mnohonásobná infekce, tedy situace, kdy je soubor infikován více než jednou.
Obrázek 4.8
Klasický parazitický virus.
V jiných případech má soubor na svém konci nějaká speciální data, jako například dodatečné informace vložené nějakým antivirovým programem. Například virus Jerusalem používal značku MS-DOSu umístěnou na konci souboru, aby rozeznal soubory, které jsou už infikované. Některé z prvních antivirových programů připojovaly na konec všech COM a EXE programů tento řetězec, aby tak zamezily opětovné infekci Jerusalemem. Ačkoliv to může znít jako dobrý nápad, takové změny souborů mohou dezinfekčním programům způsobit problémy. K tomu může dojít třeba v případě, že takto označený soubor byl už napaden jiným parazitickým virem. Jestliže se pro vyléčení souboru použije výpočet "velikost souboru-N", sáhne opravná rutina třeba o 5 bajtů dál za původním programem. Toto léčení pak bude mít za následek poškození programu, který zhavaruje po každém svém spuštění. Tomuto druhu dezinfekce se říká "rychlokvašená oprava" (half-cooked repair10). Některé speciální parazitické infektory neukládají začátek hostitele na jeho konec a místo toho používají dočasný soubor k uložení této informace mimo hostitele, někdy se skrytými atributy. Například maďarský DOS virus Qpa tuto techniku používá a ukládá 333 bajtů (velikost viru) do speciálního souboru.
132
Kapitola 4 – Klasifikace metod infekce
Tuto techniku používají také členové nechvalně známé rodiny virů W32/Klez pro uložení celého hostitelského programu v novém souboru.
4.2.6 Dutinové viry Dutinové viry (cavity viruses), znázorněné na obrázku 4.9, obvykle nezvětšují velikost svého hostitele. Místo toho přepíší určitou oblast souboru, do které se mohou bezpečně vložit. Tyto infektory většinou přepisují oblasti binárních souborů, které obsahují nuly, nicméně mohou přepsat i bloky 0xCC, které často používají kompilátory jazyka C pro zarovnání instrukcí. Jiné viry zase přepisují oblast s mezerami (bajty 0x20). Prvním virem, který začal používat tuto techniku, byl Lehigh v roce 1987. Lehigh byl vcelku neúspěšný virus, nicméně Ken van Wyk zajistil viru mnoho publicity a vytvořil na Usenetu diskusní skupinu VIRUS-L, aby s ostatními prodiskutoval svoje poznatky.
Obrázek 4.9
Mezerový virus, který sám sebe vkládá do mezery v hostiteli.
Dutinové viry obvykle bývají DOS infektory s pomalým šířením. Například bulharské viry Darth Vader nikdy nepůsobily velké škody, především kvůli faktu, že se jedná o pomalý infektor. Vždy počkal, až se program sám zapíše a teprve pak na něj zaútočil. Virus W2K/Installer (autoři Benny a Darkman) používá tuto techniku k infekci Win32 PE souborů na Windows 2000 bez zvětšování jejich velikosti. Speciální druh těchto virů zneužívá relokační sekce PE programů. Relokace spustitelných souborů ve většině případů nejsou zapotřebí a novější linkery dovedou zkompilovat spustitelné PE soubory bez relokačních tabulek, čímž tak zmenšit velikost výsledného programu. Dutinové viry útočící na relokace přepíší relokační sekci (pokud ji v programu naleznou). Jestliže je relokační sekce menší než virový kód, virus velikost souboru nezvětší, protože soubor jednoduše nenapadne. Takové viry si pečlivě ověřují, jestli je relokační sekce dostatečně velká nebo zdali je alespoň poslední v pořadí, jinak by došlo k poškození souboru. Tuto techniku například používají rodiny virů W32/CTX a W95/Vulcano.
Počítačové viry – analýza útoku a obrana
133
4.2.7 Dělené dutinové viry Několik virů pro Windows 95 používá dutinovou techniku infekce extrémně úspěšným způsobem, příkladem může být například virus W95/CIH. Jeho virový kód je rozdělený na zaváděcí rutinu a N sekcí. Zaváděcí rutina (hlavička) viru nejprve nalezne zbylé části virového kódu a načte je do spojité paměti (s pomocí tabulky offsetů, která je uložena v hlavičce). Při infikování virus nejprve najde dostatek prázdných míst v PE souboru a do nich pak nakopíruje jednotlivé části kódu. Nový vstupní virový bod bude zaznamenán v hlavičce souboru a bude ukazovat na začátek virového kódu, který je obvykle umístěný někde uprostřed hlavičky hostitele. Některé kratší dutinové infektory, jako je třeba Murkry, používají tuto oblast k infekci souborů v jednom kroku. CIH je nicméně delší a potřebuje svůj kód rozdělit do menších částí. Virus spustí hostitelský program skokem na původní uložený vstupní bod. Výhodou této techniky je to, že si virus potřebuje zapamatovat pouze původní vstupní bod hostitele. V načteném programu pak pouze stačí skočit na tu správnou adresu. Obrázek 4.10 znázorňuje stav hostitelského programu před a po infekci děleným dutinovým virem. Hostitel by normálně začal na svém vstupním bodu, který je definovaný v hlavičce. Virus nahradí tento bod virovým vstupním bodem, který ukazuje na začátek zavaděče, který poté načte zbývající části kódu. V případě, že v souboru není dostatek místa pro uložení celého zavaděče do jedné části kódu, infekce neproběhne. V moderních souborových formátech, jakým je třeba PE, bývají mezery k dispozici a dají se jednoduše najít s použitím informací uložených v hlavičkách sekcí.
Obrázek 4.10
Dělený dutinový virus.
Jedním ze speciálních problémů těchto virů je skutečnost, že obsah přepsaných oblastí nemůže být stoprocentně obnoven. K tomu dochází hlavně v případě virů, které přepíší oblast souboru, která obvykle obsahuje nuly, nicméně v tomto konkrétním případě obsahuje něco jiného. Potom nebudou kryptografické kontrolní součty po vyléčení souboru odpovídat. Také se zkomplikuje přesná identifikace takových virů, protože je nutné, aby byly kousky kódu poskládány dohromady. Detekce takových virů je založena na obsahu zaváděcí rutiny, která musí být uložena v jediné části kódu.
134
Kapitola 4 – Klasifikace metod infekce
4.2.8 Komprimující viry Tato speciální virová technika využívá možnosti zkomprimovat obsah hostitelského programu. Binární zkomprimování hostitele se někdy používá pro skrytí nárůstu délky infikovaného souboru. Komprimující viry se občas nazývají "užitečnými" ;-), protože dovedou zkomprimovat svého hostitele o mnoho více, než jej prodloužit, čímž šetří místo na disku. Tzv. runtime komprimační programy, jako PKLITE, LZEXE, UPX nebo ASPACK, jsou velmi oblíbené, nicméně jsou často zneužívány útočníky pro zkomprimování trojských koní, počítačových virů a červů tak, aby byly menší a daly se hůře analyzovat. DOSový virus Cruncher byl první, který přišel s kompresní technikou. Některé 32bitové viry pro Windows ji také používají, jako třeba W32/HybrisF (souborový infektor červa Hybris ve formě plug-inu), jehož autor si říká Vecna. Dalším nechvalně známým představitelem je W32/Aldebera, který kombinuje metody infekce s polymorfismem. Aldebera se snaží zkomprimovat hostitele tak, že jeho velikost zůstane po infekci stejná. Byl vytvořen v roce 1999 členem virové skupiny IKX B0/S0 (Bozo). Virus W32/Redemption napsaný Jackem Qwertmy také používá kompresní techniku k infekci 32bitových PE souboru na Windows. Obrázek 4.11 znázorňuje, jak komprimující viry útočí na soubory.
Obrázek 4.11
Komprimující virus.
4.2.9 Infekce typu Amoeba Amoeba je typ neobvyklé techniky infekce, která připojuje hostitelský program doprostřed virového těla. To se učiní připojením hlavičky viru na začátek a konec hostitele. Původní program se zrekonstruuje, uloží a spustí jako nový soubor na disku. Tuto techniku používá k infekci PE souborů na systémech Windows například virus W32/Sand.12300, vytvořený autorem Alcopaul a naprogramovaným ve Visual Basicu. Na obrázku 4.12 je vidět hostitelský program před a po infekci virem, který používá techniku Amoeba.
KAPITOLA 7 Pokročilé techniky vývoje kódu a generátory počítačových virů "V matematice nemůžete porozumět věcem. Můžete je pouze používat." – John von Neumann
230
Kapitola 7 – Pokročilé techniky vývoje kódu a generátory počítačových ...
V této kapitole se dozvíte o vylepšených obranných technikách, které autoři počítačových virů za dlouhá léta vyvinuli, aby odrazili útok antivirových skenerů. Podrobně se dozvíte o zakódovaných, oligomorfních, polymorfních1 a vylepšených metamorfních počítačových virech2. Nakonec se podíváme na generátory3 počítačových virů, které používají podobné techniky k vytvoření odlišně vypadajících variant virů.
7.1 Úvod Zde prozkoumáme různé cesty, po kterých se autoři virů za poslední dekádu vydali, aby porazili antivirové skenery. Ačkoliv byla většina těchto technik použita na zamaskování souborových infektorů, můžeme s jistotou očekávat, že se tyto techniky objeví v budoucích počítačových červech. Za celá ta léta vývoje ušly binární viry velmi dlouhou cestu. Pokud by se někdo vydal po stopách výsledků vývoje virů, došel by k přesvědčení, že takřka všechno myslitelné už bylo učiněno a že se problémy s viry nebudou zvyšovat. Zbývají modely distribuovaných výpočtů, které ještě ve virech spatřeny nebyly.
7.2 Vývoj virového kódu Autoři virů neustále bojují s antivirovými produkty. Jejich největším nepřítelem jsou nejpopulárnější antivirové skenery. Generická antivirová řešení, jako třeba kontrolory integrity dat a monitory blokující podezřelé chování (behavior-blockers) se (narozdíl od nich) nikdy neměla za cíl stát tak populárními. Ve skutečnosti takové generické modely detekce virů vyžaduji na systémech Windows mnohem větší promyšlení návrhu, protože tyto technologie byly na systémech DOS několikrát překonány DOSovými viry. Výsledkem je, že si mnoho lidí začalo myslet, že tyto techniky jsou k ničemu. Skenování je řešení, které trh přijal, bez ohledu na jeho nevýhody. Musí tedy čelit rostoucí složitosti a vzrůstajícímu počtu škodlivého softwaru, který se navíc dokáže sám rozšiřovat. Ačkoliv se moderní výpočetní technika výrazně zrychlila, po dlouhý čas se daly binární kódy virů současnými technikami stěží dohonit. DOSové viry se do roku 1996 vyvíjely do velmi složitých úrovní, od té doby začaly na trhu dominovat 32bitové systémy Windows. Výsledkem bylo, že se autoři virů ve vývoji binárních virů vrátili o několik let zpět. Složitost polymorfismu v DOSu vyvrcholila v roce 1996, když byl představen virus Ply s novým permutačním enginem (metamorfní virus ACG byl představen v roce 1998). Tento vývoj už nicméně nemohl dále pokračovat a tak se pionýři v psaní počítačových virů zaměřili na vyvinutí 32bitových technik pro Win32 platformy. Někteří autoři virů stále chápou platformu Windows jako příliš složitou, zvlášť v případě systémů Windows NT/2000/XP/2003. Základní techniky infekce už nicméně byly k vidění, nehledě na to, že zdrojové kódy samotných virů byly distribuovány na Internetu. Tyto zdrojové kódy poskytují základy pro masově se šířící červy. Navíc nevyžadují nějaké programátorské zkušenosti – pouze schopnost zkopírovat a vložit text. V následující části prozkoumáme základní matoucí techniky virového kódu, zakódovanými viry počínaje a moderními metamorfními technikami konče.
Počítačové viry – analýza útoku a obrana
231
7.3 Zakódované viry Už od samého počátku se autoři virů pokoušeli implementovat do kódu virů nějakou evoluci. Jedním z nejjednodušších způsobů k zamaskování fungování virového kódu bylo kódování. Prvním známým virem, který tuto techniku implementoval, byl DOSový Cascade4. Virus začíná neměnným decryptorem, po kterém následuje zakódované tělo viru. Podívejte se na ukázku decryptoru viru Cascade.1701, který je zobrazen ve výpise 7.1.
Výpis 7.1 Decryptor viru Cascade. lea
si, Start
; začátek zakódovaného těla (nastaveno dynamicky)
mov
sp, 0682
; délka zakódovaného těla (1666 bajtů)
Decrypt: xor
[si],si
; první dekódování
xor
[si],sp
; druhé dekódování
inc
si
; inkrementace prvního čítače
dec
sp
; dekrementace druhého
jnz
Decrypt
; smyčka proběhne tolikrát, než se dekódují všechny bajty
Start:
; Začátek zakódovaného/dekódovaného těla viru
Tento decryptor používá trik proti ladění, protože používá jako jeden z dekódovacích klíčů registr SP (stack pointer, ukazatel na zásobník). Dekóduje se vždy směrem dopředu, registr SI se inkrementuje o jedničku. Protože registr SI zprvu ukazuje na začátek zakódovaného těla viru, jeho počáteční hodnota závisí na relativní pozici virového těla v souboru. Cascade se připojuje na konec souboru, takže SI bude mít stejnou hodnotu v případě souborů o stejné velikosti. SI (dekryptovací klíč 1) se bude ovšem lišit, pokud mají hostitelské programy různou velikost. Registr SP je prostý čítač počtu bajtů k dekódování – jde tedy směrem dopředu a dekóduje se po slovech (2 bajty), ale místo dekódování se posunuje o jeden bajt. To decryptovací smyčku trochu komplikuje, ale nic nemění na její reverzibilitě. Operace XOR je pro viry velmi praktická, protože "XORování" stejné hodnoty dvakrát vrátí původní hodnotu. Uvažte kódování písmena P (0x50) klíčem 0x99. Tedy 0x50 XOR 0x99 je 0xC9 a 0xC9 XOR 0x99 vrátí 0x50. Proto mají autoři virů v oblibě tuto techniku zakódování – protože jsou líní! Omezí tak nutnost implementovat dva rozdílné algoritmy, jeden pro zakódování a druhý pro dekódování. Kryptograficky řečeno – takové kódování je slabé, ačkoliv první antivirové programy měly možnost získat krátký skenovací řetězec ze samotného decryptoru. To ovšem vedlo k několika problémům. Různé viry mohou mít například stejný decryptor, ale kompletně jiné vlastnosti. Detekcí viru podle jeho decryptoru se pak může stát, že antivirus nedovede správně identifikovat příslušnou variantu. A dále – nevirové programy, třeba různé obálky (wrappers) s ochranami proti ladění, mohou mít na začátku svého kódu podobný decryptor. Virus, který používá stejný kód pro svoje dekódování, tak může antivirový program zmást.
Kapitola 7 – Pokročilé techniky vývoje kódu a generátory počítačových ...
232
Taková jednoduchá metoda vývoje kódu se záhy objevila i v 32bitových virech pro Windows. W95/Mad a W95/Zombie používají stejnou techniku jako virus Cascade, jediný rozdíl spočívá v 32bitové implementaci. Podívejte se na decryptor z viru W95/Mad.2736 ve výpise 7.2.
Výpis 7.2 Decryptor viru W95/Mad.2736. mov
edi,00403045h
; EDI = začátek
add
edi,ebp
; přidej bázovou adresu
mov
ecx,0A6Bh
; délka zakódované části těla viru
mov
al,[key]
; načti klíč
xor
[edi],al
; dekóduj jeden bajt těla
inc
edi
; inkrementuj místo dekódování
loop
Decrypt
; dekóduj všechny bajty
jmp
Start
; Skoč na Start (přes data)
DB
key
Decrypt:
Start:
86
; proměnný klíč o velikosti jeden bajt ; zakódované/dekódované tělo viru
Jedná se o ještě jednodušší implementaci metody XOR. Detekce takových virů je stále možná bez nutnosti dekódovat tělo viru. Ve většině případů je vzorek kódu decryptoru těchto virů dostatečně unikátní, aby se tyto viry daly podle něj detekovat. Tato detekce sice není exaktní, nicméně stále existuje možnost dekódovat zakódované tělo viru a detekovat i různé varianty. Útočník může implementovat některé speciální techniky, aby proces kódování a dekódování více zkomplikoval a zmátl detekci, popř. léčení zavirovaných souborů antivirovými programy:
Směr dekódovací smyčky se může měnit, je možné kódovat směrem dopředu i dozadu (viz obrázek 7.1).
Použití vícenásobných vrstev kódování. První decryptor dekóduje druhý, ten dekóduje třetí a tak dále (viz obrázek 7.1c). Viry Hare5 od Demon Emperora, W32/Harrier6 od TechnoRata, {W32,W97M}/Coke od Vecny a W32/Zelly od ValleZe jsou příklady virů, které používají tuto metodu.
Některé decryptovací smyčky získávají řízení jedna po druhé s náhodně zvoleným směrem dekódování. Tato technika kód zpřehází nejvíc (viz obrázek 7.1c).
Existuje pouze jedna decryptovací smyčka, ale používá více než dva klíče k dekódování všech částí informace. V závislosti na implementaci decryptoru mohou být takové viry mnohem obtížněji detekovatelné. Dost záleží na velikosti klíče – čím je klíč větší (8, 16, 32 bitů nebo ještě více), tím déle bude dekódování hrubou výpočetní silou trvat (v případě, že klíče nemohou být jednoduše z viru vyextrahovány).
Počítačové viry – analýza útoku a obrana
233
Obrázek 7.1 Příklady dekódovacích smyček.
Začátek decryptoru je utajen. Mezi decryptorem a zakódovaným tělem nebo zakódovaným tělem a koncem souboru jsou umístěny náhodné bajty.
Použije se nelineární dekódování. Některé viry, jako třeba W95/Fono používá jednoduchý nelineární algoritmus s tabulkou klíčů. Kódování viru je založeno na substituční tabulce, virus se například rozhodne nahradit písmena A za Z, P za L atd., takže takové slovo APPLE bude po takovém zakódování vypadat jako ZLLPE. Protože dekódování viru není lineární, virové tělo se nedekóduje bajt po bajtu. To může jednoduše oklamat virové analytiky-začátečníky, protože virus nemusí vypadat, že je zakódovaný. Pokud se potom použije některý řetězec pro detekci viru, bude detekce fungovat jen částečně. Tato technika dovede přelstít i vylepšené techniky detekce, které používají emulátor. Ačkoliv by v normálním případě emulace pokračovala tak dlouho, dokud by se nenarazilo na lineární dekódování, za což se může považovat postupná změna bajtů v paměti virtuálního stroje skeneru, bude emulace pokračovat dál, dokud se nenarazí na limit. Varianta viru W32/Chiton ("Efish") používá podobnou metodu jako Fono, ale vždy se ujistí, že je každý bajt těla viru nahrazen jiným bajtem použitím kompletní substituční tabulky. Chiton navíc pro každý bajt kódu používá různé hodnoty, což znatelně komplikuje proces dekódování. Viry jako třeba W95/Drill a {W32,Linux}/Simile.D reprezentují vrchol umění nelineárního zakódování, kde se dekóduje tělo viru v pseudonáhodném pořadí a každé místo v kódu se dekóduje jen jednou7.
Útočník se může rozhodnout neukládat kódovací klíč a místo toho se pokusí ke svému dekódování použít hrubou sílu, pomocí které získá kódovací klíče po svém. Takové viry používající RDA techniky (Random Decryption Algorithm, náhodný dekódovací algoritmus) jsou mnohem hůře detekovatelné. Příkladem viru, který používá takovou techniku, je RDA.Fighter.
Útočník může použít silný algoritmus pro zakódování těla viru. Rodina viru IDEA napsaná autorem, který si říká Spanska, využívá tuto metodu. Jeden z několika decryptorů používá šifru IDEA8. Protože virus sebou nese dekódovací klíč, zakódování se nedá považovat za silné, avšak
234
Kapitola 7 – Pokročilé techniky vývoje kódu a generátory počítačových ... léčení takto napadnutých souborů je problém, protože antivirové programy musí implementovat kódovací algoritmus, který si s použitým zakódováním poradí. Druhá dekódovací vrstva viru IDEA9 navíc používá RDA.
Český virus W32/Crypto od Prizzyho demonstroval použití Microsoft Crypto API v počítačových virech. Crypto za běhu kódoval DLL knihovny na infikovaném systému s použitím dvojice klíčů (soukromý a veřejný klíč). Jiné počítačové červy a backdoory (tzv. zadní vrátka) také používají Crypto API k dekódování zakódovaného obsahu, což činí práci antivirových skenerů obtížnější. Příkladem počítačového červa, který používá Crypto API, je například W32/Qint@mm, který zakódovává EXE soubory.
Samotný decryptor někdy není součástí viru. Viry jako třeba W95/Resur10 a W95/Silcer jsou představiteli této metody. Tyto viry donutí zavaděč systému Windows k přesunutí (relocate) infikovaných modulů, jakmile se načítají do paměti. Samotná relokace modulu je zodpovědná za dekódování virového těla, protože do něj virus vložil speciální relokační záznamy. Bázová adresa spustitelného modulu v tomto případě funguje jako kódovací klíč.
Virus Cheeba demonstroval, jak může být kódovací klíč uložen mimo tělo viru. Cheeba byl vypuštěn v roce 1991 a jeho tzv. payload (aktivační rutina viru) se zakóduje jménem souboru a dekóduje se správně pouze tehdy, když virus přistupuje k souboru11. Pokud není šifra viru slabá, antiviroví výzkumníci jednoduše nemohou popsat payload viru. Dmitry Gryaznov zredukoval (s použitím kryptoanalýzy těla viru) velikost klíče potřebného k útoku na šifru Cheeby na pouhých 2150400 možných klíčů, za předpokladu, že zašifrovaný kód je napsaný podobným stylem jako zbytek kódu viru12. Výsledkem bylo nalezení správného jména souboru – "user.bss". Tento soubor patřil k populárnímu softwaru pro BBS. Je pravděpodobné, že se časem objeví více takových triků (tzv. "clueless agents"13), které znesnadní získávání znalostí o daném nebezpečí, které hrozí ze strany útočníka.
Kódovací klíče mohou být generovány různými způsoby, např. konstantně, náhodně, fixně, s posunutím atd.
Samotný klíč může být uložen v decryptoru, v hostiteli nebo nikde. V některých případech kód decryptoru funguje jako dekódovací klíč, což může způsobovat problémy tehdy, pokud debugger nějak poškodil decryptor. Tato technika může rovněž posloužit jako útok na emulátory, které používají techniky optimalizace kódu pro efektivnější běh decryptorů (příkladem takového viru je například Tequila).
Náhodnost klíče je také důležitým faktorem. Některé viry generují nové klíče pouze jednou za den a označují se jako pomalé generátory. Jiní dávají přednost generování klíčů pokaždé, když infikují soubor – ty se označují jako rychlé generátory. Útočník může k dosažení náhodnosti použít mnoho různých metod. Jednoduché příklady zahrnují časovač nebo datum a čas uložený v CMOS a CRC32. Složitějším příkladem je generátor pseudonáhodných čísel Mersenne Twister14 použitý ve virech W32/Chiton a W32/Beagle.
Útočník může označit některá místa jako místa určená dekódování zakódovaného obsahu. Nejčastější metody jsou zobrazeny na obrázku 7.2.
Počítačové viry – analýza útoku a obrana
235
Obrázek 7.2 Možná místa pro dekódování. A) Decryptor dekóduje data na místě zakódovaného těla viru. Tato metoda je nejběžnější, zakódovaná data musí být ovšem v paměti zapisovatelná, což je věc konkrétního operačního systému. B) Decryptor čte zakódovaný obsah a buduje dekódované tělo viru na zásobníku. To je pro útočníka velmi praktické, protože je zásobník zapisovatelný automaticky. C) Virus alokuje paměť pro dekódované tělo a data. To může být určitá nevýhoda, protože útočník potřebuje před samotným dekódováním prvně alokovat paměť.
Poznámka Některé metamorfní viry, jako třeba Simile, tuto nevýhodu vyřešily tak, že kód viru, který se stará o alokaci paměti, je dostatečně variabilní na to, aby se z něj dal vybrat vyhledávací řetězec.
Předchozí techniky fungují velmi efektivně, když se zkombinují s variabilními decryptory, které se postarají o změny v nových generacích viru. V následujících částech jsou probrány oligomorfní a polymorfní decryptory, které se ve virech používají.
7.4 Oligomorfní viry Autoři virů velmi rychle přišli na to, že se detekce zakódovaných virů pro antivirový software odvíjí od toho, jak dlouhý a jedinečný je samotný decryptor. Aby antivirové produkty překonali, rozhodli se implementovat techniky, které umí vytvářet mutované decryptory. Narozdíl od zakódovaných virů ty oligomorfní mění v nových generacích svůj decryptor. Nejjednodušší technikou ke změně decryptorů je použití více decryptorů namísto jednoho. Prvním takovým známým virem byl Whale, který si sebou nesl pár tuctů rozdílných decryptorů, přičemž si vždy jeden z nich náhodně vybral.
Kapitola 7 – Pokročilé techniky vývoje kódu a generátory počítačových ...
236
W95/Memorial měl schopnost vystavět až 96 různých decryptorů. Proto byla detekce viru, která byla založena na hledání kódu decryptoru, nepraktickým, ačkoliv stále použitelným řešením. Většina antivirových produktů se pokusila tento problém řešit dynamickým dekódováním zakódovaného těla, čímž byla ovšem detekce stále založena na konstantním kódu dekódovaného těla viru. Podívejte se na příklad z viru Memorial zobrazený ve výpisu 7.3, jedná se o jeden z 96ti možných případů decryptoru.
Výpis 7.3 Příklad decryptoru viru W95/Memorial. mov
ebp,00405000h
; načti bázi
mov
ecx,0550h
; počet bajtů
lea
esi,[ebp+0000002E]
; offset "Start"
add
ecx,[ebp+00000029]
; plus tento počet bajtů
mov
al,[ebp+0000002D]
; vyber první klíč
Decrypt: nop
; smetí
nop
; smetí
xor
[esi],al
; dekóduj bajt
inc
esi
; přesuň ukazatel na další
al
; posuň klíč
nop inc
; smetí
dec
ecx
; jsou tam nějaké další bajty k dekódování?
jnz
Decrypt
; skákej, dokud nejsou všechny bajty dekódované
jmp
Start
; dekódování u konce, spusť tělo ; datová oblast
Start: ; zakódované/dekódované tělo viru
Povšimněte si posunu klíče. Pořadí instrukcí může být lehce měněno a decryptor může pro smyčku používat odlišné instrukce. Porovnejte tento příklad s jiným decryptorem z výpisu 7.4.
Výpis 7.4 Lehce odlišný decryptor viru W95/Memorial. mov
ecx,0550h
; počet bajtů
mov
ebp,013BC000h
; načti bázi
lea
esi,[ebp+0000002E]
; offset"Start"
add
ecx,[ebp+00000029]
; plus tento počet bajtů
mov
al,[ebp+0000002D]
; vyber první klíč
Decrypt: nop
; smetí
Počítačové viry – analýza útoku a obrana nop
; smetí
xor
[esi],al
; dekóduj bajt
inc
esi
; přesuň ukazatel na další bajt
nop inc
237
; smetí al
; posuň klíč
loop
Decrypt
; skákej dokud nejsou všechny bajty dekódované
jmp
Start
; dekódování u konce, spusť tělo ; datová oblast
Start: ;
zakódované/dekódované tělo viru
Všimněte si výskytu instrukce "loop" a prohození instrukcí na začátku decryptoru. Virus je oligomorfní tehdy, pokud je schopný měnit svůj decryptor (v omezeném rozsahu). Je zajímavé, že některé produkty, které jsme testovali, nebyly schopny zachytit všechny instance viru Memorial. To proto, že pro nalezení a pochopení generátoru oligomorfního decryptoru je potřeba prozkoumat takové viry do nejmenších detailů. Bez patřičné ruční analýzy se nedají pomalé oligomorfní viry spolehlivě detekovat. Například decryptor viru Badboy15 se mění po jedné instrukci – a velmi mimořádně. Jedná se o velkou výzvu pro centra zabývající se automatickou analýzou virů. Jiným příkladem oligomorfních virů je ruská rodina virů nazvaná jako WordSwap.
7.5 Polymorfní viry Dalším krokem v úrovni obtížnosti je polymorfní útok. Polymorfní viry umějí měnit svůj decryptor do vysokého počtu odlišných instancí, které mohou mít až milióny různých forem.
7.5.1 Virus 1260 Prvním známým polymorfním virem byl virus 1260, který byl naprogramován ve Spojených Státech Markem Washburnem v roce 199016. Tento virus používal mnoho zajímavých technik, jejichž příchod už dříve předpověděl Fred Cohen. Virus používal k dekódování svého těla dva posunující se klíče, a co je ještě důležitější – vkládal nepotřebné instrukce do svého decryptoru. Tyto instrukce jsou v podstatě obyčejným "smetím" a nemají jinou funkci než vytvoření variabilnějšího decryptoru. Antivirové skenery byly virem 1260 poraženy, protože nebylo možné najít jednoznačný řetězec, podle kterého by bylo možné virus detekovat. Ačkoliv je decryptor viru 1260 velmi jednoduchý, může se zvětšovat a zmenšovat v závislosti na množství vložených nepotřebných instrukcí a náhodného zarovnání na konci decryptoru až po 39 bajtů smetí. Navíc každá skupina instrukcí (prolog, dekódování a inkrementace) vně decryptoru může být obměňována v libovolném pořadí. Kostra decryptoru se tedy může měnit. Podívejte se na příklad jedné instance decryptoru vyextrahovaného z viru 1260 (viz výpis 7.5).
Kapitola 7 – Pokročilé techniky vývoje kódu a generátory počítačových ...
238 Výpis 7.5
Příklad decryptoru viru 1260. ; Skupina 1 – Instrukce prologu inc
si
; volitelné, náhodné smetí
mov
ax,0E9B
; nastav klíč 1
di,012A
; offset "Start"
cx,0571
; počet bajtů – klíč 2
clc
; volitelné, náhodné smetí
mov nop
; volitelné, náhodné smetí
mov
; Skupina 2 – Dekódovací instrukce Decrypt: xor
[di],cx
; dekóduj první slovo klíčem 2
sub
bx,dx
; volitelné, náhodné smetí
xor
bx,cx
; volitelné, náhodné smetí
sub
bx,ax
; volitelné, náhodné smetí
sub
bx,cx
; volitelné, náhodné smetí
nop
; nevolitelné smetí
xor
dx,cx
; volitelné, náhodné smetí
xor
[di],ax
; dekóduj první slovo klíčem 1
; Skupina 3 – Dekódovací instrukce inc
di
; další bajt
nop
; nevolitelné smetí
clc
; volitelné, náhodné smetí
inc
ax
; posuň klíč 1
Decrypt
; skákej, dokud nejsou všechny bajty dekódovány – ; posuň klíč 2
; smyčka loop
; náhodné zarovnání až do 39 bajtů Start: ;
zakódované/dekódované tělo viru
V každé skupině instrukcí je umístěno až 5 instrukcí smetí (INC SI, CLC, NOP a další, nic nedělající instrukce) bez opakování. Jsou tam vždy dvě instrukce smetí NOP. 1260 nezvládá nahrazování registrů, ale složitější polymorfní útoky tento trik používají. Virus 1260 má nicméně efektivní polymorfní engine, který umí generovat vysoký počet rozličných decryptorů.
7.5.2 Dark Avengerův mutovací engine (MtE) Dalším důležitým milníkem v historii vývoje polymorfních virů byl MtE17, mutační engine napsaný Dark Avengerem z Bulharska. První verze MtE byla vypuštěna během léta roku 1991, druhá následovala
Počítačové viry – analýza útoku a obrana
239
počátkem roku 1992. Myšlenka mutovacího enginu byla založena na modulárním vývoji. Pro nováčky bylo obtížné napsat polymorfní virus, a proto jim chtěli schopnější autoři pomoci. Motor MtE byl vypuštěn jako objekt, který se dá připojit k libovolnému viru. MtE je navržen jako volání funkce mutovacího enginu, kdy se předávají parametry v předdefinovaných registrech. Engine se pak už sám postará o vybudování polymorfní obálky nad virem. Parametry enginu zahrnují následující:
Pracovní segment.
Ukazatel na kód, který se má zakódovat.
Délku těla viru.
Báze decryptoru.
Adresu vstupního bodu hostitele.
Cílové umístění zakódovaného těla.
Velikost decryptoru (drobný, malý, střední nebo velký).
Bitové pole registrů, které se nemají používat.
Výstupem MtE je polymorfní dekódovací rutina se zakódovaným tělem viru umístěným v zadaném bufferu (viz výpis 7.6).
Výpis 7.6 Příklad decryptoru vygenerovaného pomocí MtE. mov
bp,A16C
; Tento blok inicializuje registr BP
mov
cl,03
; (delta je v tomto případě 0x0D2B)
ror
bp,cl
mov
cx,bp
mov
bp,856E
or
bp,740F
mov
si,bp
mov
bp,3B92
add
bp,si
xor
bp,cx
sub
bp,B10C
; na "Start"-delta
; Tak, registr BP je konečně inicializován, ; ovšem dále obsahuje matoucí ukazatel ; na zakódované tělo
Decrypt: mov
bx,[bp+0D2B] ; vyber další záznam
add
bx,9D64
xchg
[bp+0D2B],bx ; ulož dekódovanou hodnotu na místo
; (poprvé na"Start") ; dekóduj ho
240
Kapitola 7 – Pokročilé techniky vývoje kódu a generátory počítačových ...
mov
bx,8F31
sub
bx,bp
; inkrementuj BP o 2
mov
bp,8F33
sub
bp,bx
; a oprav délku
jnz
Decrypt
; jsou už všechny bajty dekódované?
Start: ; zakódované/dekódované tělo viru
Tento příklad demonstruje, jak je takový engine komplikovaný. Přišli byste na to, jak jej detekovat? Zdá se být logické, abychom se prvně pokusili shromáždit dostatečně velké množství vzorků. Poprvé mi to trvalo celkem 5 dní, než jsem byl schopen pro něj napsat spolehlivý detektor. MtE dovedlo produkovat některé decryptory, které se objevily jen v 5% (nebo ještě méně) případech. Engine měl nicméně několik malých omezení, které umožnily (s pomocí disassembleru délky instrukcí a stavového stroje) virus spolehlivě detekovat. Ve skutečnosti existuje pouze jeden jediný konstantní bajt v MtE decryptoru, a to 0x75 (JNZ), který je následován záporných offsetem – i tento skok je umístěný na variabilním místě (na konci decryptoru, jehož délka není konstantní).
Poznámka MtE nepoužívá v decryptoru instrukce smetí, jako to dělá například virus 1260. MtE tedy útočí na techniky, které se snaží optimalizovat decryptory, aby překonaly polymorfismus.
Dopad MtE na antivirový software byl jasný – většina enginů antivirových programů musela projít bolestivým přeprogramováním a nutností implementovat ve skenovacím enginu virtuální stroj. Jak pravil Frans Veldman, "prostě necháme virus, aby odvedl špinavou práci za nás." Po MtE rychle přišly další podobné enginy, jako třeba TPE (Trident Polymorphic Engine), který vytvořil Masouf Khafir v Holandsku v roce 1993. V dnešní době jsou známy stovky polymorfních enginů. Většina z nich byla použita k vytvoření pouze několika virů. Jakmile lze detekovat polymorfní decryptor, jeho další používání se stává nevýhodou, protože další nové viry se dají zachytit stejnou detekcí. Taková detekce ovšem sebou nese jistá úskalí ve formě falešných poplachů. Spolehlivější techniky detekce spočívají v rozpoznání samotného těla viru. To umožňuje autorům virů úspěšně používat stejné polymorfní enginy pro různé viry – až do doby, než budou takové viry odhalitelné heuristickými nebo generickými metodami detekce.
7.5.3 32bitové polymorfní viry W95/HPS a W95/Marburg18 byly prvními viry, které začaly používat 32bitové polymorfní enginy. Tyto dva viry byly vytvořeny známým španělským autorem virů, který si říkal GriYo, a to v roce 1998. Ten také vytvořil vysoce polymorfní viry pro DOS, jako třeba virus Implant19.
Počítačové viry – analýza útoku a obrana
241
Stejně jako polymorfní engine Implantu je i engine viru HPS velmi výkonný a vyspělý. Podporuje subrutiny s použitím instrukcí CALL/RET a podmíněné skoky s nenulovým offsetem. Kód polymorfního enginu zabírá zhruba polovinu kódu viru a mezi vygenerované bloky decryptoru se umisťují náhodné bajty dat. Celý decryptor se vybuduje pouze během fáze inicializace viru, čímž je zajištěn pomalý polymorfismus, což znamená, že antiviroví výzkumníci nemohou efektivně testovat detekční spolehlivost skenerů, protože musí infikované PC vždy restartovat, aby jim virus vytvořil nový decryptor. Decryptor se skládá z instrukcí procesoru Intel 386. Tělo viru je zakódováno a dekódováno různými metodami, včetně instrukcí XOR/NOT a INC/DEC/SUB/ADD s 8, 16 nebo 32bitovými klíči. Z pohledu detekce toto drasticky snižuje použitelné možnosti. Bohužel musím uznat, že tento polymorfní engine je velmi dobře napsaný, stejně jako zbytek viru a zjevně nebyl vytvořen nějakým začátečníkem. Třeba následující příklad decryptoru, který jsem pro názornost zjednodušil. Polymorfní decryptor viru je umístěn za variabilně zakódovaným tělem viru. Decryptor je rozdělený na dva menší ostrůvky kódu, které se mohou objevit v promíchaném pořadí. V příkladu ve výpisu 7.7 decryptor začíná na návěští Decryptor_Start a dekódování pokračuje až do doby, než kód konečně skočí na dekódované tělo viru.
Výpis 7.7 Ukázka dekryptoru viru W95/Marburg. Start: ; zde je umístěné zakódované/dekódované tělo viru Routine-6: dec
esi
; dekrementuj čítač smyčky
ret Routine-3: mov
esi,439FE661h
; nastav čítač smyčky v ESI
ret Routine-4: xor
byte ptr [edi],6F
; dekóduj konstantním bajtem
ret Routine-5: add
edi,0001h
; posuň ukazatel dekódovaní na další bajt
ret Decryptor_Start: call
Routine-1
; nastav EDI na "Start"
call
Routine-3
; nastav čítač smyčky
call
Routine-4
; dekóduj
call
Routine-5
; přejdi na další bajt
call
Routine-6
; dekrementuj čítač smyčky
cmp
esi,439FD271h
; je už všechno dekódované?
jnz
Decrypt
; ještě ne, pokračuj v dekódování
jmp
Start
; skoč na dekódovaný začátek viru
Decrypt:
Kapitola 7 – Pokročilé techniky vývoje kódu a generátory počítačových ...
242 Routine-1: call
Routine-2
; trik CALL-POP!
Routine-2: pop
edi
sub
edi,143Ah
; EDI ukazuje na"Start"
ret
Předchozí decryptor je vysoce strukturovaný a každý jeho funkční celek je umístěn ve speciální rutině. Výsledkem jsou miliony možných vzorků kódu s náhodnými daty mezi ostrůvky. Polymorfní viry mohou vytvořit bezpočet nových decryptorů, které používají různé metody pro zakódování konstantních částí virového těla (kromě svých datových oblastí). Některé polymorfní viry, jako třeba W32/Coke používají vícenásobné vrstvy zakódování. Varianta Coke dokonce umí polymorfně infikovat dokumenty Microsoft Wordu. Coke mění své makro (prostřednictvím svého binárního kódu) přímo, místo používání samotných maker. Normálně jsou polymorfní makro viry velmi pomalé, protože vyžadují mnoho interpretací (interpretation). Protože Coke generuje změněná makra pomocí svého binárního kódu, nepotýká se s žádným zpomalováním počítače a jeho přítomnost je tedy hůře rozpoznatelná. Podívejte se na následující příklad viru Coke, které jsem vybral ze dvou instancí změněného makra AutoClose() ve výpisu 7.8.
Výpis 7.8 Krátký příklad polymorfního makra viru Coke. ‘BsbK Sub AuTOclOSE() oN ERROr REsuMe NeXT SHOWviSuAlBASIcEditOr = faLsE If nmnGG > WYff Then For XgfqLwDTT = 70 To 5 JhGPTT = 64 KjfLL = 34 If qqSsKWW < vMmm Then For QpMM = 56 To 7 If qtWQHU = PCYKWvQQ Then If lXYnNrr > mxTwjWW Then End If If FFnfrjj > GHgpE Then End If
Druhý příklad je trochu delší (kvůli zanesenému smetí). V příkladu jsem vyznačil některé podstatné instrukce – povšimněte si, že ani ty nejsou zobrazeny ve stejném pořadí. Předchozí instance viru například vypíná Visual Basic Editor, takže už jej v menu Wordu nespatříte. Ve výpisu 7.9 se toto odehraje taky, ale až za hromadou vloženého smetí a jiných instrukcí.
Počítačové viry – analýza útoku a obrana
243
Výpis 7.9 Další příklad polymorfního makra viru Coke. ‘fYJm Sub AUtOcLOse() oN ERRor REsUME NexT optIOns.saVenorMALPrOmpT = FAlsE DdXLwjjVlQxU$ = "TmDKK" NrCyxbahfPtt$ = "fnMM" If MKbyqtt > mHba Then If JluVV > mkpSS Then jMJFFXkTfgMM$ = "DmJcc" For VPQjTT = 42 To 4 If PGNwygui = bMVrr Then dJTkQi = 07 ‘wcHpsxllwuCC End If Next VPQjTT quYY = 83 End If DsSS = 82 bFVpp = 60 End If tCQFv=1 Rem kJPpjNNGQCVpjj LyBDXXXGnWW$ = "wPyTdle" If cnkCvCww > FupJLQSS Then VbBCCcxKWxww$ = "Ybrr" End If opTiONS.COnFIrmCOnvErsiOnS = faLSe Svye = 55 PgHKfiVXuff$ = "rHKVMdd" ShOwVisUALbaSiCEdITOR = fALSe
Novější polymorfní enginy používají decryptor založený na RDA, který implementuje útok hrubou výpočetní silou proti svému konstantnímu, avšak variabilně zakódovanému tělu. Ruční analýza takových virů může vést k velkým překvapením. Často v nich lze nalézt neefektivitu v náhodnosti generovaných algoritmů, která se dá zneužít k protiútoku. Někdy může dokonce jeden jediný "wildcard" řetězec zajistit perfektní detekci. Většina skenerů měla už před léty emulátor kódu, který uměl emulovat 32bitové PE soubory. Jiní antiviroví výzkumníci pouze implementovali dynamické dekódování, aby si s takovými viry poradili. To
244
Kapitola 7 – Pokročilé techniky vývoje kódu a generátory počítačových ...
fungovalo v předchozích případech, protože tělo viru bylo po dekódování konstantní. Jak vyplývá z různých AV testů, někteří dodavatelé stále nemají podporu detekce složitějších virů. Autoři virů použili kombinaci technik zatajení vstupního bodu s 32bitovým polymorfismem, aby učinili práci antivirových skenerů ještě obtížnější. Navíc se pokusili implementovat techniky obrany proti emulaci, aby vyřadili emulátory kódu z provozu. Všechny polymorfní viry si nicméně stále sebou nesou konstantní kód svého těla, které je možné pomocí mnoha vylepšených technik dekódovat a identifikovat. Pro názornost se podívejte na obrázek 7.3.
Obrázek 7.3
Instance zakódovaných a dekódovaných těl polymorfního viru.
7.6 Metamorfní viry Autoři virů stále tráví týdny a měsíce vytvářením nových polymorfních virů, které díky svým chybám v kódu nemají šanci se dále rozšířit. A na druhou stranu – antiviroví výzkumníci jsou schopni si s detekcí takových virů poradit během několika minut nebo dnů, za což může nízký existující počet efektivních polymorfních enginů. Samozřejmě, že se autoři virů snaží implementovat různé nové techniky vývoje kódu, aby práci výzkumníkům co nejvíce ztížili. W32/Apparition byl prvním známým 32bitovým virem, který ke svému vývoji v dalších generacích nepoužíval polymorfní decryptory. Virus si v sobě nese zdrojový kód a vypustí jej kdykoliv, když najde na počítači nějaký nainstalovaný kompilátor. Virus vkládá a odebírá ze svého zdrojového kódu smetí a znovu se rekompiluje. Tímto způsobem se virus v dalších generacích naprosto liší od předešlých. Je jen náhoda, že se W32/Apparition nestal velkým problémem. A taková technika by
KAPITOLA 11 Techniky antivirové obrany
"Ale kdo bude hlídat hlídače?" – Juvenal
Kapitola 11 – Techniky antivirové obrany
374
Tato kapitola je kolekcí technik, které se používají v antivirovém software pro ochranu uživatelů před počítačovými viry. Postupně budou vysvětleny techniky antivirových skenerů, které se vyvinuly (společně s počítačovými viry) během posledních patnáct let. Během dlouhého vývoje antivirového software se tyto techniky vyladily a dnes jsou veřejně známé a používané. Ačkoliv se časem určitě objeví nové postupy, metody uvedené v této kapitole, se jeví pro dohlednou budoucnost jako dostatečné. Pro lepší přehlednost bude detekce počítačových virů rozdělena na tyto tři části:
Detekce založená na prostém vyhledávání vzorků.
Přesná identifikace.
Detekce zakódovaných, polymorfních a metamorfních virů1.
Také vám ukáži použití generických a heuristických metod2, které mohou detekovat celé třídy počítačových virů a nikoliv pouze jejich varianty. Tato kapitola vás také seznámí s technikami léčení (včetně generických a heuristických metod), které se používají pro opravu infikovaných souborů. Současný antivirový software pro heuristickou analýzu3 používá sofistikovanou emulaci kódu (tzv. virtuální stroj) pro komplexní detekci virů. Jedná se o klíčovou komponentu antivirového software, která pomohla udržet antivirové skenery dlouho při životě. Existují dva základní druhy skenerů: on-demand a on-access. On-demand skenování se spouští pouze na příkaz uživatele a dá se také spouštět během startu operačního systému. On-access skenery jsou naopak neustále rezidentní v paměti a nahrávají se jako jednoduché aplikace, které se zavěsí na přístup k diskům a souborům nebo jsou implementovány jako ovladače zařízení, které se připojují na souborové systémy4. Například na systémech Windows NT/2000/XP/2003 jsou on-access skenery typicky implementovány jako ovladače filtrů souborového systému (file-system filter drivers), které jsou připojeny na použité souborové systémy, jako například FAT, NTFS atd. Obrázek 11.1 znázorňuje načtený ovladač filtru souborového systému připojený na sadu souborových systémů s použitím nástroje z OSR.
Obrázek 11.1
Ovladač filtru souborového systému připojený k ovladačům souborového systému.
Počítačové viry – analýza útoku a obrana
375
On-access skenery obvykle skenují soubory při jejich otevírání, vytváření nebo zavírání. Takto se dá zabránit tomu, aby se na systému spustil známý virus. Zajímavý problém vzniká u síťových infektorů, jakým je třeba virus W32/Funlove. Funlove totiž infikuje soubory na sdílených síťových discích, takže infekce na vzdáleném systému bude detekována pouze v případě, že je soubor zapsán na disk. To znamená, že v některých případech mohou mít on-access skenery problémy při zastavování činnosti virů.
Poznámka Toto riziko se dá omezit skenováním diskové cache ještě před tím, než je soubor zapsán na disk. Mohou se pochopitelně použít i jiné metody obrany, jako třeba monitory podezřelého chování nebo software zabraňující proniknutí do sítě.
Tato kapitola se také zaměřuje na techniky, které dovedou infekcím zabránit a vyléčit je – jak v souborech, tak i v oblastech souborových systémů. Také se podíváme na obecně použitelná řešení, která zahrnují následující:
On-demand kontrolory integrity dat.
On-access kontrolory integrity dat (tzv. integrity shells).
Monitory podezřelého chování (tzv. behavior blockers).
Kontrolu přístupu.
Očkování.
11.1 Skenery první generace Většina počítačových knih rozebírá detekci virů na celkem jednoduché úrovni. Dokonce i novější knihy popisují antivirové skenery jako jednoduché programy, které prohledávají sekvence bajtů extrahované z počítačového viru umístěného v souboru nebo v paměti. Jedná se skutečně o jednu z nejpopulárnějších metod pro detekci počítačových virů, která je navíc v jistých ohledech efektivní. Současný antivirový software používá k detekci složitých virů mnohem zajímavější techniky, které skenery první generace nezvládají. Následující části textu rozebírají příklady metod detekce a identifikace, které se dají použít k detekci počítačových virů.
Poznámka Ne všechny techniky se dají použít k detekci všech počítačových virů, na druhou stranu se to ani neočekává. Stačí mít arzenál vlastní detekčních technik, z nichž jedna dobře poslouží k detekci nebo dezinfekci příslušného viru. Tento fakt je často opomíjen bezpečnostními specialisty a výzkumníky, kteří jsou schopni se hádat o efektivitě techniky v případě, že se nedá použit na detekci všech infekcí.
376
Kapitola 11 – Techniky antivirové obrany
11.1.1 Skenování řetězců Skenování řetězce je tím nejjednodušším způsobem, jakým lze detekovat počítačové viry. Je použito extrahovaných sekvencí bajtů (řetězců), které jsou typické pro konkrétní virus, a které se nenacházejí v čistých programech. Tyto sekvence se ukládají v databázích, které antivirové skenery systematicky používají při prohledávání v předdefinovaných oblastech souborů a v systémových oblastech, aby tak v omezeném čase, který mají vyhrazen na skenování, detekovaly počítačové viry. A skutečně – jedna z nejdůležitějších výzev, kterou před sebou enginy antivirových skenerů mají, je efektivní využití omezeného času k provedení testu (obvykle to nebývá více než pár sekund na jeden soubor). Podívejte se na část kódu uvedeného na obrázku 11.2, který byl získán pomocí nástroje IDA (Interactive DisAssembler) z jedné varianty boot viru Stoned.
Obrázek 11.2
Část kódu viru Stoned, který byl načtený do programu IDA.
Tato část kódu čtyřikrát přečte boot sektor diskety a před každým pokusem zresetuje disk.
Poznámka Virus potřebuje volat původní obsluhu INT 13, protože současně monitoruje stejné přerušení, aby mohl infikovat diskety kdykoliv, když se k nim přistoupí. Proto virus volá CS:[09] přímo v datové oblasti na počátku virového kódu, na 0:7C09, kde se nachází uložená adresa původní diskové obsluhy. Na začátku virového kódu je pár bajtů dat, zbytek těla zůstává konstantní.
Jedná se o typickou sekvenci kódu viru. Čtyři pokusy čtení prvního sektoru jsou nezbytné kvůli starším disketovým mechanikám, které byly příliš pomalé. Virus používá dvojici instrukcí PUSH CS, POP ES, aby nastavil diskový zásobník (buffer) na segment viru. Styl kódu vypadá jako pokus o optimalizaci nastavení obsahu registrů CX a DX, které slouží jako parametry volání přerušení diskové obsluhy. Následujících 16 bajtů, což je část kódu vyextrahovaná z viru Stoned, může sloužit jako vyhledávací řetězec pro tento virus. Byl publikován v magazínu Virus Bulletin. 0400 B801 020E 07BB 0002 33C9 8BD1 419C
Počítačové viry – analýza útoku a obrana
377
Těchto šestnáct jedinečných bajtů je dostatečně dlouhým řetězcem pro bezpečnou detekci 16bitového škodlivého kódu bez rizika falešných poplachů. Není tedy překvapením, že se pro detekci různých DOSových a boot virů používaly sekvence, které byly dlouhé právě těch šestnáct bajtů. Sekvence bývaly také publikovány v různých magazínech zaměřených na antivirový výzkum (například Virus Bulletin). Pro bezpečnou detekci 32bitových virů jsou obvykle zapotřebí delší vyhledávací řetězce, zejména v případě, kdy je kód napsaný v nějakém vysokoúrovňovém jazyce. Předchozí sekvence kódu se může objevit také v jiných variantách viru Stoned. Tímto řetězcem se mohou detekovat nejenom varianty viru A, B a C, dají se jím také detekovat příbuzné viry, které už spadají do jiné rodiny. Na jednu stranu je to výhoda, protože skener dokáže jedním řetězcem detekovat více virů, na druhou stranu se může stát, že tímto řetězcem bude detekován úplně jiný virus, který bude nesprávně označen jako virus Stoned. Uživatel si pak může chybně myslet, že tento virus je relativně neškodný, ovšem špatná identifikace může způsobit mnohem více škod. Špatná identifikace viru může vést k závažným komplikacím. Ty mohou nastat třeba v okamžiku, kdy se antivirový skener pokusí napadený objekt vyléčit. Protože postup odstranění dvou odlišných rodin virů nebo i dvou variant stejného viru je obvykle odlišný, mohou snadno nastat problémy. Pro vysvětlení – některé varianty viru Stoned například ukládají původní MBR na sektor 7, přičemž jiné varianty používají sektor 2. Pokud antivirový program neidentifikuje virus správně (alespoň ve své dezinfekční rutině), výsledkem bude to, že po dezinfekci nebude možné se nabootovat do systému. Existují některé techniky, které umí omezit vznik těchto komplikací. Některé jednoduché dezinfektory používají v opravném kódu různé záložky k tomu, aby se ujistily, že dezinfekční kód je opravdu určen konkrétní variantě viru.
11.1.2 Zástupné znaky Jednoduché skenery často používají tzv. zástupné znaky (wildcards), které obvykle umožňují přeskočit bajty nebo rozsah bajtů. Některé skenery navíc podporují regulární výrazy. Viz tento řetězec: 0400 B801 020E 07BB ??02 %3 33C9 8BD1 419C
Tento řetězec se bude interpretovat následovně: 1. Porovnej na 04 a pokud se shoduje, pokračuj. 2. Porovnej na 00 a pokud se shoduje, pokračuj. 3. Porovnej na B8 a pokud se shoduje, pokračuj. 4. Porovnej na 01 a pokud se shoduje, pokračuj. 5. Porovnej na 02 a pokud se shoduje, pokračuj. 6. Porovnej na 0E a pokud se shoduje, pokračuj. 7. Porovnej na 07 a pokud se shoduje, pokračuj. 8. Porovnej na BB a pokud se shoduje, pokračuj. 9. Ignoruj tento bajt.
378
Kapitola 11 – Techniky antivirové obrany
10. Porovnej na 02 a pokud se shoduje, pokračuj. 11. Porovnej na 33 na následujících třech pozicích a pokud se shoduje, pokračuj. 12. Porovnej na C9 a pokud se shoduje, pokračuj. 13. Porovnej na 8B a pokud se shoduje, pokračuj. 14. Porovnej na D1 a pokud se shoduje, pokračuj. 15. Porovnej na 41 a pokud se shoduje, pokračuj. 16. Porovnej na 9C a pokud se shoduje, nahlas infekci. Zástupné znaky se často používají pro půlbajty, které umožňují přesnější porovnání skupin instrukcí. Některé z prvních zakódovaných virů (a dokonce i polymorfní viry) bylo možné jednoduše detekovat řetězci na bázi zástupných znaků. Použití samotného Boyer-Moorova algoritmu5 není ovšem dostatečně efektivní pro skenery, které jsou založeny na řetězcích. Tento algoritmus byl vyvinut pro rychlé prohledávání řetězců a využívá porovnávání řetězců pozpátku. Uvažme následující dvě slova se stejnou délkou: CONVENED a CONVENER
Pokud jsou dva řetězce porovnávány od začátku, je pro nalezení rozdílu potřeba celkem sedm porovnání. Pokud se začne od konce řetězce, rozdíl odhalí už první porovnání, což významně redukuje celkový počet porovnání, které je potřeba učinit.
Poznámka Boyer-Moorův algoritmus nefunguje příliš dobře v systémech IDS (Intrusion Detection Systems, systémy pro detekci průniku), protože tento způsob porovnávání může způsobit přetečení v paketu.
Podobného úspěchu je možné dosáhnout na základě použití technik záložek, které jsou vysvětleny později. Navíc s použitím různých filtrovacích6 a hašovacích algoritmů může být rychlost virtuálně nezávislá na celkovém počtu řetězců, které se musí porovnávat.
11.1.3 Neshody Neshody v řetězcích byly vymyšleny pro IBM Antivirus. Ty umožňují, aby N bajtů v řetězci mohlo být libovolné, bez ohledu na jejich umístění v řetězci. Například řetězec 01 02 03 04 05 07 08 09 s hodnotou neshody 2 se bude shodovat ve všech následujících vzorcích (viz obrázek 11.3). 01 02 AA 04 05 06 BB 08 09 0A 0B 0C 0D 0E 0F 10 01 02 03 CC DD 06 07 08 09 0A 0B 0C 0D 0E 0F 10 01 EE 03 04 05 06 07 FF 09 0A 0B 0C 0D 0E 0F 10
Obrázek 11.3
Sada řetězců, které se liší ve dvou neshodách.
Počítačové viry – analýza útoku a obrana
379
Neshody jsou užitečné zejména při vytváření generických řešení pro detekce rodin počítačových virů, nevýhodou algoritmu je jeho pomalost během skenování.
11.1.4 Generická detekce Generická detekce skenuje několik nebo všechny varianty rodiny počítačových virů s použitím prostého řetězce. Jakmile je nalezena více než jedna varianta počítačového viru, sada variant je analyzována v obvyklé oblasti kódu, přičemž se vybere jednoduchý vyhledávací řetězec, který je přítomný v co nejvíce variantách. Generický řetězec obvykle obsahuje jak zástupné znaky, tak i neshody.
11.1.5 Hašování Hašování je běžný termín popisující techniky, které urychlují vyhledávací algoritmy. Hašování se dá udělat pro první bajt nebo 16bitová a 32bitová slova vyhledávacího řetězce, což umožňuje, aby další bajty obsahovaly zástupné znaky. Antiviroví výzkumníci mohou hašování ještě vylepšit tak, že zvolí nějaký začínající bajt, který bude řetězec obsahovat. Je dobré vyhnout se prvním bajtům, které jsou běžné v normálních souborech, jako jsou třeba nuly. Výzkumník může vybrat řetězce, které obvykle začínají stejnými společnými bajty, což redukuje počet nutných porovnání. Aby bylo vyhledávání co nejrychlejší, některé skenery vůbec nepodporují zástupné znaky. Například australský antivirus VET používá vynález Rogera Riordana7, který je založen na použití 16bajtových vyhledávacích řetězců (bez zástupných znaků) založených na 64 kB velké hašovací tabulce a 8bitového posuvného registru. Tento algoritmus pak použije každé 16bitové slovo řetězce jako index do hašovací tabulky. Velmi silné hašování bylo vyvinuto Fransem Veldmanem v TBSCAN. Tento algoritmus používá v řetězcích zástupné znaky, přičemž má dvě hašovací tabulky a odpovídající spojitý seznam řetězců. První hašovací tabulka obsahuje indexové bity do druhé tabulky. Algoritmus je založen na použití čtyř konstantních 16bitových nebo 32bitových slov vyhledávacího řetězce, který v sobě neobsahuje žádné zástupné znaky.
11.1.6 Záložky Záložky (nebo také kontrolní bajty) slouží jako jednoduchý způsob pro zajištění přesnější detekce a dezinfekce. Obvykle se v bajtech vypočítá vzdálenost mezi začátkem těla viru (neboli nultým bajtem těla) a detekčním řetězcem a uloží se odděleně v detekčních záznamech. Dobré záložky jsou specifické pro dezinfekci viru. Například v případě boot virů může dát někdo přednost vybrání sady záložek, které ukazují na reference v uložených boot sektorech. Když použijeme předchozí příklad viru Stoned, vzdálenost mezi začátkem těla viru a řetězcem je 0x41 (65) bajtů. Nyní se podívejte na část kódu na obrázku 11.4. Kód přečte uložený boot sektor v závislosti na příznaku. V případě pevného disku je načten uložený boot sektor a spustí se z hlavy 0, stopy 0 a sektoru 7 z jednotky C:. V případě disket se načte sektor kořenového adresáře z hlavy 0, stopy 3 a sektoru 1 z jednotky A:.
Kapitola 11 – Techniky antivirové obrany
380
Obrázek 11.4
Další část kódu viru Stoned načtená do IDA.
Jako postačující sada záložek mohou sloužit následující bajty:
První záložku můžeme vybrat z offsetu 0xFC (252) těla viru, kde se nachází bajt 0x07.
Druhou záložku můžeme vybrat z offsetu 0x107 (263) těla viru, kde se nachází bajt 0x03.
Tyto bajty můžete nalézt na offsetech 0x7CFC a 0x7D07 v předešlém disassemblovaném výpisu. Pamatujte si, že se tělo viru načítá na offset 0x7C00.
Poznámka V případě souborových virů je dobré vybrat takové záložky, které ukazují na offset, kde je uložená hlavička původního hostitelského programu. Další dobrou záložkou může být také velikost těla viru.
Nekorektní oprava zavirovaného souboru se dá bezpečně omezit kombinací vyhledávacího řetězce a záložek. V praxi je často bezpečné opravit virus na základě těchto informací, nicméně další přesná a téměř přesná identifikace viru může detekci ještě více vylepšit.
11.1.7 Skenování začátku a konce Skenování začátku a konce se často používá pro zrychlení detekce virů, a to skenováním pouze začátku a konce souboru, namísto skenování celého souboru. Proskenují se například první a poslední 2, 4 nebo 8 kB souboru na každé možné pozici. Jedná se o trochu lepší algoritmus než ty, které používaly první implementace antivirových skenerů, které pracovaly velmi podobně jako program GREP (který prohledává celý soubor na výskyt shodného řetězce). Jak se moderní procesory staly rychlejšími, začala být rychlost skenování záviset na rychlosti I/O operací. Pro optimalizaci rychlosti se vývojáři antivirových programů zaměřili na metody, které dokážou zredukovat počet čtení z disku. Protože se většina prvních počítačových virů připojovala na začátek nebo na konec hostitelských programů, stalo se skenování začátku a konce souboru docela populární technikou.
Počítačové viry – analýza útoku a obrana
381
11.1.8 Skenování vstupních a fixních bodů Skenování vstupních a fixních bodů učinilo antivirové skenery ještě rychlejšími. Takové skenery využívají vstupní body objektů, jako třeba ty, které jsou přístupné přes hlavičky spustitelných souborů. V binárních spustitelných souborech bez struktur, jako třeba DOSové COM soubory, takové skenery následující různé instrukce, které předávají řízení (jako třeba instrukce skoku a volání) a skenují místa, kam tyto instrukce ukazují. Protože jsou tato místa častým cílem počítačových virů, mají takové skenery velkou výhodu. Jiné skenovací metody, jako třeba již zmiňované skenování začátku a konce musí porovnávat řetězce (nebo haše řetězců) s každou možnou pozicí ve skenovací oblasti, ale skenery vstupních bodů mají obvykle jedinou pozici pro skenování – vlastní vstupní bod. Uvažte 1 kB dlouhý buffer nazvaný jako B. Počet pozic, na kterých se má porovnávat řetězec, je 1024 minus S, kde S je velikost nejkratšího řetězce na porovnání. I když je hašovací algoritmus skeneru tak efektivní, že skener potřebuje provést kompletní vyhledávání řetězce pouze v 1% času, počet výpočtů se může rychle vyšplhat nahoru (v závislosti na počtu řetězců). Například s 1000 řetězců bude skener potřebovat učinit 10 kompletních porovnání na každé možné pozici. Bude tedy potřeba vykonat minimálně (1,024 – S)x10 porovnání. Násobek 1024 – S může být snížen skenováním fixního bodu s jediným potřebným porovnáním ve vstupním bodě. Jedná se tedy o velmi významný rozdíl. Jestliže vstupní bod nemá dostatečně dobré řetězce, skenování ve fixním bodě může pomoct. Skenování ve fixním bodě porovnává pozici s každým řetězcem, takže je možné nastavit počátek M (například hlavní vstupní bod programu) a pak porovnávat každý řetězec (nebo haš) na pozici M + X bajtů od tohoto fixního bodu. Takto se opět redukuje počet nutných výpočtů, protože X bývá typicky nula. Tím se také významně snižuje množství diskových I/O operací. Tuto techniku jsem používal ve svém antivirovém programu. Každý řetězec antiviru Pasteur vyžadoval pouze jediný fixní začátek, konec a konstantní velikost. Byly podporovány i zástupné znaky, ale pouze v omezené míře. Řetězce byly setříděny do několika tabulek, v závislosti na typu objektu. Při porovnávání řetězců se vybral první bajt vstupního bodu a zkontrolovalo se, zda-li začíná jako některý řetězec prostřednictvím hašovacího vektoru. Jestliže nebyly nalezeny žádné takové první bajty, vybíraly se další vstupní body (pokud nějaké zbývaly). Protože je velikost každého řetězce konstantní, algoritmus může také kontrolovat, zda-li se poslední bajt řetězce shoduje s právě skenovaným místem v souboru. Jestliže se poslední bajt řetězce shoduje, pak se shoduje celý řetězec. V praxi k tomu ovšem dochází zřídka. Tento trik je podobný algoritmu Boyer-Moore zkombinovaným s jednoduchým hašováním.
11.1.9 Hyper-rychlý přístup k disku Hyper-rychlý přístup k disku je další užitečná technika, která se objevila v prvních implementacích antivirových skenerů. Používal jej program TBSCAN, stejně jako maďarský skener VIRKILL. Tyto skenery optimalizují proces skenování obcházením API určeného čtení z disku na úrovni operačního systému a přistupováním přímo přes BIOS. Protože byl MS-DOS obzvlášť pomalý při práci se souborovým systémem FAT, bylo možné dosáhnout nahrazením volání DOSových funkcí za přístup pomocí BIOSu až desetinásobného zrychlení při I/O operacích. Navíc byla tato technika užitečná jako obrana proti
382
Kapitola 11 – Techniky antivirové obrany
stealth virům. Protože souborové stealth infektory obvykle obcházely pouze přístup k souborům na úrovni DOSu, bylo většinou možné vidět změny v souborech prostřednictvím volání BIOSu. Jiné skenery a programy pro ověřování integrity dat kvůli ještě vyšší rychlosti a bezpečnosti obcházely i BIOS a pracovaly přímo s řadiči disků. Bohužel – dnes už není možné tyto techniky jednoduše (pokud vůbec) používat na všech operačních systémech. Ne jenom kvůli tomu, že existuje mnoho systémů souborů, které by antivirové skenery musely rozeznat a podporovat, ale také kvůli tomu, že existuje velký počet řadičů disku, což činí tuto úlohu prakticky nemožnou.
11.2 Skenery druhé generace Skenery druhé generace používají přesnou a téměř přesnou identifikaci, která pomáhá vylepšit detekci počítačových virů a jiných škodlivých programů.
11.2.1 Chytré skenování Chytré skenování se objevilo v době, kdy se objevily první počítačové viry s mutačními enginy. Takové enginy obvykle pracovaly se zdrojovými kódy assembleru a snažily se tam vkládat nadbytečné, nic-nedělající instrukce NOP. Rekompilovaný virus byl pak velmi odlišný od svého originálu, protože se v něm změnilo mnoho offsetů. Chytré skenování přeskakuje v hostitelském programu instrukce typu NOP a neukládá takové instrukce ve virových signaturách. Snahou chytrého skenování je vybrat oblasti těla viru, které nemají žádné reference na data nebo další subrutiny. To zvýšilo pravděpodobnost detekce blízké varianty viru. Tato technika je také užitečná při práci s počítačovými viry, které se objevují v textových formách, jako jsou třeba skriptovací a makro-viry. Tyto počítačové viry se umějí jednoduše změnit, protože mohou obsahovat prázdné znaky (jako např. mezery, nové řádky, tabulátory atd.). Tyto prázdné znaky se mohou při chytrém skenování odstranit ze skenovacích bufferů, čímž se významně zvýší detekční schopnosti takových antivirových skenerů.
11.2.2 Detekce struktury Detekce struktury byla vyvinuta Eugenem Kasperskym a je hlavně užitečná při detekci rodin makrovirů. Namísto vybrání jednoduchého řetězce nebo kontrolního součtu sady maker skener raději zpracuje makra řádek po řádku a vypustí všechny nedůležité příkazy, stejně jako výše zmíněné prázdné znaky. Výsledkem je struktura těla makra, která obsahuje pouze nezbytný škodlivý kód, který se běžně objevuje v makrovirech. Skener pak tyto informace použije k detekci virů, čímž se dosáhne lepší detekce variant virů spadající do stejné rodiny.
11.2.3 Téměř přesná identifikace Téměř přesná identifikace se používá pro přesnější detekci počítačových virů. Například – místo jednoho detekčního řetězce se pro každý virus použijí řetězce dva. K téměř přesné detekci viru Stoned můžeme vybrat z předchozího disassemblovaného výpisu druhý řetězec z offsetu 0x7CFC:
Počítačové viry – analýza útoku a obrana
383
0700 BA80 00CD 13EB 4990 B903 00BA 0001
V případě, že skener detekuje jeden řetězec varianty viru Stoned, nepovolí odstranění viru, protože by se mohlo jednat o neznámou variantu, kterou by nemusel zvládnout korektně odstranit. Pokud jsou ale nalezeny dva řetězce, je virus téměř přesně identifikován. Sice se může stále jednat o nějakou variantu viru, ale samotné léčení má vyšší šanci na úspěch. Tato metoda je zejména bezpečná v případě, kdy je zkombinována se záložkami (bookmarks). Jiná metoda téměř přesné identifikace je založena na použití kontrolního součtu (jako třeba CRC32) z vybrané oblasti z těla viru. Obvykle se vybere dezinfekční oblast těla viru a spočítá se její kontrolní součet. Výhodou této metody je lepší přesnost. To proto, že je možné vybrat v těle viru delší oblast, bez toho aniž by byla přetížená antivirová databáze – počet bajtů k uložení do databáze bude obvykle stejný jak pro malou, tak i pro velkou oblast, což se tak neděje v případě řetězců, protože delší řetězce zaberou více místa na disku a v paměti. Skenery druhé generace dále mohou dosáhnout téměř přesné identifikace bez použití jakýchkoliv vyhledávacích řetězců, třeba za pomoci kryptografických kontrolních součtů8 nebo nějakého druhu hašovací funkce. Aby byly skenovací enginy rychlejší, začaly používat nějaký druh haše. To vedlo k tomu, že haš vypočítaný z kódu viru, nahradil detekci založenou na vyhledávacích řetězcích. Například antivirový skener Fridrika Skulasona pojmenovaný jako F-PROT9 používá k detekci virů hašovací funkci společně se záložkami. Další skenery druhé generace, jako třeba ruský KAV, nepoužívají žádné vyhledávací řetězce. Algoritmus KAVu vymyslel Eugene Kaspersky. Namísto řetězců používá skener dva kryptografické kontrolní součty, které jsou v rámci objektu vypočítané ve dvou předvolených pozicích a délce. Antivirový skener interpretuje databázi kryptografických kontrolních součtů, řadí data do skenovacích bufferů (v závislosti na formátu objektu) a porovnává součty se zařazenými daty. Buffer může například obsahovat kód ve vstupním bodě spustitelného souboru. V takovém případě se každý první kryptografický kontrolní součet, který koresponduje s detekcí kódu ve vstupním bodě, skenuje výpočtem prvního a druhého součtu. KAV zobrazí varování o možné variantě škodlivého kódu pouze v případě, že se shoduje první součet. Pokud se shodují oba kryptografické kontrolní součty, skener zobrazí varování s téměř přesnou identifikací. První rozsah součtu se obvykle optimalizuje tak, aby popisoval malou část těla viru, druhý bývá větší, aby pokryl jeho větší část.
11.2.4 Přesná identifikace Přesná identifikace9 je jediný způsob, jakým lze zaručit správnou identifikaci jednotlivých variant viru. Tato technika se obvykle kombinuje s technikami první generace. Narozdíl od téměř přesné identifikace, která používá kontrolní součty nějakého rozsahu bajtů v těle viru, přesná identifikace používá pokud možno co největší počet rozsahů, který je nezbytný k vypočítání kontrolního součtu všech jeho konstantních bitů. K dosažení této úrovně přesnosti se musí eliminovat proměnlivé bajty (variable bytes), aby se mohla vytvořit mapa všech konstantních bajtů. Konstantní data se dají v mapě použít, nicméně proměnlivé bajty mohou poškodit kontrolní součet.
384
Kapitola 11 – Techniky antivirové obrany
Uvažte kód a data získaná z viru Stoned, která jsou zobrazena na obrázku 11.5. Na začátku kódu, v nultém bajtu těla viru, je možné nalézt dvě instrukce skoku, které nakonec převedou tok vykonávání programu na opravdový začátek virového kódu.
Obrázek 11.5
Proměnná data viru Stoned.
Těsně za druhou instrukcí skoku se nachází datová oblast viru. Proměnné jsou flag, int13off, int13seg a virusseg. Jedná se o skutečné proměnné, jejichž hodnoty se mohou lišit v závislosti na prostředí viru. Konstanty jsou jumpstart, bootoff a bootseg – tyto hodnoty se nemění, stejně jako zbytek virového kódu. Protože všechny proměnlivé bajty jsou identifikovány, zbývá poslední důležitá věc ke zkontrolování – velikost virového kódu. Víme, že se Stoned vleze do jediného sektoru, nicméně virus se sám kopíruje do existujících boot a master boot sektorů. Pro nalezení skutečné velikosti viru je zapotřebí se podívat na kód, který se stará o kopírování viru do virového segmentu. Ten se dá nalézt v disassemblovaném výpisu na obrázku 11.6.
Obrázek 11.6
Hledání velikosti těla viru Stoned (440 bajtů).
Velikost viru je skutečně 440 (0x1B8) bajtů. Jakmile virus zkopíruje svůj kód do alokované paměťové oblasti, tam ihned předá řízení vlastnímu kódu. K tomu virus používá konstantní offset a virový segment virusseg uložený v datové oblasti na adrese CS:0Dh (0x7C0D). Nyní tedy máme všechny informace, které potřebujeme ke spočítání mapy viru. Mapa bude zahrnovat následující rozsahy: 0x0-0x7, 0xD-0xE, 0x11-0x1B7 s kontrolním součtem 0x3523D929. Proměnlivé bajty jsou tedy eliminovány a virus je přesně identifikovatelný. Abyste přesnou identifikaci lépe pochopili, uvažujme části kódu dvou variant viru Stoned, A a B, jak je vidět ve výpisech 11.1 a 11.2. Tyto dvě varianty mají stejnou mapu, takže jejich kód a konstantní oblasti dat se shodují. Kontrolní součet dvou různých variant se nicméně bude lišit, protože autor změnil pár bajtů ve zprávě a textové oblasti těla viru. Změna ve třech bajtech má za výsledek rozdílný kontrolní součet.
Počítačové viry – analýza útoku a obrana
385
Výpis 11.1 Mapa viru Stoned.A. Jméno viru: Stoned.A Mapa viru: 0x0-0x7 0xD-0xE 0x11-0x1B7 Kontrolní součet: 0x3523D929 0000:0180 0333DBFEC1CD13EB C507596F75722050 ..........Your P 0000:0190 43206973206E6F77 2053 53746F6E656421 C is now Stoned! 0000:01A0 070D0A0A004C4547 414C4953 534520 204D41 .....LEGALIS SE MA 0000:01B0 52494A55414E4121 0000000000000000 RIJUANA!........
Výpis 11.2 Mapa viru Stoned.B. Jméno viru: Stoned.B Mapa viru: 0x0-0x7 0xD-0xE 0x11-0x1B7 Kontrolní součet: 0x3523C769 0000:0180 0333DBFEC1CD13EB C507596F75722050 ..........Your P 0000:0190 43206973206E6F77 2073 73746F6E656421 C is now stoned! 0000:01A0 070D0A0A004C4547 414C495A 5A4500 004D41 .....LEGALIZ ZE.MA 0000:01B0 52494A55414E4121 0000000000000000 RIJUANA!........
Přesná identifikace tak může od sebe odlišit obě varianty. Taková úroveň přesnosti je ovšem používána ve velmi malém množství AV produktů, jako třeba u antiviru F-PROT9. Přesná identifikace má jak pro koncové uživatelem, tak i pro antivirové výzkumníky mnoho výhod. Na druhou stranu – skenery používající přesnou identifikaci jsou při skenování infikovaných systémů obvykle pomalejší než jednoduché skenery (pokud jsou jejich algoritmy pro přesnou identifikaci použity). V případě většího počítačového viru je také docela únavné mapovat všechny konstantní rozsahy. To proto, že virový kód často míchá data společně s kódem.
11.3 Algoritmické skenovací metody Algoritmické skenování je trochu matoucí, nicméně široce používaný termín. Jakmile si standardní algoritmy skeneru nedovedou s virem poradit, je zapotřebí implementovat nový, pro daný virus specifický detekční algoritmus. Tomu se říká algoritmické skenování, nicméně termín algoritmus detekce konkrétního viru zní mnohem jasněji. První implementace algoritmického skenování byly řešeny jako obyčejné sady pevně daných detekčních rutin, které se přikládaly k samotnému kódu jádra antivirového enginu. Není překvapením, že takový typ detekce způsoboval mnoho problémů. První spočíval v tom, že kód enginu byl smíchán se speciálními rutinami, které se obtížně programovaly na nové platformy. Druhý problém tkvěl v ohrožení stability – algoritmické skenování mohlo skener jednoduše shodit, protože aktualizace pro detekce virů se vždy musí vypouštět co nejdříve, přičemž není dost času na testování.
386
Kapitola 11 – Techniky antivirové obrany
Řešení tohoto problému je jazyk na skenování virů10. Takové jazyky v té nejjednodušší formě obvykle podporují operace posunu ukazatele a čtení ve skenovaných objektech. Algoritmický sken podle řetězce se tedy provede přesunutím ukazatele na příslušné místo směrem dopředu od začátku souboru (nebo dozadu od jeho konce nebo od vstupního bodu), čtením bajtů, spočítáním místa, kam volání ukazuje a porovnáním řetězců, pěkně jednoho po druhém. Algoritmické skenování je nezbytnou součástí architektury moderních antivirových systémů. Některé skenery, jako třeba KAV, přišly s objektovým kódem, který byl součástí antivirové databáze. Detekční rutiny pro jednotlivé viry jsou napsány v přenositelném jazyce C, zkompilovány do objektového kódu a uloženy v databázi skeneru. Skener implementuje zavaděč podobný tomu z operačního systému, který za běhu spojí všechny objekty zodpovědné za detekci virů. Ty se potom spustí jeden po druhém, v závislosti na předdefinovaném pořadí volání. Výhodou této implementace algoritmického skenování je lepší výkon, nevýhodou je možné riziko nestability způsobené spouštěním reálného kódu na běžícím systému, který může obsahovat drobné chyby způsobené rychlou reakcí antivirových společností na hrozící nebezpečí, které si vyžádalo rychlé vytvoření komplexní detekční rutiny. K eliminaci tohoto problému se moderní algoritmické skenování implementuje jako p-kód (portable code, přenositelný kód), který je podobný Javě, s použitím virtuálního stroje. Příkladem použití této techniky je Norton AntiVirus. Výhodou této metody je to, že detekční rutiny jsou vysoce přenositelné. Není totiž potřeba vytvářet znovu pro nové platformy každou detekční rutinu specifickou pro daný virus – ty totiž mohou běžet stejně dobře na PC jako na IBM AS/400 (v případě, že je skener a virtuální stroj algoritmického skenovacího enginu přeportován na takové platformy). Nevýhodou je relativně pomalé vykonávání p-kódu (v porovnání s přímým spouštěním). Interpretovaný kód totiž obvykle běží až stokrát pomaleji než pravý strojový kód. Detekční rutiny mohou být implementovány v jazyce assembleru s vysokoúrovňovými makry. Takové rutiny pak mohou poskytovat skenovací funkce, které vyhledávají skupiny řetězců. Takové skenery ovšem musí být optimalizovány filtrováním, které je více rozvedeno v následující části. Detekční kód může být také implementován v rozšiřitelném skenovacím enginu za použití nativního kódu. V budoucnu se očekává, že algoritmické skenery budou implementovat JIT (Just-In-Time) pro kompilaci detekčních rutin založených na p-kódu do nativního kódu dané architektury, podobně jako to dělá .NET Framework v Microsoft Windows. Například, když se skener spustí na platformě Intel, p-kód se za běhu zkompiluje do kódu Intelu, čímž se rychlost vykonávání p-kódu dramaticky zvýší (často více než stonásobně). Tato metoda pak eliminuje problémy při spouštění strojového kódu jako součásti databáze, přičemž samotné vykonávání zůstává pod kontrolou skeneru, protože detekční rutiny se skládají z řízeného kódu (managed code).
11.3.1 Filtrování Filtrovací technika se stále více používá ve skenerech druhé generace. Myšlenka filtrování spočívá v tom, že viry obvykle infikují pouze vybranou sadu známých typů objektů, což dává skeneru jistou výhodu. Například signatury boot virů se mohou omezit pouze na boot sektory, signatury DOSových EXE infektorů na soubory EXE atd. U řetězce nebo detekční rutiny se právě z tohoto důvodu používá speciální příznak, který indikuje, zda-li se má signatura v právě skenovaném objektu kontrolovat, což redukuje množství řetězců, které skener musí následně porovnat.
Počítačové viry – analýza útoku a obrana
387
Algoritmické skenování silně závisí na filtrech. Protože jsou takové detekce více závislé na výkonu skenování, algoritmická detekce vyžaduje filtrování na dobré úrovni. Filtrem může být cokoliv, co je specifické pro daný virus: typ spustitelného souboru, identifikační značka viru v hlavičce skenovaného objektu, sekce kódu s podezřelými příznaky nebo jmény atd. Bohužel – ne každý virus umožňuje použít proces filtrování. Problém skenerů je jasný – skenování takových virů je časově náročné pro všechny produkty. Další problémem je detekce vyvíjejících se virů (jako třeba zakódované a polymorfní viry), které se dají najít prostřednictvím řetězců se zástupnými znaky pouze ve výjimečných případech. Tyto viry se dají lépe detekovat s použitím generického dekryptoru11 (založeném na virtuálním stroji), který dekóduje tělo viru a nalezne jeho konstantní tělo za použití řetězců nebo jiné známé metody detekce. Tyto metody nicméně nejsou vždy funkční. Například takové EPO viry a viry s obranou proti emulaci jsou schopny tyto techniky odstavit. V takových případech je zapotřebí použít zcela jiné techniky, jako je třeba analýza decryptoru/polymorfního enginu. Takto se dají dokonce detekovat i viry jako třeba W32/Gobi12 (analýza decryptoru jednoduše znamená, že se nahlédne do několika polymorfních decryptorů a porovnají se části kódu decryptoru v polymorfním enginu – takto se dá v mnoha případech, za použití algoritmické detekce, detekovat i samotný decryptor). Kód algoritmické detekce obvykle stráví mnoho času ve smyčce, což vyžaduje značný výkon procesoru. Například, v některých případech vyžaduje vysoce optimalizovaná detekce viru W95/Zmist13 vykonání přes dva milióny iterací p-kódu, aby byl virus korektně rozpoznán. Tento druh detekce funguje pouze tehdy, když se dá infikovaný soubor rychle rozeznat a odlišit od souboru neinfikovaného. Ačkoliv varianty viru Zmist nijak neoznačují napadené objekty, existuje přesto několik způsobů, jakým lze napadené soubory odfiltrovat. Zmist totiž používá několik filtrů, aby omezil infekci některých spustitelných souborů. Například infikuje pouze takové soubory, které mají známá jména sekcí a neinfikuje soubory nad stanoveným limitem jejich velikosti. Kombinace takových filtrů redukuje množství souborů nutných pro zpracování na méně než 1% všech spustitelných objektů, což umožňuje, aby relativně náročný detekční algoritmus běžel efektivně na všech systémech. Pro efektivní filtrování se dají použít následující kontroly:
Kontrola počtu nulových bajtů v oblasti souboru, kde se předpokládá umístění viru. Ačkoliv některé viry používají kódování, četnost zakódovaných a nezakódovaných dat se může dost lišit. Taková technika se běžně používá pro kryptografické prolamování. Například konec PE souboru (posledních pár kilobajtů) často obsahuje více než 50% nulových bajtů. V zakódovaném viru bývá obvyklý výskyt nul mnohem menší, pod 5 procent.
Kontrola změn příznaků a velikostí v hlavičce sekce. Některé viry označují sekce jako zapisovatelné a jiné podobným způsobem mění některé důležité záznamy na atypické hodnoty.
Kontrola příznaků souboru. Některé viry neinfikují konzolové aplikace, jiné neinfikují DLL knihovny nebo systémové ovladače.
388
Kapitola 11 – Techniky antivirové obrany
11.3.2 Statická detekce decryptoru Problémy se objevují v okamžiku, kdy je tělo viru náhodně zakódované, protože rozsahy bajtů, které skener používá k identifikaci viru, jsou omezené. Různé produkty používají detekci decryptoru specifickou pro daný virus všemi způsoby, ve všech kódových sekcích programových souborů. Rychlost skenování závisí na velikosti kódových sekcí skenovaných aplikací. Taková metoda detekce se používala ještě předtím, než se objevily první generické decryptory. Sama o sobě může tato technika hlásit falešné poplachy a opomíjet zavirované soubory, nehledě na to, že nezajišťuje možnost léčení, protože kód viru není dekódován. Jakmile se ale tato metoda použije společně s nějakým efektivním filtrem, je relativně docela rychlá. Podívejte se na část kódu viru W95/Mad, který je uveden na obrázku 11.7, který je dále rozebrán v kapitole 7. Decryptor viru W95/Mad je na počátku zakódovaného těla, hned za vstupním bodem infikovaných PE souborů.
Obrázek 11.7
Decryptor viru W95/Mad.
V tomto příkladu je operand instrukce SUB umístěný na 404208 proměnlivý, takže je zapotřebí ve vstupním bodě použít řetězec se zástupnými znaky. Následující řetězec bude schopný tento decryptor detekovat i v případě jiných variant viru: 8BEF 33C0 BF?? ???? ??03 FDB9 ??0A 0000 8A85 ???? ???? 3007 47E2 FBEB
Protože tento virus používá k dekódování svého těla jednoduchou metodu (XOR s konstantním bajtem), kompletní dekódování virového kódu je vcelku prosté. Dekódování se dá docílit velmi jednoduše, protože délka klíče není příliš velká. V našem příkladu je klíč 7Bh. Všimněte si těchto bajtů v zakódované oblasti viru – jedná se o nulové bajty, protože 7Bh XOR 7Bh = 0. Protože známe konstantní kód pod
Počítačové viry – analýza útoku a obrana
389
jednou zakódovanou vrstvou, je útok na čistý (nezakódovaný, dekódovaný) text snadno proveditelný. Tato metoda detekce je předmětem následující části kapitoly. Detekce decryptoru se dá použít i pro detekci polymorfních virů. I velmi silné mutační enginy, jako třeba MtE, používají alespoň jeden konstantní bajt v decryptoru, což stačí pro algoritmickou detekci s použitím disassembleru délky instrukcí. Polymorfní decryptor se jím dá disassemblovat a kód decryptoru profilovat. MtE používá konstantní instrukce podmíněného skoku zpět na proměnlivém místě. Operační kód instrukce je 75h, což se dekóduje jako instrukce JNZ. Operand instrukce vždy ukazuje směrem zpět, což značí, že se jedná o decryptor. Potom se tok programu zanalyzuje na všechny možné způsoby, kterými virus dekóduje své tělo, přičemž se ignorují všechny nadbytečné instrukce. Je sice časově náročné analyzovat vylepšené polymorfní enginy pro všechny možné dekódovací metody a nadbytečné instrukce, ale často je to jediný způsob, jakým lze takové viry detekovat.
11.3.3 Rentgenová metoda (X-raying) Jiná skupina skenerů používá kryptografickou detekci. Jak lze vidět v předchozím zmíněném příkladu, virus W95/Mad používá konstantní zakódování přes XOR s náhodně zvoleným bajtem, který slouží jako (de)kódovací klíč uložený v těle viru. To činí dekódování a následnou detekci viru opravdu triviální záležitostí. Podívejte se na část těla viru W95/Mad v zakódovaném a dekódovaném tvaru ve výpisech 11.3 a 11.4. V následujícím příkladě slouží jako decryptovací klíč bajt 7Bh.
Výpis 11.3 Zakódovaná část viru W95/Mad. Zakódovaný text
ASCII bajty
5B4A42424C7B5155 - 1E231E7B20363A3F
[JBBL{ QU.#.{
5B1D14095B2C1215 - 424E265B0D1E0908
[...[,..BN&[....
1214155B4A554B5B - 393E2F3A5A5B5318
...[JUK[9>/:Z[S.
5239171A18105B3A – 151C1E171B424C7B
R9....[:.....BL{
2031393937002A2E - 655865005B4D4144
1997.*.eXe.[MAD
6:?
20666F722057696E - 39355D2076657273
for Win95] vers
696F6E20312E3020 - 4245544121202863
ion 1.0 BETA! (c
29426C61636B2041 - 6E67656C60393700 )
Black Angel`97.
Výpis 11.4 Dekódovaná část viru W95/Mad. Odpovídající čistý text
ASCII bajty
2031393937002A2E - 655865005B4D4144
1997.*.eXe.[MAD
20666F722057696E - 39355D2076657273
for Win95] vers
696F6E20312E3020 - 4245544121202863
ion 1.0 BETA! (c
29426C61636B2041 - 6E67656C60393700
)Black Angel`97.
390
Kapitola 11 – Techniky antivirové obrany
Virus se dá jednoduše dekódovat algoritmickou technikou a následně přesně identifikovat. Antiviroví výzkumníci také mohou prozkoumat polymorfní enginy vylepšených virů a vypátrat metody zakódování, které používají. Jednoduché metody, jako třeba XOR, ADD, ROR atd. se často používají s 8bitovými, 16bitovými a 32bitovými klíči. Někdy decryptor viru používá více než jednu vrstvu, která je zakódována stejnou metodou (nebo i více metodami) s jednobajtovým, dvoubajtovým a čtyřbajtovým klíčem. Útok na zakódování virového kódu se nazývá jako rentgenové (X-RAY) skenování, které vymyslel Frans Veldman pro svůj produkt TBSCAN, stejně jako někteří další výzkumníci v podobném čase a nezávisle na sobě. Poprvé jsem tuto techniku použil pro detekci viru Tequila. Myšlenka rentgenování byla vcelku přirozená, protože dekódování kódu viru bylo – pro účely léčení – nezbytné i v případě starších známých, a neustále se šířících virů, jako třeba Cascade. Veselin Bontchev mě informoval, že poprvé spatřil dokument popisující techniku rentgenování u Eugena Kasperskyho. Rentgenové skenování využívá všech jednoduchých metod kódování a provádí se na vybraných oblastech v souborech, jako třeba na jeho začátku, na konci nebo blízko kódu u vstupního bodu programu. Skener tedy stále může pro detekci zakódovaných – a dokonce i složitých polymorfních – virů14 používat jednoduché řetězce. Skenování je sice trochu pomalejší, ale technika je obecně použitelná. Problém s touto metodou vyvstane v momentě, kdy začátek těla viru není k nalezení na fixním místě a útok proti decryptoru se tak musí spustit na velké oblasti souboru, což vede k velkému zpomalení. Výhodou této metody je kompletní dekódování virového kódu, což umožňuje soubor vyléčit i v případě, kdy jsou informace, které jsou nezbytné k obnovení, uloženy v zakódované formě.
Poznámka Rentgenové skenování často detekuje instance počítačových virů, které mají falešný decryptor. Některé polymorfní viry vytvářejí falešné decryptory, které nedekódují tělo viru správně, nicméně dekódování rentgenovou metodou skončí i na těchto vzorcích úspěchem. Takové vzorky se dají detekovat pouze tímto způsobem, protože detekční techniky založené na emulaci, vyžadují fungující decryptor.
Některé viry, jako třeba W95/Drill, používají více než jednu zakódovanou vrstvu a polymorfní engine, ale i tak mohou být efektivně detekovatelné. Nejvíce záleží na kombinaci kódovacích metod. Příliš nezáleží na tom, jestli polymorfní zakódování používá metodu XOR jednou nebo stokrát – v obou případech se dá virus rentgenováním detekovat. Nebo třeba takový polymorfní engine SMEG (Simulated "Metamorphic" Encryption Generator), vytvořený autorem jménem Black Baron, se dá efektivně detekovat s použitím algoritmické detekce, která využívá techniku rentgenování.
Poznámka Christopher Pile, autor virů SMEG, byl v listopadu roku 1995, podle zákona Computer Misuse Act Spojeného Království, odsouzen k osmnácti měsícům ve vězení.
466
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
Od doby červa Morris v roce 1988 se počítačoví červi stali jednou z největších výzev internetového věku. Každý měsíc jsou v široké skupině operačních systémů a aplikací hlášeny kritické zranitelnosti. A rovněž roste v alarmujícím množství počet případů zneužití těchto zranitelností počítačovými červy. Tato kapitola reprezentuje některé slibné techniky ochrany před průniky (intrusion), které jsou založeny na hostitelích, a které mohou zastavit celou třídu rychle se šířících virů, využívajících útoků přetečením bufferu (například W32/CodeRed1, Linux/Slapper2 a W32/Slammer3).
Poznámka Zmínil jsem zde techniky přetečení bufferu, protože je pokládám za nejvýznamnější. Existuje ovšem několik dalších možností, kterým jsem se vyhnul – buď proto, že nejsou natolik důležité, anebo jsou velice specializované a pokrývají pouze malý počet možných exploitací.
13.1 Úvod Počítačoví červi mohou být klasifikováni na základě způsobu replikace, který používají. Během několika posledních let používala většina úspěšných (také nazývaných "in-the-wild") počítačových červů e-mail, jako svůj infekční nástroj pro rozšíření se do nových hostitelských systémů. Červi tohoto typu se nazývají jako hromadně se rozesílající červi. I před fakt, že se binární červi typu W32/SKA@m (červ Happy99) silně rozšířili, stali se všeobecně známými až díky e-mailovým virům založeným na makrech a skriptech, jako třeba V97M/Melissa@mm nebo VBS/LoveLetter@mm. Tento trend byl pak následován několika lety úspěšných útoků binárních červů pro Win32, jako například W95/Hybris, W32/ExploreZip, W32/Nimda či W32/Klez. V nedávné době se začal u autorů virů objevovat nový trend, vedoucí k vytváření agresivních a rychle se šířících červů. Tento trend byl potvrzen představením červa W32/CodeRed, který znamenal velkou bezpečnostní výzvu. Když se objeví relativně nová a úspěšná strategie psaní virů, dojde vždy k tomu, že se začnou objevovat nové a nové viry, které začnou tuto strategii používat také. Tento proces klonování produkuje stovky rodin virů, které mají stejné základní charakteristiky, obvykle však s některými vylepšeními. Proto se také očekávalo klonování červa W32/CodeRed a vznik nových a ještě více agresivnějších červů. Objevení červa W32/Slammer, který v 376 bajtech převzal základní koncept červa CodeRed, nebyl proto nijak překvapující. Slammer je jedním z nejrychleji se šířících binárních červů všech dob4. Infekce dosáhla vrcholu v několika hodinách a vedla k masivnímu útoku DoS (Denial of Service) na internetu. Namísto protokolu TCP, který byl použit v červu CodeRed, červ Slammer používá pro útoky protokol UDP. Protože tento protokol (na rozdíl od TCP) není potvrzovaný a protože byl útok realizován pomocí jediného paketu, byl Slammer mnohem rychlejší než CodeRed. Proces, který se pokouší o spojení pomocí TCP, musí pro zjištění neúspěchu počkat, až vyprší timeout. Slammer oproti tomu jednoduše provede útok na možný cíl a bez čekání pokračuje dál. Úspěšný útok trvá stejně dlouho, jako útok neúspěšný – každý z nich spočívá pouze v zaslání paketu a je tedy velmi rychlý.
Počítačové viry – analýza útoku a obrana
467
Abych byl úplně přesný – metody asynchronního spojení TCP mohou být téměř tak efektivní, jako metody UDP, nicméně to vyžaduje výrazně větší schopnosti jak programátora, tak i kódu. V budoucnosti můžeme očekávat více škodlivých hackerů, kteří budou těžit z "automatizovaných průniků" za pomoci červů. Vzrůstá proto důležitost systémů ochrany proti těmto skupinám červů.
13.1.1 Blokování skriptů a SMTP červů Skriptovací červi, jako například VBS/Loveletter@mm, se šíří řádově mnohem rychleji, než předchozí "generace" virů. Skriptovací červi donutili vývojáře společnosti Symantec k začlenění technik blokující tyto hrozby do programu Symantec AntiVirus. V důsledku toho byla technologie pro blokování skriptů úspěšně nasazena už v roce 20005. Je pozitivní, že technologie blokování skriptů vedla k velkým změnám v antivirových produktech, které pak dokázaly efektivněji chránit uživatele v domácnostech. Úroveň nebezpečí se pak začala pomalu snižovat. Další techniky blokování skriptů a efektivnější, souborově orientované, heuristiky pak způsobily trvalý pokles hrozby nebezpečných skriptů. Náhlý vzrůst 32bitových binárních červů, kteří používají vlastní SMTP engine pro šíření sebe sama pomocí e-mailů, byl přirozeným důsledkem rozvoje skriptů a makro virů. Vznik SMTP červů, jako jsou například W32/Nimda@mm a W32/Klez@mm, vedl k vytvoření a začlenění techniky pro blokování červů v produktu Symantec AntiVirus 2002. Blokování červů je sice jednoduchá, nicméně velmi efektivní technika. Během posledního roku se pomocí takových technik totiž úspěšně podařilo zabránit hromadnému rozšíření červů, jako W32/Bugbear@mm, W32/Yaha@mm, W32/Sobig@mm6, W32/Brid@mm, W32/ HLLW.Lovgate@mm, W32/Holar@mm, W32/Lirva@mm a mnoha dalším variantám. Oddělení společnosti Symatec, které je zodpovědné za bezpečnost, dostalo po několika měsících od vypuštění nové verze svého produktu s blokujícími technikami, několik tisíc hlášení o tom, kteří červi byli úspěšně zablokování. Například – v srpnu roku 2003 se stal červ W32/Sobig.F@mm zodpovědným za jeden z nejvýznamnějších e-mailových útoků, který po několik dní paralyzoval e-mailové systémy. Technologie blokování červů zablokovala více než 900 kopií červa – uživatelé antiviru od společnosti Symatec tak byli před červem chráněni ještě předtím, než byli tito červi vůbec definováni. A podle posledních statistik blokování zastavilo více než 12000 kopií červa W32/Mydoom.A@mm. Tabulka 13.1 ukazuje žebříček dvaceti červů seřazených podle počtu zablokování jejich kopií. Typicky bývají útoky červů úspěšné až do doby, dokud nejsou v systémech aktualizovány příslušné signatury. Podle tabulky 13.1 je jasně vidět, že bez techniky blokování červů by dalších 12 tisíc počítačových systémů začalo propagovat červa Mydoom.
468
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
Tabulka 13.1 – Seznam dvaceti nejvíce zablokovaných červů pro Win32. Počet hlášení
Jméno červa
12159
W32.Mydoom.A@mm
9709
W32.Netsky.D@mm
5334
W32.Netsky.B@mm
5111
W32.Yaha.K@mm
2598
W32.Netsky.C@mm
2451
W32.Mydoom.F@mm
1275
W32.Netsky.Z@mm
1274
W32.Sobig.E@mm
1210
W32.Mapson.Worm
1048
W32.Netsky.K@mm
1039
W32.Bugbear.B@mm
1021
W32.Sobig.F@mm
971
W32.Netsky.X@mm
888
W32.Dumaru@mm
745
W32.Netsky.Q@mm
673
W32.HLLW.Mankx@mm
652
W32.Sobig.C@mm
629
W32.Sobig.B@mm
390
W32.Mimail.A@mm
372
W32.Netsky.Y@mm
Získávané informace o zablokovaných červech vedou k rychlejšímu vydávání updadů s jejich signaturami. Zákazníci Symantecu tím získávají rychlejší odezvu na vysoce infikující Win32 červy. Tento výsledkem je výborný, zejména s ohledem skutečnost, že autoři virů vytvořili v průběhu každého měsíce roku 2004 cca několik set nových 32bitových virů pro Windows. Mnohé z těch nejvíce úspěšných patří mezi hromadně se rozesílající prostřednictvím e-mailu. Obrázek 13.1 ukazuje za období od září 1999 do října 2004 celkový počet známých variant 32bitových virů.
Počítačové viry – analýza útoku a obrana
Obrázek 13.1
469
Celkový počet známých variant 32bitových virů pro Windows měsíčně.
Z obrázku je zjevné, že tvorba virů se zrychlila v roce 2004, současně s rychle se rozvíjejícím druhem počítačového červa, který pracuje na síťové úrovni a který využívá různé exploitace. Za posledních několik let se objevila asi tisícovka binárních červů založených na e-mailu. Během posledních 12 měsíců se však objevily tisíce nových variant červů, které využívají různých zranitelnosti. Počet těchto červů však může být (v porovnání s e-mailovými červy) ještě podhodnocen, z jednoho hlavního důvodu – je totiž obecně těžší je zaznamenat, nehledě na fakt, že lidé mají každodenní zkušenost s vedlejšími efekty e-mailových červů, stejně jako se spamy. E-mailové schránky jsou jich plné. Základní myšlenka blokování červů je jednoduchá. Patentovaná technologie funguje tak, že SMTP proxy založená na hostiteli, používá ovladač režimu jádra pro přímé sledování odchozího provozu. Tato komponenta neslouží pouze jako antivirový skener e-mailů, ale slouží také pro blokování červů. Tato komponenta pro blokování červů ví o všech procesech, které incializují odchozí SMTP provoz, protože všechno prochází přes příslušnou proxy. Příslušná komponenta tak může kontrolovat, zdali je tento proces (nebo jeho nadřazený proces), přítomen v daném e-mailu ve formě přílohy. Škodlivý software, který se sám rozesílá, je tak snadno detekován a následně zablokován. Tento postup funguje i v případě, kdy je přílohou zkomprimovaný soubor, například typu ZIP. Porovnávací algoritmus navíc dokáže rozeznat změny obsahu souboru do té míry, že jsou detekovatelní i červi, kteří během replikace mění strukturu svého těla (například W32/Klez nebo W32/ExploreZip).
470
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
Technika blokování červů nemusí být schopna zastavit všechny červy. Má však velké šance na úspěch, zejména v případech, kdy se objeví červi, kteří jsou pouze odvozeni od jiných červů.
13.1.2 Blokování nových útoků – CodeRed a Slammer Počítačoví červi, jako například W32/CodeRed nebo W32/Slammer, jsou velkou výzvou pro již existující antivirové technologie. Tito vysoce nakažliví červi skáčou z hostitele na hostitele a infikují procesy systémových služeb, přičemž využívají síťových služeb a útoků pomocí přetečení bufferu. Protože není potřeba vytvářet na disku nějaké soubory, a protože je kód injektován přímo do adresovacího prostoru zranitelného procesu, jsou v případě těchto útoků omezeny schopnosti systémů určených pro ověřování integrity souboru. Tato kapitola se zaměřuje popis aktivních metod, které jsou založeny na hostitelích, a které by měly sloužit jako linie obrany proti neznámým útokům využívající známé metody. Blokování červů na bázi hostitele slibuje detekci neznámých variant červů a jejich útoků, založených na již známých technikách. Techniky blokování červů založené na hostiteli pak nabízejí v takových případech výrazné zvýšení ochrany.
13.2 Techniky blokování útoků využívající přetečení bufferu "Každý netriviální program obsahuje chyby." Tato část popisuje některé z nejdůležitějších technik pro detekci a ochranu před útoky využívající přetečení bufferu a související exploity v počítačových systémech. Některé z nich jsou teprve ve fázi výzkumu, jiné se už používají. Tyto procedury pomáhají při ochraně před infekcemi rychle se šířícími počítačovými červy. Pokud pomineme komplexnost a typ přetečení, v zásadě není rozdíl mezi technikou přetečení internetového červa Morris7 a dnes používanými pokročilejšími útoky (jako Linux/Slapper2). Tito červi jsou totiž založeny na stejných myšlenkách, které souvisejí s přetečením zásobníku nebo struktur heapu. Mohou být rozděleny do několika hlavních kategorií. Většinu červů na systémech BSD a UNIX, jako jsou třeba Morris, Linux/Slapper, BSD/Scalper nebo Solaris/Sadmind, můžeme označit mezi červy založené na kódu shellu (shellcode). Kód shellu je krátká posloupnost kódu, která běží v interpretu příkazů (shellu) na vzdáleném systému. Jedná se například o /bin/sh na UNIXu nebo cmd.exe na Windows. Komunita hackerů si mezi sebou vyměňuje tyto kódy, které jsou určeny pro mnoho operačních systémů. Někteří hackeři je pak používají pro útoky pomocí přetečení, eventuálně je upravují pro tento typ útoku. Poté, co shell spustí na vzdáleném stroji, může se do systému nakopírovat červ, který pak nad ním získá úplnou kontrolu. Hackeři používají tuto techniku pro "získání vlastnictví" nad cizím počítačem. Jiné třídy červů, například W32/CodeRed, tuto techniku nepoužívají. Místo toho ukradnout (hijack) thread některé vadné aplikace a pomocí kódu injektovaného za běhu se spustí jako součást exploitované služby hostitele. Techniky představené v této kapitole poskytují ochranu jak proti shell kódům, tak i proti útokům pomocí injektáže kódu za běhu.
Počítačové viry – analýza útoku a obrana
471
Zde existuje jedna významná skupina útoků, označovaná jako "návrat k LIBC" (return-to-LIBC). V takovém případě se útočník snaží přesměrovat návrat do standardního existujícího kódu v systému (například run-time jazyka C nebo API operačního systému). Útočník se snaží dosáhnout přetečení zásobníku takovým způsobem, aby mohl pomocí instrukce ret přesměrovat tok vykonávání do volání zamýšleného API s parametry, které si sám stanoví (zásobník je přepsán zvolenými parametry a stejně tak i "návratovou adresou", která je právě adresou zamýšleného volání API). Tímto způsobem není prováděn kód v zásobníku, a ani na heapu. To je důležité, protože některé techniky ochrany proti přetečení vyžadují kontrolu kódu, který neběží tam, kde by měl – tedy právě v zásobníku, nebo na hromadě. Z tohoto důvodu je tato třída útoků vůči zmíněným technikám ochrany imunní. Přestože existující červi tuto techniku nepoužívají, dá se očekávat, že ji v budoucnu využívat začnou. V očekávání vzniku takových červů jsem strávil mnoho času popisováním technik proti útokům typu return-to-LIBC.
13.2.1 Přezkoumání kódu Nejefektivnější metodou ochrany proti útokům pomocí přetečení bufferu je přezkoumání kódu, které provádějí bezpečnostní experti. Softwarové produkty mnoha společností jsou často vydávány s minimálním, nebo vůbec žádným přezkoumáním kódu, což vede k eventuálním bezpečnostním problémům. Ale i když je toto přezkoumání prováděno, lidé občas nebývají dostatečně kvalifikováni k tomu, aby dokázali odhalit případné bezpečnostní problémy. Ve všech stádiích vývoje je potřeba si vytrénovat bezpečnostní profesionály. Programátory je potřeba neustále vzdělávat v otázkách bezpečnosti. Prozkoumávání kódu je důležité především z toho důvodu, že ten, kdo má k dispozici zdrojový kód, má také nejlepší možnosti obrany. Nemůžeme však předpokládat, že vývojář dokáže detekovat všechny bezpečnostní problémy. Většinu takových nedostatků totiž odhalí lidé nezasvěcení do kódu – jako třeba profesionálové v oblasti bezpečnosti a hackeři. Dalším problémem je to, že bezpečnostní přezkoumání kódu se často soustředí na samotný kód, přičemž se opomine samotný návrh aplikace. To samo o sobě vede k závažným problémům se zranitelností.
13.2.1.1 Bezpečnostní aktualizace Mnoho bezpečnostních profesionálů věří, že publikování zranitelných míst nějakého produktu přinutí danou společnost, aby rychle vytvořila příslušné záplaty. Nicméně – pokud je záplata k dispozici, zákazníci je často zapomínají použít, a to až do té doby, dokud nejsou taková zranitelná místa zneužita proti nim. Důvody pro malé používání bezpečnostních aktualizací jsou následující:
Lidé neví, že bezpečnostní záplaty existují, nebo je nechtějí používat.
Ve velkých společnostech je často nákladné je implementovat.
Záplaty občas neopraví všechny bezpečnostní nedostatky.
Občas způsobují havárie nebo nekompatibilitu se stávajícími programy.
Používání aktualizací je nejefektivnějším typem ochrany proti některým bezpečnostním rizikům. Opomíjení jejich používání není dobrou praxí, přestože aktualizace na některých systémech občas působí
472
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
problémy. Dobrým příkladem je Microsoft Security Bulletin MS03-007, který mnoho lidí nepřesně zná pod označením "zranitelnost WebDav". Jedna z tehdejších chyb přetečení bufferu byla umístěna v okruhu oprávnění 3 (ring 3), v uživatelském režimu. Bylo potřeba opravit funkci run-time knihovny (RTL) nativního API modulu NTDLL.DLL. Kromě toho existovala v jádře zranitelnost ohledně přetečení celých čísla (integer). Protože původní škodlivý exploit pracoval se součástí WebDav systému IIS, mnoho bezpečnostních profesionálů si myslelo, že k obraně proti možnému útoků postačí, když se WebDav zakáže. Záplata, kterou poskytoval Microsoft, nahrazovala soubor NTDLL.DLL novou verzí, což bylo chápáno jako příliš velký zásah, který by mohl na mnoha systémech způsobit komplikace. Díky tomu se pak spousta lidí příslušnou aktualizaci vůbec nezabývala, přičemž se spokojili s pouhým zakázáním součásti WebDav. Mnoho systémů tak bylo ponecháno bez odpovídající ochrany. Důležitým poznatkem je tedy to, že mohou být zneužity zranitelnosti v jednotlivých aplikacích. Je-li však chyba v některé sdílené komponentě, například v nějaké součásti operačního systému, jsou napadnutelné i všechny aplikace, které tuto komponentu využívají. Když se objeví zranitelnost některé aplikace, neznamená to ještě, že ostatní aplikace jsou bezpečné. Zakázání aplikace v tomto případě znamená zakrytí skutečného problému. Tato situace je ještě horší, objeví-li se zranitelnosti ve staticky linkovaných knihovnách, jako například zlib nebo openssl. Toto může způsobit zranitelnost celého systému. Mnoho výrobců software si bohužel neuvědomuje, že jsou jejich produkty zranitelné nebo tuto skutečnost rovnou zanedbávají a žádné bezpečnostní aktualizace neposkytují. Kvůli ochraně zranitelného software proti možným útokům musíme důsledně dotáhnout do konce každou fázi jeho vývoje. K ochraně je potřeba přistupovat na všech úrovních – od zdrojových kódů až po ochranu aplikace za běhu. Přitom je potřeba porozumět všem možnostem i omezením jednotlivých technik ochrany.
13.2.2 Řešení na úrovni kompilátoru Po nějakou dobu používali programátoři specifický software pro zjišťování bezpečnostních nedostatků aplikace, jako například BoundsChecker. Ten jim pomohl najít mnoho existujících přetečení a dalších problémů s kvalitou programů. Jak se však útoky pomocí přetečení bufferu stávaly stále populárnějšími a úspěšnějšími, začali bezpečnostní profesionálové uvažovat o lepším řešení na úrovni kompilátoru. Programovací jazyky C a C++ nabízejí velké možnosti všem typům útoků založeným na přetečení bufferu. Protože je kód, zapsaný v těchto jazycích, obzvláště zranitelný, musí programátoři využívat různých technik spojených s kompilátory. Taková řešení nás samozřejmě nemohou zbavit potřeby provádět bezpečnostní prozkoumání kódu. Techniky na úrovni kompilátorů jsou prvotní ochranou proti většině známých typů útoků pomocí přetečení zásobníku. Většina z nich ovšem proti takovým útokům neposkytuje naprosto stoprocentní ochranu – zpravidla ani neposkytují ochranu proti přetečení, které se týká heapu. Tato kapitola uvádí několik jednoduchých příkladů toho, proč jsou některé systémy zranitelné pomocí útoků na zásobník (stack), i když jsou označeny jako chráněné. Měli bychom si však uvědomovat, že čím více technik je nasazeno k zajištění ochrany, tím větší množství znalostí a schopností je potřeba k jejich obejití. A to zdaleka všichni potencionální útočníci nemají. Ne-
Počítačové viry – analýza útoku a obrana
473
hledě na fakt, že útočníci, kteří jsou vybaveni dostatečnými znalostmi, potřebují k provedení úspěšného útoku také více času. Na straně útočníka jsou nicméně následující výhody:
Mají přístup ke zkompilovanému kódu; v případě open-source i ke kódu zdrojovému.
Mají většinou dostatek času.
Obtížnost různých exploitů. Některé zranitelnosti jsou útočníky snadno zneužity, zatímco práce na jiných trvá měsíce. Složitost ochrany proti nim se však nemění. Je stejně obtížná a vůbec to nezáleží na tom, jak snadno je možné konkrétní zranitelnost využít. U některých projektů může být obtížná (a také extrémně drahá) změna pouhých dvou řádků kódu.
I když některé exploity vyžadují naprostou preciznost, exploity na jiných systémech už nemusí po útočnících vyžadovat takovou přesnost.
13.2.2.1 StackGuarg StackGuard byl uveden v roce 19988 jako jedno z prvních rozšíření kompilátorů k ochraně proti některým typům útoků přetečením zásobníku. Byl vytvořen jako rozšíření překladače gcc. Šikovným způsobem používá detekci modifikované návratové adresy pomocí techniky "kanára" ("canary"). Většina přetečení zásobníku spočívá v přetečení bufferu, umístěného poblíž návratové adresy funkce na zásobníku. Chybějící "kontrola ohraničení" (bounds check) umožňuje přetečení bufferu pomocí řetězce velké délky a tudíž i manipulaci funkce návratové hodnoty na zásobníku. Takový útok se nazývá jako stack smashing9. Když se funkce vrací k volajícímu (caller), vezme si adresu, kterou tam předtím vložil útočník. StackGuard se takovým útokům brání tak, že vedle návratové adresy na zásobník vloží varovnou hodnotu (tzv "kanára" – viz obrázek 13.2). StackGuard je jednoduchou záplatou pro function_prologue a function_epilogue v gcc. Rozšířením function_prologue o tuto varovnou hodnotu (kanára) a function_epilogue pro její ověřování, může být za běhu programu detekována úprava této hodnoty. Pokud je hodnota změněna, rutina epilogu provede "handler mrtvého kanára" (canary-death-handler) místo návratu funkce. Pokud je tedy útok detekován, kód útočníka nemá možnost se spustit. Existuje ovšem pár věcí, na které se implementace StackGuardu verze 2.x nezaměřuje – některé z nich bude pokrývat StackGuard 3. Neposkytuje například ochranu proti útokům na ukazatele rámce (frame pointer, EBD). Kanár je totiž umístěn za návratovou adresou a přetečení ukazatele rámce tak nemusí být detekováno. Ke změně ukazatele rámce není potřeba změnit hodnotu kanára. StackGuard je dále zranitelný vůči útokům, které jsou vedeny proti ukazatelům funkcí mezi lokálními proměnnými. Zůstává však skutečností, že StackGuard dokáže efektivně blokovat mnoho internetových červů (jako například červa Morris). Je to možné ovšem pouze v případě, že aplikace, která obsahuje zranitelný kód (například fingerd), byla se StackGuardem zkompilována.
474
Obrázek 13.2
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
StackGuard umístí "kanára" na zásobník pod "návratovou adresu".
Červ Morris používal útok založený na kódu shellu, přičemž pro spuštění tohoto kódu modifikoval na zásobníku návratovou adresu funkce main(). Kód shellu zde byl vložen jako "řetězec" prostřednictvím zranitelné služby fingerd10. Rekompilace zranitelných služeb se StackGuardem může ochránit před linuxovými červy, kteří používají jednoduché útoky na zásobník. Červi jako Linux/Slapper používají přetečení na heapu, kterým StackGuard nemůže zabránit. Je však důležité poznamenat, že v současných počítačových červech není přetečení hromady obecně používanou technikou – většina červů používá jednoduchou techniku přetečení zásobníku. Používání StackGuardu je silně doporučeno. Kompilace StackGuardu pro Linuxu jsou dostupné a rekompilace se StackGuardem činí systém mnohem více bezpečnějším. Pro Microsoft Visual C++ .NET 2003 7.0 byla vyvinuta technika fungující podobným způsobem jako StackGuard. Ve verzi 7.1 došlo ke změnám a nově používaná metoda je spíše podobná technologii ProPolice.
13.2.2.2 ProPolice ProPolice vyvinul výzkumník IBM Hiroaki Etoh12. Uvádí mnoho nových vlastností, založených na StackGuardu. A podobně jako on poskytuje ochranu proti přetečení bufferu na úrovni kompilátoru. Jeho nové metody umožňují přesun hodnoty kanára a optimalizaci umístění bufferů a ukazatele funkcí v zásobníku, takže pokusy o exploitaci ukazatele funkcí jsou mnohem komplikovanější. Ilustrace je uvedena na obrázku 13.3.
Počítačové viry – analýza útoku a obrana
Obrázek 13.3
475
"Kanár" ProPolice pod ukazatelem rámce a "návratovou adresou".
ProPolice standardně chrání jak ukazatel rámce, tak i návratovou adresu pomocí metody, kdy je pod ukazatelem rámce umístěna hodnota kanára. Dále také spojí buffery řetězců a umístí je nad lokální proměnné, čímž poskytne lepší ochranu ukazatelům funkcí, které jsou lokálními proměnnými. ProPolice se také pokouší o vytváření lokálních kopií vložených ukazatelů funkcí, optimalizace kompilátoru zde však může způsobit určité problémy. Další vlastnosti zahrnují ukazatele funkcí ve strukturách, které jsou předány jako parametry, a které obsahují řetězcové buffery. Podobně jako StackGuard, i ProPolice si našel své místo při tvorbě operačních systémů. V současné době je k dispozici ve verzi 3.3 systému OpenBSD, čímž jej činí mnohem odolnějším proti útokům. ProPolice zajišťuje, že útoky pomocí přetečení zásobníku jsou mnohem komplikovanější a měl by tak nabízet velkou výzvu i velmi schopným útočníkům. Protože ProPolice zajišťuje integritu zásobníku, neposkytuje žádnou ochranu proti útokům na struktury heapu (hromady)13, čehož využívá například červ Linux/Slapper2.
13.2.2.3 Microsoft Visual Studio .NET 2003: 7.0 a 7.1 Microsoft uvedl volbu /GS poprvé ve Visual Studiu .NET 2003. Tato nová volba se nazývá jako "Kontrola bezpečnosti bufferů" (Buffer Security Check), a je přístupná jako volba při generování kódu. Implicitně je zapnutá. Uvažujme chybný kód v jazyce C ve výpisu 13.1.
Výpis 13.1 Chybný kód v jazyce C. int Bogus(char *mystring) { char buf[8];
476
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
strcpy(buf, mystring);
// pozor!
return 0; } void main(void) { Bogus("Toto je typické přetečení zásobníku!"); }
Kompilátor primárně chrání pole, která jsou nejméně pět bajtů dlouhá. Pro kratší buffery není kód pro testování bezpečnosti generován. Je to zřejmě takový bezpečnostní kompromis – předpokládá se, že k přetečení obvykle dochází až v rozsáhlejších bufferech. Jestliže se však útočníkovi podaří vložit svůj kód do chybné funkce, může být funkce exploitována nezávisle na tom, jak je buffer krátký. Podívejme se nyní na kód, který generuje VC .NET 2003 7.0: 00401296 push offset string "Toto je typické přetečení zásobníku!" 0040129B call Bogus (401000h)
Prostřednictvím zásobníku jsme vložili do funkce Bogus() ukazatel na dlouhý řetězec. Výpis 13.2 ukazuje, co se děje uvnitř této funkce.
Výpis 13.2 Nastavení "Security Cookie". Bogus: 00401000 sub esp,0Ch 00401003 mov eax,dword ptr [___security_cookie (407030h)] 00401008 xor eax,dword ptr [esp+0Ch] 0040100C lea edx,[esp] 00401010 mov dword ptr [esp+8],eax
Funkce Bogus() nejprve zpřístupní hodnotu security_cookie, která je náhodně vygenerovaná pomocí CRT. Speciální rutina CRT tuto hodnotu inicializuje jako náhodné číslo DWORD. Důvod je jednoduchý – může-li útočník uhodnout hodnotu security_cookie, bude schopen způsobit přetečení vložením "falešné" hodnoty security_cookie, což kontrola bezpečnosti bufferu nedetekuje. Takový útok je uskutečnitelný, pokud by útočník obešel tuto kontrolu bezpečnosti, přepsal předchozí rámec nad zásobníkem, pomocí ukazatele funkce spustil svůj kód a nakonec, kvůli utajení, opravil obsah zásobníku. Hodnota security_cookie je nejprve "XORována" s aktuální návratovou adresou a poté je uložena za návratovou adresou na zásobníku jako cookie. Potom provede chybné (buggy) kopírování, například pomocí funkce strcpy(), viz výpis 13.3.
Počítačové viry – analýza útoku a obrana
477
Výpis 13.3 Podmínka možného přetečení. 00401014 mov eax,dword ptr [esp+10h] 00401018 sub edx,eax 0040101A lea ebx,[ebx] 00401020 mov cl,byte ptr [eax] 00401022 mov byte ptr [edx+eax],cl 00401025 inc eax 00401026 test cl,cl 00401028 jne Bogus+20h (401020h)
A nakonec epilogová rutina funkce Bogus() vezme uloženou hodnotu cookie a "dekóduje" ji do registru "ecx", což je ukázáno ve výpisu 13.4.
Výpis 13.4 Dekódování "Security cookie". 0040102A mov ecx,dword ptr [esp+8] 0040102E xor eax,eax 00401030 xor ecx,dword ptr [esp+0Ch] 00401034 add esp,0Ch 00401037 jmp __security_check_cookie (4013F1h)
Další skok epilogu vede do runtime části C, definovaného v setcook.c uvnitř zdrojového kódu CRT. To je ukázáno ve výpisu 13.5.
Výpis 13.5 Standardní "bezpečnostní" handler. void __declspec(naked) __fastcall __security_check_cookie(DWORD_PTR cookie) { /* verze x86 zapsaná v assembleru kvůli ochraně všech registrů */ __asm { cmp ecx, __security_cookie jne failure ret failure: jmp report_failure } }
Porovnání se tedy provede vůči původní bezpečnostní hodnotě cookie. Je-li detekován rozdíl, pokračuje kód na adrese report_failure. Pokud předtím nebyl nastaven žádný user_handler, provede se pouze stan-
478
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
dardní výpis. Nastavení uživatelského ovladače (user handler) umožňuje zajistit jinou funkcionalitu, než tu, kterou poskytuje výchozí metoda. Adresa uživatelského ovladače (user_handler) je ukazatelem na funkci, který je umístěný v datové sekci, takže v některých případech bude možné jeho přepsání pomocí přetečení. To umožní útočníkovi spustit jeho vlastní kód pomocí tohoto handleru. Pokud není user_handler nastaven pomocí funkce _set_security_error_handler(), je přetečení zásobníku ohlášeno uživateli a vykonávání programu je ukončeno. Hodnota cookie je umístěna pod ukazatel rámce, pokud ovšem nějaký existuje. Tímto způsobem může kontrola reagovat na útoky proti tomuto ukazateli. V kompilátoru verze 7.1 Microsoft zásadním způsobem vylepšil kontrolu bezpečnosti bufferu. Hodnota cookie již není XORována s návratovou adresou, což původně nepřinášelo žádnou viditelnou výhodu. Místo toho je tato cookie uložena a ověřována. Některá problémy zde popsané však vyřešeny nebyly. Nejdůležitějším rysem edice 7.1 je to, že buffery řetězců jsou spojeny dohromady. Ukazatele funkcí a ostatní lokální proměnné jsou pak umísťovány kompilátorem pod buffery na zásobníku. Implementace Microsoftu ohledně kontroly integrity zásobníku tak následuje nejdůležitější vlastnosti ProPolice. A podobně jako v případě ProPolice, i bezpečnostní volby Microsoft Visual Studia .NET 2003 způsobují konflikty s možnostmi optimalizace kompilátoru. V optimalizovaném kódu tak mohou vložené ukazatele funkcí sloužit jaké přímé reference do předchozího rámce zásobníku. Takové ukazatele funkcí ovšem mohou být přepsány a exploitovány ještě předtím, než se provede bezpečnostní kontrola, která se neprovádí před návratem funkce. Vnořená volání, která jako parametry používají poškozené ukazatele funkcí (prostřednictvím přímých referencí do volajícího rámce zásobníku), jsou tak kvůli těmto poškozením zranitelná. Jednou z uvažovaných alternativ je použití direktiv "pragma" vedoucí k vypnutí optimalizace pro některé části kódu (například pro sekce, které předávají ukazatele funkcí). To je však praxe, která dává prostor vzniku dalších problémů, jako je mazání "tajných míst v paměti" (odstraňování dočasných klíčů) na posledním řádku funkce, kterou může chytrá optimalizace eliminovat jako mrtvý kód. Je tomu z toho důvodu, že daná proměnná se po dosažení konce funkce jeví jako nevyužitá. Zbývající výzvou je pak standardní ošetřování výjimek ve Windows. Když je vyvolána výjimka, prochází se řetěz ovladačů pro nalezení aktivního ovladače výjimky, který bude vyvolán. Mnoho obecných typů exploitů Windows je založeno na tom, že se přepíšou rámce ovladačů výjimek založené na zásobníku, což vede ke spuštění kódu útočníka. Tuto techniku používá několik současných virů, stejně jako červ W32/CodeRed. Kontrola bezpečnosti bufferu sama o sobě tyto problémy nezmírňuje. Alternativou, která funguje proti těmto útokům, byla vyvinuta společností Symantec. Více informací je uvedeno v části 13.3, která popisuje techniky blokování červů. Je vhodné poznamenat, že pro Visual Studio 2005 Microsoft plánuje provést několik změn v implementaci přepínače /GS. Ty by se měly zaměřit především na nedostatky, popsané v této kapitole.
Počítačové viry – analýza útoku a obrana
479
13.2.3 Řešení na úrovni operačního systému a rozšíření run-time Kontrola integrity zásobníku pomocí kompilátoru je pouze jednou z mnoha možností ochrany proti přetečení na úrovni operačního systému. I když jsou rekompilované systémové komponenty (ať už samotného operačního systému nebo třetích stran) hůře zranitelné útoky založenými na zásobníku, nechráněné komponenty (ať už systémové nebo jakékoliv jiné) způsobují to, že systém zůstává stále napadnutelný. Ačkoli většina procesorů Intel neposkytuje ochranu na úrovni stránkování proti operacím vykonávaným na zásobníku, některé procesory ji poskytují, přičemž operační systémy mohou takové ochrany využívat (alternativy k systémům Intel jsou podrobněji popsány později). K nejzávažnějším problémům ochrany na úrovni překladače patří to, že pro kompilaci je potřebný zdrojový kód. Během několika posledních let se sice objevila nová řešení, která zdrojový kód nevyžadují, nicméně se vztahují ke specifickým procesorům (například Intel) nebo ke specifickým operačním systémům (jako je například Linux). Následující část pak rozebírá některá z nejvýznamnějších rozšíření takových systémů.
13.2.3.1 Solaris na systému SPARC Mnoho operačních systémů má v sobě zabudované mechanismy ochrany proti některým typům útoků pomocí přetečení bufferu. Například systémy Solaris mohou chráněny pouhou změnou nastavení systému v souboru /etc/system. Systém se tak může, pomocí zásobníku na procesoru SPARC, bránit proti útokům založených na přetečení bufferu. Ilustrace je na obrázku 13.4. set noexec_user_stack=1 set noexec_user_stack_log=1
Obrázek 13.4
Nastavení konfigurace Solarisu na SPARCu.
Důsledkem této změny nastavení systému je to, že uživatelský prostor zásobníku procesů Solarisu nebude mapován jako vykonatelný (exec), takže pokus o vykonání obsahu zásobníku povede k násilnému ukončení a k výpisu obsahu procesu (core dump). Tento výpis bude také součástí systémového logu (pokud je to nakonfigurováno). Situaci ilustruje obrázek 13.5. #pmap 653 653: /sbin/sh 00010000 272K read/exec
/sbin/sh
00062000
16K read/write/exec
/sbin/sh
00066000
24K read/write/exec
[ heap ]
FFBEE000
8K read/write
[ stack ]
total 320K
Obrázek 13.5
Uživatelský zásobník procesu "sh" není označen jako vykonatelný ("exec").
480
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
Některé systémy ochrany se pokoušely dosáhnout podobných výsledků použitím vykonatelných a datových segmentů pro procesory od Intelu (viz příklady v části 13.2.5). I toto řešení preventivně zabraňuje vykonání kódu na zásobníku. Přestože jsou tato řešení atraktivní, je důležité mít na paměti, že existují nebezpečí přetečení, která nevyžadují provádění kódu na zásobníku – například přetečení heapu nebo útoky return-to-LIBC. Právě v těchto případech mohou pomoci techniky založené na kompilátorech. Tyto technologie – StackGuard, ProPolice, nebo kontrola bezpečnosti bufferů od Microsoftu – se snaží potlačit možné zneužití prostřednictvím změny návratové adresy a ukazatele rámce. Některé z nich také znesnadňují zneužití ukazatelů funkcí. Je tedy vhodné poznamenat, že tyto systémy se navzájem dobře doplňují. Je také zřejmé, že pro zmírnění dalších negativ by měly být použity jiné techniky.
13.2.4 Rozšíření subsystému – Libsafe Některá řešení přidávají mechanismy ochrany do uživatelského adresovacího prostoru jednotlivých aplikací. Libsafe14 je run-time ochrana dostupná v systému Linux. Chrání proti napadení návratových adres, stejně jako proti útokům na rámec zásobníku. Není však schopna ochránit procesy, které mezi voláním funkcí nepoužívají ukazatele rámců na zásobníku. V takových případech Libsafe jednoduše nechává aplikace, aby si dělaly, co chtějí. Libsafe využívá jednu ze standardních vlastností Linuxu, která umožňuje "přetížit" některé funkce v dynamicky linkovaných knihovnách. Nahrává se jako dynamická knihovna a do adresovacího prostoru procesu zavádí jména funkcí, jako jsou memcpy() nebo strcpy(). Pokud je zavedena knihovna GLIBC (standardní run-time knihovna jazyka C v Linuxu), jsou tyto funkce již známy, takže se nepoužijí jejich verze v GLIBC, ale verze obsažené v Libsafe. Když aplikace zavolá strcpy(), bude nejdříve volat Libsafe. Libsafe trasuje zásobník použitím ukazatelů na rámce ze struktury zásobníku. Poté použije svoji logiku k validaci parametrů a k rozhodnutí, zdali je parametr příliš dlouhý a zdali je schopný přepsat místo uložení ukazatele rámce nebo návratové adresy. Pokud ano, Libsafe okamžitě zastaví běh procesu. Jinak se dynamicky přepne do GLIBC a zavolá původní funkci. V současné době zajišťuje Libsafe ochranu těmto funkcím – memcpy(), strcpy(), strncpy(), wcscpy(), stpcpy(), wcpcpy(), strcat(), strncat(), wcscat(), [v]sprintf(),[v]snprintf(), vprintf(), vfprintf(), getwd(), gets() a realpath(). Nejedná se sice o vyčerpávající seznam "zranitelných" funkcí, nicméně určitě obsahuje některé z nejobvyklejších zranitelností v kódu C. Libsafe 2.0 tak chrání nejvíce využívanou skupinu "zranitelných" funkcí před útoky založenými na napadání zásobníku. Chrání také funkce, které mohou být využity pro vykonávání exploitů založených na formátovacích řetězcích10.
13.2.5 Rozšíření režimu jádra Spousta rozšíření (extensions) režimu jádra se snaží pracovat s velkým množstvím různých útoků. Taková řešení však vykazují mnoho nedostatků, nehledě na fakt, že nějaké rozšíření v režimu jádra může snadno ovlivnit stabilitu systému, což platí i o technologii, která byla poprvé použita pod názvem PaX15 pro různé open-source systémy, která zahrnuje přímou manipulaci příznaků stránek v tabulkách strá-
Počítačové viry – analýza útoku a obrana
481
nek. V systémech s uzavřenými zdroji (closed-source), jsou problémy s podobnými rozšířeními ještě více markantnější. PaX a jeho další implementace, SecureStack16, nastavují v příznacích stránky "Supervisor" bit takovým způsobem, aby byl způsoben výpadek stránky (page-fault). Ten pak využívá ovladač produktu v případě, že jsou dané stránky zpřístupňovány v uživatelském režimu. Tímto způsobem je možné rozlišit, jestli se instrukční ukazatel odkazuje na zapisovatelnou stránku na zásobníku nebo na heapu. Implementace využívá důmyslnou techniku, která minimalizuje možné snížení výkonu tak, že k výpadkům stránek dochází při provádění instrukcí, a nikoliv během přístupu k datům. Tato technika udržuje snížení výkonu pod hranicí 5%. Podstata této techniky spočívá ve využití bufferů TLB (translation look-aside) procesorů Intel. Na 32bitové architektuře Intel popisuje jedna položka stránky tabulky (PTE) každou stránku paměti o velikost i 4kB. PTE popisuje informace o umístění stránky a pomocí několika různých atributů i její dosažitelnost. Jedním z PTE příznaků je také bit "Supervisor". Je-li tento bit nastaven v PTE, která přísluší určité stránce, pak pokus o přístup k ní, v uživatelském režimu, vyvolá výjimku. Dále pak provede ovladač produktu (product's driver), který je nastaven ke zpracování výjimek v režimu jádra, kontrolu bezpečnosti. PaX a SecureStack tento bit nastavují pro některé stránky v uživatelském režimu, jako například zapisovatelné stránky nebo oblasti zásobníku. Pro podstatu této techniky je klíčová skutečnost, že Pentium a následující procesory mají dva TLB – jeden pro přístup k datům (DTLB), a druhý pro instrukce (ITLB). Výpadky stránek jsou minimalizovány tak, že bit "Supervisor" je nastavován pouze ITLB kopii PTE, nikoli v DTLB16. Provádění kódu v zapisovatelných stránkách prostřednictvím ITLB tak může být snadno detekováno a následně znemožněno. Důležitou vlastností této techniky je to, že blokuje provádění kódu na zásobníku a na heapu. Provádění kódu v zapisovatelných stránkách je však bohužel běžné (typicky na systémech Windows, ale nejenom na nich). Dobrým příkladem této skutečnosti jsou například samorozbalovací archivy. Při legitimizaci pokusů o běh zapisovatelných stránek hlásí systém falešná pozitiva (false positive). Provádění kódu v zapisovatelných stránkách však naštěstí není běžné na serverových platformách. Pro zmírnění problémů s falešnými pozitivy nabízí PaX nástroj pro označení aplikací jako přátelských. Některé další specifické systémy mohou tento problém dále zmírňovat. PaX na platformě Intel implementuje ještě jeden mechanismus ochrany před prováděním kódu na zásobníku. Ten je založen na segmentaci adresovacího prostoru procesu a na přístupových právech samotných segmentů. Výhodou této segmentace je to, že nedochází ke ztrátě výkonu. Toto řešení však vyžaduje těsnou spolupráci se samotným operačním systémem, což vede k obtížím při vývoji na platformy, které nemají otevřený kód (open-source). Významným přínosem je však stabilita. Tento druh řešení je nezávislý nejenom na procesoru, ale také na verzi operačního systému (což zahrnuje i nezávislost na použité verzi service packu). Tyto techniky poskytují prostředky k ochraně proti široké skupině útoků v uživatelském režimu, které jsou nejvíce rozšířené. Nemusí však nezbytně nutně poskytovat ochranu proti přetečení v režimu jádra (na úrovni 0, ring 0), takže takové systémy pak nejsou odolné vůči zranitelnostem v operačním systému nebo v ovla-
482
Kapitola 13 – Techniky blokování červů a ochrany před pronikáním ...
dačích třetích stran, u kterých může škodlivý vstup vést k nepříjemným postranním efektům (novější verze PaX mají speciální ochranu pro stránky jádra). Útočník může ovšem překonat ochranu proti provádění kódu na zásobníku a heapu pomocí útoku typu "return-to-LIBC", který popisován dříve. Tyto problémy však mohou být zmírněny dalšími technikami, které jsou stručně popsány v části 13.3 věnované technikám blokování červů.
13.2.6 Doprovázení programů Ve výzkumných zprávách MIT17 byla jednou diskutována zajímavá technika se slibnými výsledky. Tato nová technika se nazývá doprovázení programů (program shepherding). Doprovázení programů je založeno na použití dynamického optimalizátoru, nazvaného jako DynamoRIO. Cílem RIO je rychlé provádění kódu a jeho optimalizace bez toho, aby byla vyžadována jeho rekompilace. Tento projekt byl založen na spolupráci mezi Hewlett-Packard a Massachusetts Institute of Technology (MIT)18. Technika doprovázení programů byla založena na tomto modelu a je výhodná jak z hlediska rychlejšího provádění kódu, tak i z hlediska implementace ověřování toku instrukcí. To je zajištěno implementací vyrovnávací paměti (cache) kódu, do které je kód programu po částech kopírován, a ověřováním tohoto programového kódu před jeho vykonáním. Systém tedy nikdy nevykonává skutečný kód, ale pouze jeho kopii, a to takovým způsobem, že využívá skutečné CPU systému, a nikoliv jeho emulaci. Některé části programu jsou při jeho běhu modifikovány, přičemž je možné tímto způsobem kód ovládat. To umožňuje bezpečné provádění aplikací. K tomu, aby se rozeznaly některé techniky exploitace, základní systém potřebuje některá rozšíření. Zvláště obtížným problémem je detekce změny toku kódu, která se objeví jako důsledek změny dat v adresovacím prostoru procesu. Například mohou být modifikována místa, jako jsou GOT (globální tabulka offsetů) v Unixu nebo IAT (adresovací tabulka importů) ve Windows – takto lze dosáhnout změn v toku kódu, které je velmi těžké detekovat verifikací toku kódu v cache.
13.3 Techniky blokování červů Tato část popisuje techniky, které byly vyvinuty a implementovány firmou Symantec jako alternativní řešení k potlačení prvních a druhých generací exploitů používaných červy. Zde předpokládáme, že většina červů raději zaútočí na zranitelné systémy (tedy takové, které nejsou nijak zabezpečeny proti přetečení), protože je jich mnohem více, než systémů dostatečně zajištěných. Z hlediska útočníka je neefektivní používat při exploitacích náročné techniky, protože celkový výsledek útoku může být označen za úspěšný i bez nich. Tento závěr vzešel z revize několika posledních červů, jako jsou Linux/Slapper a W32/Slammer, které byly zodpovědné za většinu hromadných infekcí v poslední době. Techniky popsané v této části mohou takové útoky efektivně zastavit; uvedené principy jsou však pouze demonstrační a jejich účelem je ukázat, jak moc efektivní mohou tato řešení být. Nejedná se o ucelenou skupinu myšlenek, ale spíše o ukázku spolehlivých pravidel, která mohou být dostatečně efektivní vůči rychle se šířícím počítačovým červům. Použití takových pravidel může být součástí většího systému pro řízení přístupu, případně mohou být zkombinována s podobnými systémy.