MTA SZTAKI; E4 - 4671/4/2003
•
Utolsó nyomtatás: 2004. 07. 08.
Nem utolsó sorban a minőségi, nagy biztonságú termékek és rendszerek piaci védelmére, az olcsó, nem bizonyítottan biztonságos eszközök és szolgáltatásokkal szemben.
MTA SZTAKI; E4 - 4671/4/2003
Utolsó nyomtatás: 2004. 07. 08.
elektronikus aláírással is foglalkozó Informatikai Biztonság Albizottság (INBA). Ezek keretében több jelentős kiadvány jelent meg (elérhetők az ITKTB honlapjáról: http://www.itktb.hu): •
A Magyar Információs Társadalom Stratégia elektronikus aláírás részstratégiája
•
Informatikai biztonsági részstratégia 1 és 2. kötet
•
A Magyar Információs Társadalom Stratégia intelligens kártya részstratégiája
•
Magyar Információ Biztonsági Értékelési és Tanúsítási Séma (MIBÉTS)
Fontos megemlíteni, hogy 2004-ben megalakult a Magyar Elektronikus Aláírás Szövetség (MELASZ, angol név: Hungarian Association for Electronic Signature, HAES) és már az eat új szövegének és más idetartozó tanulmányok véleményezésében igen aktív tevékenységet fejt ki. Összességében megállapítható hogy a célok helyesek, felgyorsultak az események, és ha ez folyatódik a jelenlegi nehézségek zömét rövid idő alatt le lehet győzni. Naivitás lenne viszont azt hinni, hogy a fejlődés nem fog folyamatosan újabb és újabb problémákat generálni. A feladat az, hogy ezeket is rendbe kell és lehet tenni, ha folyamatos az odafigyelés és az igény arra, hogy a nemzetközi szabványosítási folyamatokban a hazai szakemberek és államigazgatási döntéshozók részt vegyenek.
4.9
Biztonságos szoftverfutási környezet (TCB)
Ábra 45. Hierarchikus elektronikus aláírás termék tanúsítási folyamata.
Egy teljes aláíró rendszer egészében a nulláról való tanúsítása sem időben, sem költségekben nem valósítható meg a jelenlegi hazai helyzetben. Nemzetközi szinten sem általános, gyors és olcsó folyamat egy ilyen munka, ezért el kell fogadni a hierarchikus tanúsítási módszert, vagyis azt, hogy nagyobb rendszerelem tanúsításában elfogadjuk az összetevők (építő elemek) már meglévő termék tanúsítványait. Természetesesen alapos vizsgálatnak kell alávetni az építő elemek környezeti feltételeit, hogy a csatlakozó elemek azokat kielégítik-e.
4.8.10
4.9.1
A biztonságos szoftverfutási környezet jelentősége
A biztonságos futási környezet egy számítógépes rendszer biztonságának a legalapvetőbb eleme, függetlenül attól, hogy a hálózaton elérhető-e, és ha igen, akkor kliens vagy szerver funkciókat lát-e el. A biztonságos futási környezet (TCB) teljes definíciója az INFOSEC szójegyzéke [Infosec] alapján a következő:
Következtetések
A biztonságos elektronikus aláíró rendszerek műszaki feltételei adottak, bár a rendszerek beruházási költségei jelentősek. A jogszabályok és szabványok átmeneti hiányosságai szakértelemmel áthidalhatóak. A legnagyobb akadály az elterjedésben azon alkalmazások sokaságának hiánya, amelyek, a befektetet költségek megtérülését biztosítanák. Ez igaz a végfelhasználó és a szolgáltatók oldalán is. A piaci verseny és fejlődés előfeltétele a kritikus tömeg elérése, ami állami beavatkozás nélkül nem remélhető. Az elektronikus üzletvitel és adminisztráció egyik leglényegesebb eleme az elektronikus aláírás, ami nélkül az összes többi csak korlátozott eredményeket hozhat. Előző években sokat ígérő kezdeményezések indultak be a 1126/2003. (XII. 12.) Korm. Határozata a Magyar Információs Társadalom Stratégiáról és annak végrehajtásáról (MITS) rendelet alapján. Létrejött az Információs Társadalom Koordinációs Tárcaközi Bizottság (ITKTB) és annak számos albizottsága. A tanulmány szemszögéből legjelentősebb az MTAsec_w1
Mielőtt a webszerverek biztonságára térnénk, külön kell tárgyalnunk a biztonságos szoftverfutásai környezet fogalmát és elvárásait.
281/517
„A biztonságos futási környezet (TCB - Trusted Computing Base) a számítógépes rendszer védelmi mechanizmusainak összessége, amely magába foglalja a hardvert, a firmware-t és a szoftvert, amelyek az informatikai biztonságpolitika (security policy) betartatásáért felelősek. Megjegyzés: Az, hogy a biztonságos futási környezet mennyire képes kikényszeríteni az egységes informatikai biztonságpolitikát, a biztonságos futási környezeten belüli védelmi mechanizmusok hibátlanságán, a hibátlanságot bizonyító mechanizmusok védelmén valamint az informatikai biztonságpolitikához kapcsolódó paraméterek megfelelő alapadatain múlik.” Jelen fejezet ennek a futási környezetnek csak a szoftver részével fog foglalkozni, annak is csak egy viszonylag kis, a gyakorlati hálózati biztonság szempontjából releváns részével. Ennek az az oka, hogy az informatikai rendszerek jelentős részén a felhasználóknak (legyenek azok bármilyen tudásszinten) nem áll módjában megválasztani, hogy milyen biztonsági jellemzőkkel bírjon a rendszer építésénél felhasznált számítógép hardver és firmware. Ezeket a tulajdonságokat a dokumentációk extrém kivételektől eltekintve meg sem említik. Azt azonban ki lehet jelenteni, hogy az informatikai rendszerek kompromittálódásáért szinte soha nem ezek a rendszerkomponensek felelősek. A rendszerek vesztét leggyakrabban a hálózaton elérhető
MTAsec_w1
282/517
MTA SZTAKI; E4 - 4671/4/2003
Utolsó nyomtatás: 2004. 07. 08.
szolgáltatások okozzák, ritkábban a helyben, csak a számítógép előtt ülve elérhető programok. Így tehát a legnagyobb hangsúlyt azokra a részekre kell fektetni egy rendszer megerősítésénél, melyek a hálózatról elérhető szolgáltatások biztonságát kisebb-nagyobb mértékben növelik. Ha a hálózati rendszerek védelmét akarjuk tárgyalni, akkor nem hagyhatjuk említés nélkül a rendszerek szoftver futási környezetét. Nézzünk egy példát! Amennyiben meg akarunk védeni egy webszervert, akkor a védelem felépítésének csak egy nagyon kicsi része a webszerver telepítése és beállítása. Ha komoly biztonsági szintre törekszünk, akkor fel kell készítenünk a futtató rendszert a webszerver vagy az aktív webtartalom sérüléseiből adódó esetleges problémákra. Gondoskodnunk kell arról, hogy egy esetleges sikeres támadás esetén a támadó ne legyen képes a rendszer más szolgáltatásaiban is kárt tenni, lehetőleg semmilyen, a webszerver működéséhez üzemszerűen nem szükséges információhoz ne tudjon hozzáférni. Fontos az is, hogy ilyen esetben a rendszert ne lehessen egy másik rendszer, vagy ugyanazon gép másik alrendszere ellen intézendő támadás kiindulópontjául használni. Ezek a veszélyek az alaprendszer és a szerverprogram beágyazási módjának, jogosultságainak megfelelő tervezésével és beállításával nagymértékben csökkenthetők. Ezért nem hagyható el egy hálózati rendszer tervezésénél a hálózati kiszolgálórendszereket futtató alaprendszer körültekintő tervezése, felépítése és karbantartása.
4.9.2
Tipikus programozási hibák
MTA SZTAKI; E4 - 4671/4/2003
eszközök (pl. perl
Utolsó nyomtatás: 2004. 07. 08.
-T
kapcsolóval, ld. man
http://www.perl.org/; RaceGuard,
perlsec,
vagy a Perl honlapját:
http://www.immunix.org/raceguard.html, fordítók
szemantikai elemző képességei, pl. a nem inicializált változók kiszűrésére), de ezek csak a problémák egy nagyon kicsiny részére nyújthatnak megoldást. Ennek a problémacsoportnak a megoldása kizárólag a fejlesztők továbbképzésével oldható meg. 4.9.2.2
Nyelvfüggő programozási hibák
Védelmi szempontból a nyelvfüggő programozási hibák lényegesen érdekesebbek, mert sok esetben megelőző módszerek segítségével meg lehet akadályozni a kihasználásukat. Mivel a hálózati rendszerek fejlesztésének tipikus programozási nyelve a C, és mivel ez a fejezet csak egy rövid bevezető a programozási hibákba, ezért most a C nyelv tipikus hibái közül mutatunk be egyet, amely az elmúlt évek legtöbb programhibájáért volt felelős. A hiba neve: puffer túlcsordulás (buffer overflow, becenevén BOF). Sok alfaja létezik, a hibát kihasználó támadási módok elemzéséről írt tanulmányokkal egy kisebb könyvtár megtölthető lenne. int buffer_overflow_me(char *str) { char buffer[20]; strcpy(buffer, str); printf("Buffered data: %s\n", buffer); return 0; }
1. példa: C programozási nyelvű függvény tipikus hibával A fejezetbe beillesztettünk egy első ránézésre nem ideillő részletet. Mint rózsabokor a sivatagban. Mit keres itt egy rövid leírás a tipikus programozási hibákról? A kockázatok helyes megítéléséhez és a védelmi rendszerek felépítéséhez meg kell ismerni azon hibák némelyikét, amelyeket a programrendszerek fejlesztői gyakran elkövetnek, hogy a rendszertervezőnek fogalma legyen róla, hogy mi ellen is kell védekezni. 4.9.2.1
Nyelv-független programozási hibák
A programozási hibák két fő csoportba sorolhatók: a nyelv-független és a nyelvtől függő programozási hibákra. Az első hibacsoport olyan, általában program logikai hiba, amely lehetővé teszi a program védelmi rendszerének kikerülését, vagy amelyik miatt a program olyan tevékenységre kényszeríthető, amelyet a tervezők eredetileg nem szerettek volna (például olyan állomány megnyitása és továbbítása, amelynek semmi köze a programrendszer működéséhez). Ilyen hiba a webszervereknél jól ismert „..” (dotdot) hiba. A program ellenőrzi, hogy a hivatkozott állomány elérési útjának eleje a megengedett könyvtáron belül van-e, azt azonban nem veszi észre, hogy az operációs rendszerek állományrendszereinek sajátosságai miatt használható „..” hivatkozással a támadó az engedélyezett könyvtárból vissza tud lépni, így a támadó olyan állományokhoz férhet hozzá, amelyek nincsenek a konfigurációban megadott könyvtárban. Az a legmulatságosabb, hogy nemcsak a szakirodalom írja le ezt a hibát számtalanszor, hanem a HTTP szabvány is megemlékezik róla, és ennek ellenére rendszeres visszatérő témája a biztonsággal foglalkozó levelező listáknak, mintha a szabvány azt írná, hogy a webszerverek első verziójába kötelező implementálni. Mintha a webszerverek fejlesztői nemigen jutnának el a szabvány olvasásában a „Biztonsági figyelmeztetések” fejezetig. Sajnos. Egy másik tipikus nyelv-független hiba az átmeneti állományok hibás kezelése. Helytelenül kezelt átmeneti állományokkal a fejlesztő szándékai ellenére információ szivároghat ki a rendszerből, vagy szélsőséges esetben akár a rendszer más részeinek működését is befolyásolni, bénítani lehet. Szerencsére csak helyben támadható, tehát csak akkor, ha valaki jogosultságot szerzett a rendszerhez. Ezek a problémák ritkán detektálhatók, orvosolhatók automatikus eszközökkel. Egyes programozási nyelvekhez léteznek bizonyos hibák elkerülésére alkalmas MTAsec_w1
283/517
A hiba lényege, hogy a C nyelvben a hívott függvények lokális adatait a rendszer olyan memóriaterületen tárolja, amely közel van a függvény visszatérési címének tárolt értékéhez. Amennyiben a fejlesztő nem ellenőrzi, hogy egy pufferbe mennyi adatot olvas be, ahogy ez az 1. példa függvényénél látszik, akkor elképzelhető, hogy a gonosz támadó a pufferbe támadó programrészletet (shellcode) tud bejuttatni, és a memória további területének átírása során a visszatérési cím is felülíródhat. Bizonyos C könyvtári függvények (pl. strcpy, sprintf stb.) nem ellenőrzik, hogy mennyi adatot írhatnak egy memóriaterületre, így ezek használata esetén a támadó elégséges méretű kódot és egyéb adatot juttathat be a rendszer sikeres megtámadásához. Ha a visszatérési címet a támadónak sikerül úgy módosítania, hogy az a pufferbe korábban bejuttatott kódra mutasson, akkor máris a hibás programot futtató felhasználó jogosultságaival rendelkezik, és kicsit sarkítva az általa bejuttatott programmal a megtámadott felhasználó nevében azt tesz, amit akar. Ha nem is képes a vezérlést átvenni, még lehetősége lehet a program működésének befolyásolására. Amennyiben a program biztonsága kritikus szempont, akkor jobb ezeknek a függvényeknek a használatát messze elkerülni, ez azonban egy már létező rendszernél nem lehetséges. A lehetséges hibák érzékeltetése kedvéért nézzünk meg egy Perl nyelvű tipikus hibát is. A nyelvre jellemző, hogy szkriptnyelv, továbbá az, hogy ördögi keveréke az egyéb programozási nyelvek hasznosnak ítélt darabjainak. A Perl hírhedt hibája a varázslatos open (magic open). Azért hívják varázslatosnak, mert nagyon sokrétű. Lehetőséget ad fájlok megnyitására (írás, olvasás, átírás), külső program futtatására úgy, hogy a bemenetét a Perl szkript adja vagy úgy, hogy a külső program kimenetét a szkript olvashatja. Azt, hogy éppen mit szeretne csinálni a felhasználó, az open függvény úgy dönti el, hogy a megnyitandó szöveg tartalmaz-e cső jelet (|), és ha igen, akkor hol. Amennyiben a szöveg elején talál egyet, akkor elindítja a megadott külső programot, és visszaad egy csak írható fájlkezelőt (file handle), ha a szöveg végén, akkor hasonlóan, csak a fájlkezelő csak olvasható lesz. Mi lehet ezzel a probléma? Nézzünk egy egyszerű kis Perl függvényt a 2. példában.
MTAsec_w1
284/517
MTA SZTAKI; E4 - 4671/4/2003
Utolsó nyomtatás: 2004. 07. 08.
sub please_hackme_by_wrong_chars { print("Give me the filename with path: "); my $filename = <>; open(FILE, "$filename"); my @contents =
; close(FILE); print(join(", ", @contents), "\n"); return 0; }
Jól látható, hogy a fejlesztő vakon megbízik a felhasználóban, és nem ellenőrzi le, hogy milyen szöveget visz be a $filename változóba. Ha a felhasználó elég szemfüles, akkor rájöhet, hogy tetszőleges állomány tartalmához hozzáférhet a program nevében, hisz a megnyitandó állomány neve nincs ellenőrizve. Kis töprengés után a támadó feltehetőleg arra is rájön, hogy ha állománynév helyett egy parancsot ad meg cső jellel („|”) lezárva, akkor azt a program lefuttatja, és annak kimenetét írja ki. Így a támadó közvetlenül programot tud futtatni az ellenőrizetlen bevitel miatt. Számos ilyen, gyakran elkövetett biztonsági hiba lehetősége rejlik szinte minden programozási nyelvben. Sajnos sok esetben csak a programozók továbbképzése ad teljes körű megoldást ennek a hibaforrásnak a megszűntetésére, itt azonban több esetben, automatikus megoldás is lehetséges. Ilyen esetben sem kilátástalan a helyzet. Meg lehet annyira nehezíteni a támadók dolgát, hogy a rendszer feltörése annyiba kerüljön (idő és pénz), hogy ne érje meg a befektetett munkát. Megakadályozható, hogy a támadó bizalmas adatokhoz férjen hozzá, továbblépjen a rendszerről, vagy egyéb illegális tevékenységre használja azt. Ezekről a megoldási lehetőségekről szól a fejezet további része.
A futási környezet biztonsági kockázatai
Valaha a számítógéprendszerek tervezői nem foglalkoztak eleget a biztonság témájával, így a korai operációs rendszerek egy része szinte semmilyen beépített biztonsági mechanizmussal sem rendelkezett. Ilyen esetben a bizalmas adatok védelme kiegészítő szoftverek nélkül megoldhatatlan volt. Ma a világ eljutott odáig, hogy a számítógépes rendszerek alvilága ráébresztette a rendszerek fejlesztőit, hogy a biztonsággal komolyan foglalkozni kell. A ma fejlesztett modern operációs rendszerek (néhány speciális feladatú, szeparált rendszeren futó kivételtől eltekintve) már mind rendelkeznek több-kevesebb beépített biztonsági funkcióval, amelyek szükség esetén továbbiakkal egészíthetők ki. Ezek a védelmi mechanizmusok a számítógépes biztonság egyre komolyabb elméleti alapjaira és gyakorlati tapasztalatokra épülnek, így általánosságban el lehet mondani, hogy ha helyesen működnek, akkor képesek megvédeni az adatokat és alrendszereket az illetéktelenekkel szemben. Néhány operációs rendszernél a felhasználók kedvéért olyan kompromisszumokat kötöttek a tervezők a biztonság és a kényelem között, ami negatív hatással van az egész Internet biztonságára (pl. folyamatos email vírusok bizonyos levelezőprogramok kényelmi funkciói miatt), de ez az operációs rendszerekre általánosságban nem jellemző. A biztonságos futási környezet védelmi mechanizmusait is emberek fejlesztik, így a hiba lehetősége nem zárható ki. A biztonságos futási környezetet fenyegető elsődleges kockázati tényező a tervezési vagy programozási hibából adódó védelmi rés. Elterjedt rendszerekben ma már elég ritkán lehet igazán nagy tervezési melléfogással találkozni, de ez sem lehetetlen, kisebb rendszereknél pedig feltehetőleg soha nem is fog megszűnni. Itt most nem egy apró MTAsec_w1
Utolsó nyomtatás: 2004. 07. 08.
programozási hiba komoly kihatásaira kell gondolni, hanem arra, hogy ha a rendszer tervezői például hátsó ajtót (backdoor) építenek az azonosítási folyamatba (például egy adatbázis szerverbe...), hogy ha később a felhasználó elfelejtené a jelszavát, akkor is hozzá tudjon férni a rendszerhez. Az ilyen hiba akkor is felbecsülhetetlen kárt okozhat, ha az érintett program „csak” egy szerver vagy kliensprogram, még rosszabb, ha maga az operációs rendszer érintett. Ha egy rendszerben olyan hibát találtak az elmúlt egy évben (az időintervallum szubjektív, van, aki így fogalmazna: ha valaha olyan hibát találtak), amely megkérdőjelezi a tervezők hozzáértését, akkor a rendszer használatát lehetőség szerint ajánlatos elkerülni.
2. példa: Perl nyelvű függvény tipikus hibával
4.9.3
MTA SZTAKI; E4 - 4671/4/2003
285/517
Ahogy korábban láttuk, a programozási hibák is nagyon komoly veszélyt jelenthetnek a rendszer biztonsági funkcióira. Semmi esetre sem szabad azonban ugyanakkora jelentőséget tulajdonítani nekik, mint a komoly tervezési hibáknak. Egy-egy hiba sajnos a legkitűnőbb fejlesztőnél is becsúszhat. Nagyon fontos megkülönböztetni az apró figyelmetlenségből adódó hibákat (például egy véletlen double free) a nyilvánvaló hozzá nem értésből adódó hibáktól (például klasszikus BOF az strcpy használata miatt). Ha egy rendszerben gyakran (évente többször) találnak kisebb-nagyobb biztonsági hibákat, akkor az adott program helyett lehetőleg mást kell választani. Ha azonban csak egyedi, kis jelentőségű hibák merülnek fel, akkor az eszköz még bátran használható. Különösen szerencsés, ha a program forráskódját hozzáértő auditor csapat fésüli át hibák után kutatva (pl. OpenBSD Audit Process). A felesleges funkciók (programok és programrészek) eltávolításával is csökkenthető a kiszolgálóra leselkedő veszély. Nagyon komoly gondokat okozhat a biztonsági funkciók nem megfelelő beállítása. Könnyen belátható, hogy milyen károkkal járhat, ha az állományrendszer jogosultságok nem a szükséges minimális hozzáférést teszik lehetővé a felhasználóknak. Előfordulhat, hogy egy tévesen kiadott parancs mindenki által olvashatóvá tesz egy olyan állományt, amely súlyos következményekkel jár a rendszer egyéb védelmi funkcióira nézve (pl. Unix jellegű rendszereken a /etc/shadow). A rendszer minden védelmi mechanizmusát a lehető legnagyobb alapossággal meg kell ismerni, és körültekintő tervezés után a rendszer biztonsága szempontjából szükségeseket megfelelően bekonfigurálni. Ebben az alfejezetben vázoltuk, hogy milyen jellegű problémákkal kell számolni egy biztonságos hálózati rendszer építésénél. A további alfejezetekben a lehetséges problémákat és védelmi megoldásokat részletesebben ismertetjük.
4.9.4
A biztonságos futási környezet védelmi erejének növelése
Egy szoftverrendszer általános biztonsága (annak beállításaitól eltekintve) a következő módszerekkel javítható: 1. a rendszer részeit képező programokban lévő hibák számának csökkentésével, 2. a nem használt programok számának csökkentésével (különös tekintettel a magasabb jogosultságokkal rendelkező programokra), 3. a rendszer biztonsági funkcióinak szaporításával, javításával. Az első kérdést több irányból lehet megközelíteni. Egy adott feladatra fejlesztett programban a hibák számát a fejlesztés alatt jól definiált módszerekkel csökkenteni lehet, elvileg akár nullára. Erre a problémára nyújt megoldást, például a CC (Common Criteria) [ISO15408], amely ma már nemzetközi szabvány. A CC egy nagyszerűen felépített rendszer, amely kikényszeríti, hogy a fejlesztők minden felmerülő fenyegetettséget felmérjenek, és a fejlesztési terveket ez alapján készítsék el. A gond az, hogy egy program CC szerinti fejlesztése nagyon komoly költségekkel jár, ami természetesen a fejlesztő céget terheli. Ez tehát ellene hat a használatának. Mivel MTAsec_w1
286/517
MTA SZTAKI; E4 - 4671/4/2003
Utolsó nyomtatás: 2004. 07. 08.
MTA SZTAKI; E4 - 4671/4/2003
azonban ma már biztonsági területen gyakran elvárják a felhasználók, hogy a biztonságos szoftverek rendelkezzenek CC minősítéssel, így a fejlesztő cégek a profitorientáltság miatt gyakran kompromisszumot hoznak, és egy gyenge követelményeket kitűző PP (Protection Profile) és/vagy ST (Security Target) alapján tervezik meg a TOE-t (TOE: Target of Evaluation), ezzel elérve az elsődleges célt, az EAL4-es (EAL: Evaluation Assurance Level) CC minősítést, azonban kikerülve a valódi feladatot: egy biztonságos rendszer fejlesztését. Érdemes egy pillantást vetni a CC szerint minősített biztonsági szoftverek ST-jére. Sajnos gyakran az látszik rajtuk, hogy elkészítésüknél nem a biztonság fokozása, csak a papír megszerzése volt a cél.
Utolsó nyomtatás: 2004. 07. 08.
•
Feltételezzük, hogy a program egy független funkcionális egységében 0 .. n hiba van. Elképzelhető az az eset is, hogy egy adott független funkcionalitás javítja ki egy másik rész hibáját, így a program egészének szempontjából „negatív” mennyiségű a benne lévő hibák száma, ez azonban elég ritkán előforduló eset (független funkcionalitást feltételezve), így tekintsünk el tőle.
•
A program bizonyos független funkcionális részleteit eltávolítva a hibák száma vagy állandó marad, vagy csökken.
Mivel a programok biztonságos fejlesztése – ahogy a szoftverek minőségbiztosítása is – ma még gyermekcipőben jár, így a hibák számának csökkentésére más, a gyakorlatban is jól használható megoldást kell találnunk. A megfelelő eljárás kieszeléséhez vizsgáljuk meg tüzetesebben, hogy milyen biztonsági szempontok szerint csoportosított funkcionális részekből áll egy számítógép rendszer szoftver része.
Ezt a kis okoskodást kiterjesztve a teljes szoftverrendszerre (amely független funkcionális egységekből áll), a funkcionális és védelmi szempontból érdektelen funkciókat eltávolítva a rendszer biztonsági szintje vagy nem változik, vagy növekszik. Ezt az alapelvet követve a rendszer hibáinak száma több szinten csökkenthető.
A speciális célrendszerek kivételével egy számítógéprendszer a következő komponensekből épül fel:
4.9.5
•
A használatban lévő perifériák kezelőprogramjai
•
A használatban nem lévő vagy a számítógépből hiányzó perifériák kezelőprogramjai
•
Az operációs rendszer magjának a számítógép működésének és védelmének szempontjából releváns funkciói
•
Az operációs rendszer magjának a számítógép működésének és védelmének szempontjából irreleváns rendszermag funkciók
•
A számítógép funkciójának és védelmének szempontjából fontos programok által használt közös függvénykönyvtárak (shared object, dinamic linkable library)
•
Az előzők által nem használt közös függvénykönyvtárak
•
A számítógép funkcionalitásának és védelmének szempontjából releváns programok és állományok
•
A számítógép funkcionalitásának és védelmének szempontjából irreleváns programok és állományok
A fenti felosztás szándékosan igyekszik rávilágítani, hogy hogyan lehet a hibák számát egy kézenfekvő módszerrel csökkenteni: mindent el kell távolítani, aminek nincs szerepe a rendszer működésében. Ez kézenfekvő, mégis sokan megfeledkeznek róla. A módszer arra a sejtésre alapoz, hogy a rendszer méretének növekedése óhatatlanul a biztonsági hibák számát is növelni fogja, a méret csökkenése tehát csökkent(het)i azt, így a rendszer biztonságát növeli. Ez természetesen nem jelenti azt, hogy itt egy módszer, amivel gondolkodás nélkül lehet egy rendszer biztonságát növelni. Ha azonban okosan el tudjuk távolítani a rendszer működésének és védelmének szempontjából felesleges dolgokat, akkor vagy nem változtatunk a rendszer összes hibáinak a számán, vagy csökkentjük azt. Ezt valahogy így lehetne logikusan levezetni: A sejtés megalapozására állítsunk fel egy modellt, ahol a fejlesztők viszonylag egyenletes teljesítményt nyújtanak. •
MTAsec_w1
Az operációs rendszer és a programok beszerzése
Mivel ma már gyakran előfordul a hamisítás, így erről a biztonsági kockázatról is meg kell emlékeznünk. Amennyiben az operációs rendszert megbízható szállítótól vásároljuk, és az átadás eredeti adattároló médián (pl. floppy, CD) történik, akkor minden rendben. Ha akár az operációs rendszert, akár a későbbi szoftvereket vagy frissítéseket az Interneten keresztül szerezzük meg (töltjük le), akkor nagyon fontos, hogy leellenőrizzük, hogy valóban az eredeti program vagy javítás érkezett-e meg hozzánk. Nem zárható ki a lehetősége annak, hogy DNS mérgezéssel, egy tükör feltörésével vagy más furmányos módon módosított változat jut el hozzánk. Az ellenőrzés lehetőségét természetesen minden tisztességes szoftverszállítónak meg kell adnia. Erre a leggyakrabban a nyilvános kulcsú titkosítási algoritmusokat szokták valamilyen formában használni. Lehetőség van akár magának a programnak, akár csak egy ellenőrző összegeket tartalmazó állománynak az aláírására. Ha a valódi nyilvános kulcsot sikerült megszerezni, akkor leellenőrizhető, hogy a letöltött szoftver valódi-e. Ilyenkor természetesen fontos, hogy a nyilvános kulcs vagy tanúsítvány más forrásból jöjjön, hisz a támadók egyúttal azt is kicserélhették. Ilyen esetben jó szolgálatot tehetnek a nyilvános kulcsszerverek. Ha a letöltött program aláírása hibátlan, akkor a telepítés megkezdhető. Ha hibás, akkor érdemes több ellenőrzés után értesíteni a forrás rendszer adminisztrátorait, hogy a problémát kiderítsék és elhárítsák.
4.9.6
A rendszermag biztonsága
A gyakorlati irodalom általában három részre vágja a szoftverrendszereket: a rendszermagra (kernel), a közös függvénykönyvtárakra és az alkalmazásokra. Biztonsági szempontból a legkritikusabb a rendszermag, mivel annak biztonsági mechanizmusaira építenek a többi alrendszer fejlesztői. Ha a rendszermagban biztonsági hiba van, akkor a teljes rendszer komoly bajban van. Az eszközök kezelését a rendszermag gyakran a hardvergyártó által fejlesztett kiegészítésekkel oldja meg. Ezek a kiegészítések sajnos sokszor kizárólag a funkcionalitást tartják szem előtt, fejlesztésüknél a biztonság általában nem fontos szempont. Ezért jobb csak azokat a külső fejlesztők által készített modulokat használni, amelyek elkerülhetetlenek.
Egy programban egy adott állapotában a funkcionalitás növekedésével a programsorok száma növekszik. 287/517
MTAsec_w1
288/517
MTA SZTAKI; E4 - 4671/4/2003
Utolsó nyomtatás: 2004. 07. 08.
Mivel a méret minimalizálás itt is jó hatással van a biztonságra, így – amennyiben erre az operációs rendszer lehetőséget ad – érdemes a lehető legkevesebb rendszermag funkciót és eszközvezérlőt hagyni a rendszermagban. Amennyiben lehetőség van a rendszer újrafordítására, akkor a felesleges részeket a fordításnál el kell távolítani, ha ez nem lehetséges, akkor a felesleges eszközvezérlő modulok betöltését kell elkerülni. Ha a rendszermag moduláris (tehát eszközvezérlő vagy egyéb funkcionális modulok induláskor vagy futás közben betölthetők), akkor érdemes modulba fordítani a rendszermag azon részeit, amelyek nem folyamatosan használtak vagy csak biztonsági tartalékként kerültek be. Ilyen lehet egy tartalék SCSI vezérlőkártya eszközmeghajtója, vagy a CD meghajtó használatához szükséges rendszermag részek. A modulok használata sokak szerint csökkenti a biztonságot, hisz egy esetleges behatolás esetén a támadó a tevékenységét elrejtő rendszermag modult tölthet be. Ez alacsony képzettségű támadóknál igaz lehet, de mivel modulok feltöltéséhez erős jogosultságokra van szükség, így feltételezhető, hogy a támadó képes hozzáférni a teljes memóriához. Ebben az esetben viszont megfelelő szaktudással felesleges a rendszermag moduláris felépítése, hiszen a szakirodalomban (pl. Phrack, http://www.phrack.org/) részletesen dokumentált, hogy hogyan lehet a futó rendszermagot a memóriában módosítani a támadó céljainak megfelelően. Ez ellen több védekezési technika létezik, ezekről a fejezet későbbi részében lesz szó. A Posix szabvány korábbi biztonsági funkciói ma már nem elégségesek, ezért 1985-ben hozzákezdtek egy szabvány-kiegészítés kidolgozásához. Ez a kiegészítés Posix.1e és a Posix.2c amely a következő biztonsági funkciókkal foglalkozik: Hozzáférés szabály listák – ACL (Access Control Lists), kötelező hozzáférés vezérlés – MAC (Mandatory Access Control), Jogosultsági szintek – Capabilities, biztonsági felülvizsgálat – Security audit, információ címkék – information labeling. Ezek közül a fontosabbakra a fejezet későbbi részében részletesen kitérünk. 4.9.6.1
A verem védelme
Bizonyos rendszerek a tapasztalatok alapján abból a tényből indulnak ki, hogy a programok biztonsági hibákat tartalmaznak, más rendszerek viszont feltételezik, hogy a programok által ígért biztonsági szint és funkciók kifogástalanul működnek. A bizalmatlan rendszerekre jellemző, ahogy arra a fejezet korábbi részében már utaltunk, hogy a tipikus biztonsági hibák által okozott károkat több szinten igyekeznek enyhíteni, lehetőség szerint kiküszöbölni. Ezen problémák egy része rendszermagból orvosolható. Többféle rendszermag szintű védelmi módszer létezik, ezek közül az egyszerűbbek csak megnehezítik a támadó dolgát, mások megfelelő beállítás mellett lehetetlenné teszik a sikeres támadást. A rendszermag szintű védelmi módszerek lényege a – szükség szerint valamilyen szempont szerint kiválogatott – binárisok lehetőségeinek leszűkítése. Ez a szűkítés lehet valamilyen speciális belső működésmódosítás, vonatkozhat állományok vagy hálózat hozzáférésének korlátozására, de speciális esetben lehetőséget adhat akár a rendszerhívások bizonyos részének kiszűrésére is. Az operációs rendszerek fejlesztőinek véleménye megoszlik a magas védelmi szint hivatalos rendszerekbe való integrálásának kérdésében. Van, aki azt az elvet vallja, hogy ha a hibákat demonstráló kis programok (exploit-ok) a hivatalos – kevesebb védelmi mechanizmussal felszerelt – rendszerre készülnek el, akkor még az olyan védelmi kiegészítések is tovább növelik a védelmi szintet, amelyek csak megnehezítik a támadó dolgát. Ez az alapelv a szerényebb tudással rendelkező támadókkal szemben valóban hatásos, mivel sok támadó csak arra képes, hogy a közzétett exploit-okat felhasználja, azok működését azonban nem érti, így az esetleges egyszerűbb védelmi rendszerek elleni módosításokat sem képes megtenni. További tény, hogy a magasabb védelmi szintű rendszerek a plusz funkciók miatt általában lassabbak, mint a védelem nélküliek. Egy másik hozzáállás szerint az operációs rendszer fejlesztőinek mindent meg kell
MTAsec_w1
289/517
MTA SZTAKI; E4 - 4671/4/2003
Utolsó nyomtatás: 2004. 07. 08.
tenniük annak érdekében, hogy a rendszer a lehető legjobb biztonsági funkciókat tartalmazza. Ennek tökéletes példája az OpenBSD rendszer, ahol a fejlesztők a biztonság érdekében még azt a merész lépést is vállalták, hogy a legfontosabb közös függvénykönyvtárakból eltávolították az általuk veszélyesnek ítélt függvényhívásokat. Ezzel feladták a kompatibilitást, hiszen az új rendszerre le sem lehet fordítani egy régi függvénykönyvtárral fejlesztett kódot, cserébe azonban a fejlesztők kénytelenek lettek elkerülni a veszélyes függvényhívásokat, ami a biztonságra előnyösen hatott. Annak érdemes nagyon alaposan utána járni, hogy a használt operációs rendszer milyen biztonsági funkciókat tartalmaz gyárilag, és milyeneket lehet beszerezni hozzá. Általában elmondható, hogy a hivatalos Linux és *BSD rendszermagok védelmi funkcióin kívül nagy mennyiségű kiegészítő érhető el az Interneten, az egyéb rendszerek védelmi funkcióinak bővítése nem gyakori, azok a dokumentációban leírt védelmi mechanizmusokkal rendelkeznek. Az első lehetőség a puffer túlcsordulás hibák kiszűrésére a kódok futásának megakadályozása a verem területén. Erre a problémára több különböző megoldás született, szerencsésebb architektúrákon hardver szintű védelem is lehetséges, ahol nem, ott szoftver megoldások születtek, melyek gyakran nem tökéletesek, és kicsit lassítják a gép működését, de a biztonságért sajnos áldozatot kell hozni. Érdemes használni őket, mert a beállításuk nem igényel komolyabb szakértelmet, az egyszerűbb exploit-okkal támadókkal (pl. férgekkel) szemben mégis megfelelő védelmet nyújtanak. A Windows 2003 rendszer már rendelkezik ezzel a védelmi mechanizmussal. A hivatalos Linux rendszermag nem tartalmaz vermen futtatás elleni védelmet, azonban léteznek az: •
OW (OpenWall, http://www.openwall.com/linux/),
•
PaX (http://pax.grsecurity.net/),
•
exec-shield (http://people.redhat.com/mingo/exec-shield/), és az
•
integrált grsecurity (http://www.grsecurity.net/) kiegészítések,
amelyek más-más megoldásokat adnak a problémára. A hivatalos OpenBSD beépített rendszermag és bináris szintű védelmi mechanizmust tartalmaz (http://kerneltrap.org/node/view/573), de léteznek kiegészítők (pl. StackGhost http://stackghost.cerias.purdue.edu/). 4.9.6.2
Az egyéb speciális kezdeményezések
Külön figyelmet érdemel a Systrace projekt, amely több szabad operációs rendszeren működik (http://www.citi.umich.edu/u/provos/systrace/), és egy nagyon érdekes kiegészítő, betanító eszközt is tartalmaz. A rendszer futása közben az egyes rendszerhívások a grafikus felületen egy ablakban megjelennek, azokkal kapcsolatban működés közben döntéseket lehet hozni. Egy alrendszer kezelőszoftverének néhány futtatása után összeáll egy olyan szabályfájl, amely az adott alrendszer szabályos működése melletti rendszerhívásokat lehetővé teszi, a hibatűrő beállítás jegyében minden mást célszerű tiltani. Ha ezek után egy támadó valamilyen módszerrel olyasmire akarja rákényszeríteni a szerverdémont, ami nem megszokott tőle (például shell-t indít), akkor a systrace alrendszer képes az akciót megakadályozni, ezzel tehát az ismeretlen támadási formák jelentős része megakadályozható. Az állományrendszer szeparációjának egy speciális esetét valósítja meg a SubDomain rendszer (http://www.immunix.org/subdomain.html), amely lehetővé teszi annak beállítását, hogy a programok számára csak az állományrendszer bizonyos részei legyenek láthatóak, azon belül is
MTAsec_w1
290/517