ActiveX, IEjev grobar
Dokler ni Microsoft leta 1996 predstavil ActiveX, je bil splet veliko varnejši. Kajti vsaka izvršna koda, ki je distribuirana prek medmrežja, je poligon za razvijanje novih načinov zlorab. ActiveX je očitno idealen poligon za kaj takega. Zadostuje bežen pogled na priljubljeno "skladišče" izkoriščevalske kode, Milw0rm. Med zadnjimi tridesetimi "remote exploiti" je kar 23 posledica katere izmed varnostnih vrzeli v ActiveX.
ActiveX je zgolj marketinško ime, splavljeno ob združitvi Microsoftovih tehnologij COM (Component Object Model) in OLE (Object Linking and Embedding). Namen modela COM je ustvarjanje delcev kode t. i. gradnikov (components) ali kontrolnikov (controls), ki vsebujejo vmesnike (interfaces), ki jih lahko uporabljajo tudi drugi programi. OLE pa je protokol, ki omogoča povezovanje predmetov v okolju Windows. V končni fazi pa ActiveX dejansko predstavlja integracijo modela COM v Internet Explorer. Zunanji razvijalci imajo tako ob pomoči gradnikov možnost neposredne komunikacije s spletnimi programi, obenem pa tudi povečujejo funkcionalnost Internet Explorerja v obliki različnih razširitev (expansions), vtičnikov (plug-ins) in dodatkov (add-ins).
ActiveX na kratko
Gradnike najdemo najpogosteje v obliki datotek .ocx ali .dll, torej gre za izvršno kodo. V domače mlinčke se namestijo prek Internet Exporerja ali ob namestitvi nekaterih programov. Microsoft je seveda hitro odkril, v katerem grmu tiči nevarnost, zato je že pred časom začel omejevati ali celo preprečevati izvajanje nekaterih kontrolnikov. Z vsako različico brskalnika je bil obroč okrog gradnikov tesnejši. Najnovejša različica (IE7) ima tako vgrajen kar t. i. "Opt-in", ki določa, da so vsi gradniki privzeto onemogočeni, razen tistih, ki so definirani v posebnem registrskem ključu. Seveda pa lahko nameščene gradnike kasneje tudi ročno onemogočimo.
Gigant iz Redmonda se očitno na vso moč trudi povečati varno uporabo kontrolnikov ActiveX. Odkriti vrzel v Microsoftovih gradnikih, je tako danes že kar majhen podvig. Kljub temu številni zunanji razvijalci poskrbijo za visoko koncentracijo vrzeli ActiveX na že omenjenemu Milw0rmu. Nemalo gradnikov ima tako vgrajene potencialno nevarne lastnosti COM (Safe for scripting/Safe for initialization), četudi niso namenjeni interakciji z brskalnikom. Slednje je seveda zgolj odsev nepoznavanja osnovnih konceptov varnega in zanesljivega razvijanja kontrolnikov ActiveX. Takšne aplikacije tako kmalu postanejo tarča množice skriptnih otročajev. Uporabniki smo s strani Microsofta nemalokrat deležni posodobitev za IE, ki poleg dejanskih popravkov vsebujejo tudi sveženj registrskih vnosov (Kill bit), ki odpravljajo pomanjkljivosti v zunanjih gradnikih. Nezakrpane vrzeli v gradnikih ActiveX namreč vodijo do popolne kompromitacije sistema.
Vsak kontrolnik ActiveX ima unikatno številko CLSID (CLasS IDentifier), ki je definirana v registrskem ključu HKLM\Software\Classes\CLSID ali HKCR\CLSID. Ključa sta povsem enaka. Redkeje imajo gradniki določen tudi ProgID, torej simbolično ime. Vse ključe CLSID v računalniku lahko izpišemo z ukazom
reg query HKCR\CLSID | findstr "CLSID".
Seznam zna biti precej dolg. Internet Explorer lahko gradnik inicializira ob pomoči značke <OBJECT>, seveda pod pogojem, da je gradnik označen kot "varen za skriptno izvajanje" (Safe for scripting/SFS) ali "varen za inicializacijo" (Safe for initialization/SFI). Obe lastnosti sta definirani pod registrskim ključem HKCR\CLSID\<CLSID>\Implemented Categories. Čisto iz varnostnih razlogov pa je Microsoft vgradil tudi t. i. Kill bit. Za "agresivno" besedno zvezo se skriva preprost vnos v register, ki gradniku ActiveX preprečuje izvajanje v brskalniku. Torej, čeprav je gradnik označen za SFS/SFI, se ob vnosu Kill bit ne bo izvedel. S tem preprostim posegom v register lahko tudi sami onemogočimo inicializacijo kontrolnikov ob morebitni nezakrpani vrzeli. Kill bit za določen gradnik določimo z DWORD vnosom vrednosti 0x00000400 v registrski ključ HKLM\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\<CLSID>\CompatibilityFlags (support.microsoft.com/kb/240797).
Torej, če v nekaj besedah povzamemo, kako IE deluje, ko naleti na spletno stran z značko <OBJECT>: naprej preveri, ali je v registru zahtevani CLSID (če ga ni, se prikaže opozorilo uporabniku ali gradnik poizkusi namestiti); nato preveri, ali ima zahtevani CLSID postavljen Kill bit (v tem primeru prekine inicializacijo gradnika), v nasprotnem pa preveri, ali ima kontrolnik vgrajen vmesnik IObjectSafety, prek katerega preveri, ali je gradnik označen kot SFS/SFI. Če gradnik nima omenjenega vmesnika, IE preveri register za vnos GUID, ki določajo, ali je kontrolnik varen za izvajanje in inicializacijo. Brskalnik seveda prekine inicializacijo gradnika, če ne najde ustreznih registrskih vnosov.
Namestitev novega kontrolnika zahteva skrbniške pravice. Čeprav novejša Okna podpirajo t. i. "uporabniške gradnike", torej gradnike, ki ob namestitvi ne zahtevajo skrbniških privilegijev in ki jih lahko nato uporablja le določen uporabnik, je večina kontrolnikov nameščenih na globalni ravni. Atribut CODEBASE znotraj značke <OBJECT> pove brskalniku naslov URL, na katerem je programski paket. IE izvede preverjanje in če uporabnik namestitev potrdi, registrira in nato inicializira kontrolnik. Ko je gradnik enkrat nameščen, je na razpolago vsem uporabnikom, torej globalno.
Gradniki in (ne)varnost
Kakor smo že omenili, so gradniki izvršna koda, ki se v računalniku izvaja v kontekstu uporabnika, ki jo je izvedel. Večina uporabnikov Windows XP seveda po spletu križari s skrbniškimi privilegiji. Naj zveni še tako nemogoče - posledice vrzeli ActiveX je mogoče precej omejiti ali celo preprečiti s pristopom LUA (Least-User Account), torej z uporabo manj privilegiranega uporabniškega računa. Na srečo je tak pristop v Windows Vista privzet. Rezultat je več kot vzpodbuden, saj je izkoriščanje ActiveX vrzeli v najnovejših Oknih skoraj izkoreninjeno.
Nevarnosti slabo napisanih gradnikov lahko razdelimo v dve veliki kategoriji: prekoračitve medpomnilnika (buffer overflows) in vrivanje ukazov (command injection). Slednje so sicer bolj znane kot "insecure method exposure", za njihovo izrabljanje pa zadostuje, da najdemo funkcijo (metodo), ki ne preverja vnesenih parametrov in ki jih lahko nato poljubno določimo. Na primer takole:
iz obj.funkcija("niz") v obj.funkcija("\\windows\\system32\\cmd.exe").
O prekoračitvah medpomnilnika smo že pisali (Monitor 10/2006) in takrat tudi omenili, da so zaradi številnih varovalnih mehanizmov klasične prekoračitve sklada (stack overflow), kot so prepisovanje registra EIP in "vrnitev-v-dll", že skoraj pozabljene. Prekoračitve se tako vse bolj selijo v segment pomnilnika "heap" (kopica). Odkrite so bile številne tehnike, npr. razprševanje kopice (heap spraying) in "heap feng-shui", ki z uporabo JavaScripta omogočajo nadvse učinkovito izrabljanje vrzeli v gradnikih. Začuda pa znajo biti včasih uporabne celo zastarele metode, npr. prepisovanje SEH (SEH overwrite). Čeprav, resnici na ljubo, le redko.
Kot zanimivost velja omeniti tudi MoAxB (Month of ActiveX Bugs) ali "Mesec ActiveX hroščev", ki je potekal maja 2007, ko je heker po imenu shinnai vsak dan objavil novo vrzel v gradnikih ActiveX (moaxb.blogspot.com).
Morda zveni absurdno, vendar trenutno ni (javnega) orodja, ki bi učinkovito in zanesljivo odkrivalo ranljivosti v gradnikih ActiveX. Seveda so "skenerji" in "fuzerji", ki dokaj olajšajo delo, vendar se dolgočasnemu "ročnemu" raziskovanju ne moremo popolnoma izogniti. Idealnemu orodju se najbolj približata skenerja/fuzerja Axman (www.metasploit.com/users/hdm/tools/axman) in ComRaider (labs.idefense.com/software/fuzzing.php). Prvega je napisal nadarjeni in nadvse kreativni HD Moore, med drugim tudi avtor orodja Metasploit Framework. Uporaba obeh skenerjev je preprosta, morda je malce nepraktično le to, da Axman zahteva predhodno namestitev spletnega strežnika (npr. Apache).
ComRider prikaže lastnosti gradnika.
V napad ...
Da bo vse skupaj bolj pestro, bomo prikazali postopek izrabljanja vrzeli, ki je bila odkrita februarja letos. Gre za pomanjkljivost v programu Yahoo! Music Jukebox v2.2 (www.securityfocus.com/bid/27590/), ki je seveda že pokrpana. Uporabniki omenjene aplikacije so bili namreč deležni popravka prek samodejnega posodabljanja. Tudi sicer pa lahko vrzel pokrpamo sami z uporabo Kill bita (www.kb.cert.org/vuls/id/101676).
Prvi koraki ...
Najprej moramo ranljivost seveda odkriti, to je v bistvu najteže in zahteva precejšnjo iznajdljivost. Začnimo s pregledovanjem in izpisovanjem vseh gradnikov, ki so definirani kot SFS/SFI, te bomo namreč lahko inicializirali prek brskalnika. Torej poženimo ComRaider in izberimo "Start/Choose from controls that should be loadable in IE". V našem primeru ukaz prikaže 118 zadetkov, nekateri imajo postavljen Kill bit in torej odpadejo, vendar nas več kot očitno čaka veliko dela. YMP/Yahoo tudi sicer ni naveden, zato poskusimo drugače: "Start/Scan a directory for a registered COM servers" in izberimo "Program Files\Yahoo". Tokrat 112 zadetkov. Nas seveda zanimajo le tisti, ki jih lahko inicializiramo. Zdaj je že jasno, da ima kontrolnik vgrajen vmesnik IObjectSafety, saj bi bil v nasprotnem izpisan že v prvem poizvedovanju. Kriterijem tako ustreza pet objektov COM in končno lahko začnemo iskati ranljivosti. Uporabili bomo t. i. "fuzzing" ali "fault injection", torej vnašanje "napačnih" vhodnih podatkov. Naš namen je sesutje aplikacije in analiza delovanja v kaotičnem okolju. Tri objekte lahko mirne duše izločimo, saj ne dajejo v uporabo nobenih funkcij, temveč določajo zgolj lastnosti gradnika. Preostaneta nam torej dva kontrolnika: {5F810AFC-BB5F-4416-BE63-E01DD117BD6C} in {22FD7C0A-850C-4A53-9821-0B0915C96139}. Oba gradnika dajeta v uporabo veliko število funkcij, vendar nas zanimajo predvsem tiste, ki imajo podatkovni tip vrednosti "niz" (string). Vnašanje neustreznih podatkov v ComRaiderju ne obrodi želenih sadov, tudi sicer je "fuzzer", vgrajen v ComRaider, precej omejen, zato raje uporabimo Axman. Program poženemo z naslednjim ukazom:
gradniki axman
kjer "gradniki" predstavlja ime mape, v katero se bodo shranjevali najdeni CLSID. Med izvajanjem se bodo na zaslonu prikazovala/odpirala različna okna; brez skrbi, to je pričakovan odziv. Axman je nadvse učinkovit program, zato je pričakovati konstantna "sesuvanja" programov.
Med uporabo orodja Axman so takšna "sesutja" pogost pojav.
Seveda pa sesutje kot tako še ne pomeni, da je program mogoče uspešno izkoristiti v "zle" namene. To lahko naredimo le z uporabo razhroščevalnika (debugger). Začuda Axmanu ne uspe sesuti naših kontrolnikov, kljub temu pa nam ponudi nekatere namige (brskalnik med analizo večkrat zamrzne za daljši čas), iz katerih lahko sklepamo, da bi morda veljalo poskusiti z drugačnim pristopom - ročno delo torej. Uporabimo skripto, ki bo inicializirala gradnik in funkciji vrinila podatke v obliki niza. Sveto pravilo vrivanja vhodnih podatkov se glasi takole: začni z majhnimi vrednostmi! Pa začnimo. Prvi poskus, funkcija AddButton() ... Zadetek v polno!
Faultmon zapiše izjemo (exception), nastalo zaradi neveljavne vrednosti registra EIP.
Razprševanje kopice ali prepisovanje verige SEH?
Faultmon.exe (program, ki zapisuje sesutja programov) nam prikaže, da smo z vrivanjem niza dolžine 344 znakov uspešno prepisali register EIP. Zdaj lahko že govorimo o ranljivosti. Neizbežno vprašanje pa je seveda takole: le zakaj Axmanu ni uspelo odkriti vrzeli? Preprosto zato, ker analizo začne s previsoko začetno vrednostjo, seveda pa lahko začetne nastavitve spremenimo v izvirni kodi programa.
Vsekakor je pomembno razumeti proces, ki se sproži, ko nastopi izjema (exception). SEH (Structured Exception Handling) je mehanizem, ki je odgovoren za upravljanje izjem. Ob nastanku izjeme nadzor nad izvajanjem programa prevzame mehanizem SEH, ki skuša v t. i. verigi SEH (SEH chain) poiskati upravljavca (handler), ki bi bil pripravljen "obdelati" izjemo. Če ga ne najde, SEH prekine izvajanje aplikacije (vsem dobro znano "sesutje"). Jedro verige SEH je struktura EXCEPTION_REGISTRATION, ki vsebuje (najmanj) dva kazalca: "Pointer to the next SEH" in "SE Handler". SEH je seveda na skladu, omenjena kazalca lahko torej prepišemo z ustreznimi vrednostmi in tako preusmerimo izvajanje programa tja, kjer je lupinska koda (shellcode). V novejših različicah Oken stvar seveda ni več tako preprosta, saj je SEH zaščiten z nekaterimi varovalnimi mehanizmi: Kazalec "SE Handler" ne sme imeti vrednosti, ki je na skladu, z uporabo stikala /SafeSEH pa je Microsoft v svoje prevajalnike (compiler) vgradil možnost uporabe varnih, torej predhodno določenih upravljavcev SEH. Pomanjkljivost varnega stikala SEH je ta, da morajo biti za popolno učinkovitost vsi moduli z uporabo navedenega stikala. Verjetno je odveč omenjati, da številni razvijalci tega ne upoštevajo.
Prepisovanje strukture SEH. Napadalec je tu že zelo blizu popolni kompromitaciji sistema.
V našem primeru je gradnik preveden z uporabo /SafeSEH, torej prepisovanje verige SEH odpade. Izbrali bomo torej naslednjo možnost: razprševanje kopice. Dejansko gre za zelo učinkovito tehniko, ki odpove le v redkih primerih, na primer ko je vrednost nestabilnega kazalca (dangling pointer) zelo oddaljena od začetka kopice. Zaseganje (pre)velikih količin pomnilnika namreč neizbežno vodi v degradacijo sistemske odzivnosti. Celoten koncept temelji na predpostavki, da bomo s sistematičnim prepisovanjem pomnilnika prej ali slej prepisali tudi lokacijo, na katero kaže kazalec. Pomnilnika seveda ne bomo prepisovali naključno, temveč z lupinsko kodo in nizom NOP (No OPeration). Po vsej verjetnosti bo na želenem naslovu zdaj niz NOP, prek katerega bomo zdrsnili v lupinsko kodo, ki bo izvedla naše ukaze. Razprševanje kopice lahko dejansko izvedemo z nekaj vrsticami kode JavaScript in je tudi zato nadvse primeren za izrabljanje vrzeli v gradnikih ActiveX (www.varnostnenovice.com/index.php?option=com_content&task=view&id=1427).
Seveda je bilo razprševanje uspešno tudi v našem primeru. Potrebovali smo pičlih 400 blokov, prepisali smo torej le nekaj zanemarljivih MB pomnilnika. Mimogrede, AddButton() sploh ni edina ranljiva funkcija v tem gradniku.
ComRaider izpiše vrednosti podatkovnega tipa določene funkcije.
Ni univerzalnega zdravila proti razprševanju kopice, vendar imajo številni protivirusni programi vgrajene module, ki prepoznajo vzorce napada "heap spraying". Namensko orodje Comodo Memory Firewall (www.memoryfirewall.comodo.com) razmeroma dobro preprečuje različne oblike prekoračitev, tudi razprševanje na kopici. Tudi nepriljubljeno omejevanje izvajanja skriptne kode (JavaScript, VBScript) vsekakor pripomore k boljši varnosti.
Obramba
Najprej seveda najpomembnejše: ranljivi so le uporabniki Internet Explorerja. Drugi brskalniki namreč ne podpirajo gradnikov ActiveX. Firefox je sicer do različice 1.5 s posebnim vtičnikom omogočal izvajanje nekaterih kontrolnikov, vendar je razvoj dodatka zamrl in v najnovejši različici brskalnika (2.x) ni več podprt.
Izkoriščanje vrzeli ActiveX je nadvse priljubljeno pri t. i. napadih "drive-by download", kjer se nezakrpane ranljivosti v gradnikih izkoriščajo za namestitev zlonamerne kode v uporabnikov računalnik. Veliko "neznanih" orodnih vrstic (toolbar), vohunskih (spyware) in reklamnih (addware) programov je nameščeno podobno. Zadostuje obisk strani in ranljiv gradnik. Znani so primeri, ko so bile v napade"drive-by download" vpletene strani velikih organizacij in korporacij. Seveda ne namerno. Napadalcem zadošča trivialna vrzel (npr. vrivanje SQL ali XSS), s katero v kodo spletne strani vrinejo skrito značko <IFRAME>, ki vsebuje povezavo do zlonamerne kode v nekem drugem strežniku.
Nevarnosti v ranljivih gradnikih ActiveX ne gre podcenjevati, na srečo pa se lahko precej uspešno zaščitimo. Nekatere napotke smo že omenili (koncept LUA, Kill-bit); organizacija CERT je objavila priporočila za varno uporabo brskalnikov (www.cert.org/tech_tips/securing_browser/); izvajanje gradnikov, ki jih ne potrebujemo, lahko preprosto onemogočimo (v IE7 lahko to storimo pod "Orodja/Internet možnosti/Programi/Upravljanje dodatkov"); Microsoft pa je za razvijalce izdelal tudi posebno predlogo "Site-lock" (msdn2.microsoft.com/en-us/library/bb250471.aspx), s katero lahko izvajanje kontrolnika omejimo na specifično spletno stran.
Rešitve morda niso elegantne, a delujejo. Znan rek pravi, da je varnost obratno sorazmerna z uporabnostjo. Določanje prednosti eni izmed njiju pa je naša osebna odločitev.
Najprej seveda najpomembnejše: ranljivi so le uporabniki Internet Explorerja. Drugi brskalniki namreč ne podpirajo gradnikov ActiveX.
Microsoft je seveda hitro odkril, v katerem grmu tiči nevarnost, zato je že pred časom začel omejevati ali celo preprečevati izvajanje nekaterih kontrolnikov. Z vsako različico brskalnika je bil obroč okrog gradnikov tesnejši.
Posledice vrzeli ActiveX lahko precej omeji ali celo prepreči pristop LUA (Least-User Account), torej uporaba manj privilegiranega uporabniškega računa. Na srečo je tak pristop v Windows Vista privzet. Rezultat je več kot vzpodbuden, saj je izkoriščanje vrzeli ActiveX v najnovejših Oknih skoraj izkoreninjeno.
Kot zanimivost velja omeniti tudi MoAxB (Month of ActiveX Bugs) ali "Mesec hroščev ActiveX", ki je potekal maja lani, ko je heker po imenu shinnai vsak dan objavil novo vrzel v gradnikih ActiveX (moaxb.blogspot.com).