Ko se protivirusnik razblini ...
Ko pogovor nanese na ranljivost protivirusnih programov, njihovi zagovorniki zastavijo v svojo obrambo naslednje vprašanje: "Ali zaklepaš vrata, ko greš od doma? Le zakaj to počneš, ključavnica namreč ni 100 % varna in zanesljiva?" Seveda zaklepam vrata svojega doma, vsekakor pa tega ne bi počel, če bi zaradi pomanjkljive ključavnice izginila cela vrata.
Naj že takoj na začetku razjasnimo nekatera dejstva in se tako izognemo nesporazumom: članek ni namenjen prepričevanju uporabnikov, da so protivirusniki neučinkoviti in torej zgolj nepotrebna navlaka. Antivirus je nedvomno pomemben in nujen del standardne programske opreme vsakega mlinčka, ki ga poganjajo Okna. Tudi diskreditacija AV razvijalcev ni naš namen. Verjamemo, da jim ni lahko ob vseh količinah zlonamerne kode, ki jo vsak dan proizvede "temna stran" medmrežja. In seveda, nekatere tu opisane vrzeli so mnogi že odpravili. Namen članka je zgolj in samo eden: obveščanje uporabnikov o varnostnih pomanjkljivostih pri teh programih, ki bi jim jih priljubljen razvijalec protivirusne programske zaščite (ne)hote zamolčal. Protivirusnik namreč še zdaleč ni "popolni (od)rešitelj", temveč zgolj izdelek, računalniška varnost pa ni izdelek, temveč proces, ki ga moramo stalno nadgrajevati in dopolnjevati. S poznavanjem pomanjkljivosti v nameščeni programski opremi bomo korak bliže boljši varnosti. Sicer pa, le kdo bi varnost svojega sistema slepo zaupal (bolj ali manj hroščatemu) programu?
Osnove
Da, protivirusne programe je neverjetno lahko pretentati (delovanje protivirusnikov smo podrobneje opisali v Monitorju 9/2006). Pa si oglejmo na preprostem prikazu. Vzemimo, na primer, datoteko EICAR (www.eicar.org/anti_virus_test_file.htm), ki je sicer popolnoma nenevarna in namenjena le testiranju protivirusnikov. Njena posebnost je, da vsebuje le kode ukazov, ki so lahko prikazane s standardnimi ASCII znaki (EICAR je namreč izvršilna datoteka; ko jo zaženemo, izpiše privzeto besedilo). Originalna datoteka EICAR v Beležki/Notepadu je videti takole:
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
Protivirusniki prepoznajo EICAR kot "EICAR test file", torej kot datoteko, namenjeno preizkušanju. Datoteka je industrijski standard med izdelovalci protivirusne zaščite. Če je naš protivirusnik ne odkrije, je skrajni čas, da zamenjamo izdelovalca ... Ker vsi protivirusniki odkrivajo zlonamerno kodo na osnovi podpisov (signature detection), je izogibanje odkritju več kot očitno: spremeniti moramo zaporedje znakov v datoteki EICAR. S tem se spremeni binarni zapis, ki tako ne bo več enak primerku, shranjenem v "bazi podpisov". Torej, odprimo EICAR v Beležki in spremenimo niz znakov. Na primer takole:
X5O!P%@AP[4\PZX54(P^)7CC)7}$PWNING-EICAR-FOR-FUN-NOT-PROFIT....$H+H*.
Odkritju smo se uspešno izognili, naš EICAR pa je tudi po prilagoditvi povsem funkcionalen. Če ga poženemo, še vedno izpiše želeno besedilo. Preprosto, mar ne?
Enak pristop lahko seveda uporabimo tudi pri konkretni zlonamerni kodi. Potrebujemo le razhroščevalnik (debugger) in šestnajstiški urejevalnik (hex editor). Celoten proces spreminjanja je zelo nazorno opisan tule:
packetstormsecurity.org/papers/virus/Taking_Back_Netcat.pdf
So mutatorji premagani?
Zgornji postopek je vsekakor precej zamuden. Hekerji (no, pogosteje skriptni otročaji) isti učinek, vendar veliko hitreje, dosežejo ob pomoči "stiskalnikov" (packer), "šifrirnikov" (crypter) in mutatorjev programske kode (code mutator). Mutatorji so polimorfizem pripeljali do skrajnosti. V kodi spremenijo sintakso in zaporedje izvajanja ukazov, vendar ohranijo semantiko, se pravi končni učinek spremenjenega programa. Pred dobrim letom smo v Monitorju naredili poskus z dvema mutatorjema kode (CCryptor in CPervertor). Protivirusniki so takrat spremenjene "viruse" odkrili le v poraznih 14,8 % primerov. Po letu dni se je ob uporabi istih mutatorjev, zdaj že veliko bolj znanih, odkrivanje povečalo na "zavidljivih" 35-46,9 odstotka. Na žalost pa lahko ugotovimo, da nekateri "veliki" (McAfee, Kaspersky, NOD32, Panda, F-Secure, F-Prot, Norman, Microsoft ...) tudi po letu dni še vedno ne znajo odkriti tako prilagojene kode.
Podobno se lahko izognemo tudi odkrivanju vse bolj razširjenih zlonamernih skript, ki izkoriščajo vrzeli v brskalnikih in so odskočna deska za namestitev različnih sleparskih orodnih vrstic (rogue toolbars), prevarantskih iskalnikov (fake search engines) ter različnih drugih zlonamernih programov. Večina protivirusnikov namreč ob pomoči različnih modulov za odkrivanje skriptov odkriva tudi zlonamerno spletno kodo (predvsem JavaScript/VBScript). Iznajdljive glave so kaj kmalu odkrile preprost, a učinkovit način izmikanja: na različna mesta v kodi vstavimo 256 (ali več) ničelnih zlogov (null byte). Metoda je sicer le ena izmed različic zastrupljanja z ničelnim zlogom (null-byte poisoning), deluje pa le v primeru, ko uporabljamo brskalnik Internet Explorer. Firefox/Opera tako modificirane kode namreč ne upodabljata (izrisujeta).
Opisani načini izogibanj so izvedljivi zgolj zaradi arhaičnega načina odkrivanja. Drži, preverjanje podpisov je le eden izmed načinov odkrivanja, sicer resda osnoven. Protivirusniki obvladajo tudi druge metode odkrivanja in preprečevanja izvajanja. Zlonamerno kodo tako odkrivajo ob pomoči hevristike, obnašanja (behavioral detection), peskovnika (sandbox), preverjanja integritete datotek (file integrity) ... Navedene metode naj bi pripomogle pri odkrivanju tudi neznane, vendar morebiti nevarne kode. Na prvi pogled odlična zaščita, ki v celoti preprečuje izvajanje škodljivih programov. V idealnem svetu morda res ...
Klasične programske napake na ravni jedra
Protivirusniki imajo namreč še eno pomembno značilnost. V sistem naložijo različne gonilnike ter omogočijo delovanje namenskih storitev (services), ob pomoči katerih lahko opravljajo svoje poslanstvo. Tako gonilniki kakor storitve pa se izvajajo z izredno visokimi sistemskimi privilegiji. Zakaj bi torej uporabljali namensko zlonamerno kodo, pri kateri je možno odkritje, če lahko za kompromitacijo sistema izkoristimo vrzeli v samem protivirusniku. Ranljivosti je silno veliko in zanje ni imun noben protivirusnik. Vprašanje je le, v kakšnem obsegu in kako pogosto se pojavljajo. Vrzeli so v razponu od najbolj težavnih, te zahtevajo silno veliko znanja s strani napadalca, do povsem banalnih in splošno znanih, pri katerih se lahko le vprašamo, kako, presneto, da jih niso odkrili med procesom razvijanja in preizkušanja. Ljudje bi pričakovali, da razvijalci programov, ki promovirajo in zagotavljajo varnost, najprej poskrbijo za zanesljivost lastnih izdelkov in torej izvedejo podrobno revizijo kode (code auditing) in intenzivna preskušanja.
Pa poglejmo, kako globoko seže zajčja luknja ... Različne vrste prekoračitev, tako na skladu (stack) kakor kopici (heap) ali celoštevilčne (integer), so precej pogost pojav. Prekoračitve so najpogosteje izvedene prek ranljivih kontrol ActiveX ali protivirusnih storitev, ki delujejo na določenih vratih. Posebej pogoste so tudi nepravilnosti pri obdelavi različnih stisnjenih (UPX, bzip, rar ..) ali prilagojenih PE (Portable Executable) datotek. Torej t. i. ranljivost "file parsing", ki lahko vodi do prekoračitve medpomnilnika ali zavrnitve storitve (DoS) in "sesutja" programov. Protivirusni programi zaradi naprednih zaščitnih mehanizmov intenzivno, s pomočjo gonilnikov oz. jedrnih modulov, izvajajo tudi prestrezanje jedrnih funkcij (kernel hooking) s spreminjanjem SSDT (System Service Dispatch Table), torej tabele, v kateri so shranjeni kazalci do jedrnih funkcij. Čeprav je metoda nedokumentirana in nepodprta s strani Microsofta, je pri pravilni izpeljavi lahko zelo učinkovita. Tako v pozitivnem kakor negativnem smislu. Nobena skrivnost ni, da je prestrezanje SSDT priljubljena tehnika "skrivanja" številnih korenskih kompletov. Težave pa nastanejo, če izpeljava prestrezanja ni pravilno izvedena. Vsakršna nepravilnost pri izvajanju jedrne kode namreč pogosto vodi do osovraženega modrega zaslona. Bistvo je v tem, da imajo parametri do upravljavcev SSDT (SSDT function handlers) izvor v uporabniškem prostoru, medtem ko se t i. "handlerji" izvajajo v jedrnem prostoru. Ko preverjanje argumentov funkcij API ni ustrezno, lahko tudi neprivilegirani uporabnik namenoma povzroči (najmanj) sesutje operacijskega sistema. Četudi je tabela sistemskih klicev privzeto definirana "samo za branje" (read only), je teoretično možno tudi izvajanje arbitrarne kode v obroču ring 0, torej eskalacija privilegijev, vendar slednje v praksi še ni bilo javno potrjeno. Naravnost impresivno pa je, koliko programov (ne le protivirusnikov) nepravilno izvaja prestrezanje SSDT:
www.matousec.com/projects/windows-personal-firewall-analysis/plague-in-security-software-drivers.php
Microsoft je seveda objavil številne dokumente, v katerih je programerjem gonilnikov svetoval učinkovito in sistematično preverjanje parametrov funkcij API. Ker priporočila očitno niso zadostovala, je storil še naslednji korak. Uporabniki Windows Vista x64, Windows Server 2003 SP1 x64 ter Windows XP Professional x64 si tako lahko oddahnejo, saj mehanizem "PatchGuard" oz. "kernel patch protection" preprečuje vsakršno modifikacijo tabele SSDT.
No, ostanimo še trenutek v jedrnem prostoru, kjer v zadnjem času pridobivajo na renomeju t. i. vrzeli IOCTL. IOCTL (Input/Output Controls) so namenjeni komunikaciji med gonilniki in uporabniškimi programi, komunikacija pa poteka prek strukture IRP (Input/Output Request Packet). Zaradi neučinkovitega preverjanja vnesenih podatkov v dispečerskih upravljavcih IOCTL (dispatch handlers) znotraj gonilnikov lahko vsiljivec spremeni parametre IRP in tako povzroči prekoračitev medpomnilnika v jedrni strukturi. Uspešna zloraba vodi do izvajanja arbitrarne kode in eskalacije privilegijev. Četudi izkoriščanje teh pomanjkljivosti zahteva veliko znanja, so priljubljena tarča napadalcev, saj skorajda ni protivirusnika, v katerem ne bi bila odkrita vsaj ena vrzel IOCTL. Velja omeniti, da je v primeru IOCTL nemočen tudi PatchGuard. Ali, drugače, ranljivi so tudi uporabniki 64-bitnih Oken, z Visto vred. O tem, da imajo vrzeli v pomanjkljivo napisanih gonilnikih globoke korenine, pričajo tudi odkrite ranljivosti v programih enega izmed gurujev računalniške varnosti Marka Russinovicha (Microsoft Sysinternals), konkretno v orodjih DebugView, RegMon in Process Monitor.
Nekaj zanimivih vrzeli
Čeprav omenjene ranljivosti ne morejo biti ravno v čast razvijalcem, ki promovirajo "absolutno varnost", jih vendarle lahko nekako toleriramo. To, kar sledi, pa je popolnoma nesprejemljivo (skorajda iz kategorije "Saj ni res, pa je"). Odkrivanje naslednjih vrzeli je namreč povsem enostavno, pa tudi samo odpravljanje je dokaj trivialno. Seveda pa mora biti s strani razvijalca določen interes.
1.) Brezplačna različica BitDefender 10 tako uporablja knjižnico za stiskanje (compression library) zlib.dll 1.1.3 iz leta 1998, za katero je znano, da vsebuje pomanjkljivost "double free", ki lahko vodi do prekoračitve kopice (heap overflow).
2.) Cela serija protivirusnikov (TrendMicro, Norman, Ikarus, Ashampoo, Comodo, Outpost ...) je ranljiva za zdaj že legendarno zvijačo "program.exe", ki smo jo v naši reviji omenili že pred časom (glej Monitor 07/2006). Resnici na ljubo je krivda za to ranljivost v sami funkcionalnosti operacijskega sistema Windows in torej samo na strani Microsofta. Čeprav se pomanjkljivost vleče še iz časov Windows NT 3.1, gigant iz Redmonda "improper file path handling" ne jemlje kot varnostni problem (mimogrede, ranljivih je sicer tudi nekaj Microsoftovih programov) in zato napake ne namerava v celoti zakrpati. Slednje bi namreč lahko imelo katastrofalne posledice za podedovano združljivost (backward/legacy compatibility). Razvijalcem torej ne preostane drugega, kot da težavo odpravijo sami, to pa lahko storijo zelo preprosto: s pravilno uporabo družine funkcij CreateProcess() (msdn2.microsoft.com/en-us/library/ms682425.aspx). Microsoft sicer trdi, da je napako odpravil že s tem, da je v novejših operacijskih sistemih XP/2003/Vista neprivilegiranim uporabnikom privzeto onemogočeno pisanje v korenski imenik, kar v celoti izključuje izvajanje datoteke "program.exe". To resda drži, vendar je zadeva še vedno funkcionalna v Windows 2000 (da, nekateri ga še vedno uporabljajo) in v primeru nepravilno nastavljenega seznama za nadzor nad dostopom (ACL; Access Control List), pa tudi, ko je uporabnik član skupine "Power User". V teh primerih je zvijača "program.exe" najenostavnejši način eskalacije privilegijev v račun NT AUTHORITY\SYSTEM. Zahvaljujoč mehanizmu "Service Hardening", je Microsoft omenjeno težavo v Visti dokončno odpravil na eleganten način: storitve se v Visti povečini ne izvajajo v sistemskem kontekstu. Konec koncev pa lahko težavo zelo enostavno odpravimo tudi sami uporabniki: v registru postavimo ImagePath do ranljivega programa v dvojne narekovaje.
3.) Nekateri Protivirusniki ob namestitvi spremenijo dovolilnice namestitvenih imenikov ali datotek v Everyone:Full Control. To pomeni, da jih lahko vsakdo brez težav zamenja ali odstrani. Vsiljivec preprosto zamenja eno izmed izvršilnih datotek programa s svojo (ustrezno preimenovani cmd.exe popolnoma zadostuje) in ob naslednjem zagonu sistema ga pričaka ukazni poziv s sistemskimi privilegiji. Zanimivo, da so bile podobne pomanjkljivosti odkrite tudi v nekaterih protivirusnikih za okolja Unix. Pri nekaterih je bila namreč odkrita t. i. vrzel "insecure /tmp file creation", ki omogoča neprivilegiranemu uporabniku izvajanje napadov symlinks, torej izvajanje ukazov s privilegiji uporabnika, ki je namestil programov (pri protivirusnikih je to vedno uporabnik root).
4.) No, pa se dotaknimo še našega prvega članka o izogibanju odkrivanja protivirusnikom (že omenjeni Monitor 9/06), ki je bil pred objavo poslan domačemu zastopniku protivirusne opreme Panda, ta pa ga je posredoval gospodu Fernandu de la Cuadru, strokovnemu uredniku za stike z javnostjo pri Panda Security. Ta je zatrdil, da bo Pandina tehnologija TruPrevent uspešno in zanesljivo izsledila vsakršno zlonamerno kodo. Morda res, vendar je njihov takratni izdelek Panda AntiVirus 2007 ter pozneje Panda AntiVirus 2008 vseboval t. i. vrzel "insecure file permissions" in je torej omogočal trivialno eskalacijo privilegijev neprivilegiranega uporabnika na sistemsko raven brez uporabe zlonamerne kode. Za nameček pa so nekateri njihovi izdelki tudi nepravilno izvajali prestrezanje SSDT. Panda Security je navedene pomanjkljivosti zdaj že odpravil ...
Je aroganca res pravi pristop?
Če želimo odkriti stopnjo profesionalnosti določenega razvijalca, je dovolj, če preverimo njegov odnos do varnostnih raziskovalcev oz. t. i. pristopa "full-disclosure" (FD). Znano je, da morajo razvijalci programske opreme skozi tri faze: fazo zanikanja, fazo jeze in groženj ter fazo sprejemanja. Praviloma so velike korporacije v fazi zanikanja ali jeze (groženj), manjši izdelovalci pa so veliko bolj dostopni in sprejemljivi. Nekateri pa dobesedno prekoračijo vsakršno mejo profesionalnega pristopa in uzanc. Družba Norman je npr. do strokovnjakov, ki jo opozorijo na vrzeli, celo brezbrižna in arogantna:
www.nruns.com/advisories/[n.runs-SA-2007.020] - Norman Antivirus ACE parsing Arbitrary Code Execution Advisory.txt.
Komentar verjetno ni potreben. Ob takem odnosu s strani razvijalcev vsekakor ne čudi, da mnogi raziskovalci obupajo in javno objavijo podrobnosti, še preden je izdan uradni popravek. Mnogi namreč še vedno ne dojamejo, da namen FD ni postavljanje pogojev ali izvajanje pritiska na razvijalce, temveč garancija, da bodo zakrpali vrzel.
Kako varen je torej naš protivirusnik?
Najbolje, da to ugotovimo kar sami. Za začetek uporabimo orodje AccessChk:
www.microsoft.com/technet/sysinternals/Security/AccessChk.mspx
ali grafični ekvivalent AccessEnum:
www.microsoft.com/technet/sysinternals/Security/AccessEnum.mspx
in preverimo dovolilnice datotek, storitev, predmetov, registrskih ključev ... Če naletimo na Everyone:Full Control ali Everyone:Write, bodimo pozorni in podrobneje preglejmo zadevo. Preden se lotimo spreminjanja dovolilnic, velja razmisliti: spremembe lahko včasih negativno vplivajo na funkcionalnost programov.
Za odkrivanje nepravilnega prestrezanja SSDT uporabimo orodje BSODhook (www.matousec.com/projects/windows-personal-firewall-analysis/plague-in-security-software-drivers.php). Če odkrijemo, da je naš program ranljiv, kaj veliko sicer ne moremo storiti. Preostane nam le upanje, da je nekdo že obvestil razvijalca in bo popravek morda kmalu na voljo. Pri odkrivanju vrzeli IOCTL nam lahko pomaga program Kartoffel (kartoffel.reversemode.com), vendar je orodje napredno in zahteva določeno predznanje in razumevanje problema s strani uporabnika. Tudi tu kaj veliko sami ne moremo storiti, poleg upanja/čakanja na popravek lahko kvečjemu zamenjamo protivirusnik ...
Lahko seveda tudi ignoriramo vse zgoraj napisano in se vedemo, kakor da se ni zgodilo nič. Kot da to ni naš problem, saj nas varuje popoln protivirusnik ...
Povezavi:
www.nruns.com/parsing-engines-advisories.php
labs.idefense.com/intelligence/vulnerabilities
Pred dobrim letom smo v Monitorju naredili poskus z dvema mutatorjema kode (CCryptor in CPervertor). Protivirusniki so takrat spremenjene "viruse" odkrili le v poraznih 14,8 % primerov. Po letu dni se je ob uporabi istih mutatorjev, zdaj že veliko bolj znanih, odkrivanje povečalo na "zavidljivih" 35-46,9 odstotka.
Ljudje bi pričakovali, da razvijalci programov, ki promovirajo in zagotavljajo varnost, najprej poskrbijo za zanesljivost lastnih izdelkov in torej izvedejo podrobno revizijo kode (code auditing) in intenzivna preizkušanja.
Lahko seveda tudi ignoriramo vse zgoraj napisano in se vedemo, kakor da se ni zgodilo nič. Kot da to ni naš problem, saj nas varuje popoln protivirusnik ...