Hyökkääjämalli

Tämä pääluku keskittyy turvallisuuden teknisiin näkökohtiin, mikä tarkoittaa että uhkamalli jättää huomiotta sisäpiiriuhat, ihmisten käyttäytymisen, fyysiset hyökkäykset, projektinhallinnan, yrityksen käytännöt jne. Nekin ovat tärkeitä mutta eivät ole käyttöjärjestelmien hallinnassa. Tarkasteltaviksi jää seuraavanlaisia uhkia ja hyökkäysmenetelmiä, joita jäljempänä käsitellään tarkemmin — DoS-tapauksia lukuun ottamatta (niistä on enemmän verkkoturvan yhteydessä.)

Haitalliset laajennukset
Hyökkääjä onnistuu vakuuttamaan järjestelmän lataamaan haitallisen ohjaimen tai ydinmoduulin (esim. troijalaisena).
Bootkit
Hyökkääjä rämettää käynnistysprosessin saadakseen hallinnan jo ennen kuin käyttöjärjestelmä käynnistyy.
Muistivirheet (ohjelmisto)
Paikalliset ja ajalliset muistivirheet päästävät hyökkääjän (paikallisen tai etäisen) ohjaamaan kontrollivuota tai paljastamaan arkaluonteisia tietoja.
Muistin vioittuminen (laitteisto)
Haavoittuvuudet, kuten DRAM-muistin Rowhammer, päästävät paikallisen tai etähyökkääjän muokkaamaan tietoja, joihin hänellä ei pitäisi olla pääsyä.
Alustamattoman tiedon vuoto
Käyttöjärjestelmä palauttaa käyttäjän ohjelmalle dataa, jota ei ole alustettu oikein ja joka voi sisältää arkaluonteisia tietoja.
Samanaikaisuusvirheet ja kaksoishaku
Esimerkki: käyttöjärjestelmä soveltaa samaksi tarkoitettua dataa käyttäjän prosessista kahdesti, mutta data muuttuu näiden kahden käytön välillä. Esimerkiksi data on tarvittavan tilan koko, ja ensin tehdään tilanvaraus puskurista ja myöhemmin kopiointi puskuriin.
Sivukanavat (laitteisto)
Hyökkääjät voivat mitata jaettujen resurssien, kuten välimuistien ja muistiviittauksia nopeuttavien taulujen, käyttöaikoja havaitakseen, että toinen prosessi on käyttänyt resurssia, jolloin arkaluonteista dataa voi vuotaa.
Sivukanavat (spekulatiivisessa suorituksessa)
Käyttöjärjestelmän keskimääräistä nopeutta voidaan parantaa sopivilla poikkeamilla komentojen normaalista suoritusjärjestyksestä. Jos laskenta osoittautui turhaksi, jäljet siivotaan, mutta suorittimen tilaan voi silti jäädä mitattavissa olevia jälkiä.
Sivukanavat (ohjelmisto)
Esimerkki: kun käyttöjärjestelmät käyttävät muistin tehostusominaisuuksia, kuten kaksoiskappaleiden poistoa, hyökkääjä voi aikamittauksella selvittää, kun häneltä kielletyllä suojausalueella on jokin sisältö sama kuin hänellä.
Resurssien ehdyttäminen (DoS)
Varaamalla resursseja (muisti, suoritin, väylät jne.) hyökkääjä estää muita ohjelmia edistymästä, mikä johtaa palvelunestoon.
Lukkiutumat (DoS)
Hyökkääjä saattaa järjestelmän tilaan, jossa ohjelmiston jotkin osat eivät edisty, esimerkiksi lukkiutumisen vuoksi.

Yksinkertaisin tapa rämettää järjestelmä on ujuttaa haitallinen laajennus käyttöjärjestelmän sisälle. Esimerkiksi monoliittisissa järjestelmissä, kuten Linux ja Windows, tämä voi olla haitallinen ohjain tai ydinmoduuli, jonka käyttäjä on saattanut asentaa Troijan hevosena. Sillä on pääsy kaikkiin etuoikeutettuihin toimintoihin. Säilyttääkseen otteensa järjestelmästä piilossa pysyen ja riippumatta siitä, mitä käyttöjärjestelmä tai hypervisor voi tehdä, hyökkääjä voivat tartuttaa järjestelmän käynnistysprosessin. Tämä voi tapahtua esim. ylikirjoittamalla pääkäynnistystietue, tai UEFI (Unified Extensible Firmware Interface). Haittakoodi saa hallinnan käynnistysprosessissa jokaisen uudelleenkäynnistyksen yhteydessä, jopa ennen kuin käyttöjärjestelmä käynnistyy, jolloin se voi ohittaa kaikki käyttöjärjestelmätason suojaukset.

Troijalaisten käytön lisäksi hyökkääjät usein rikkovat turvallisuuden ilman käyttäjän apua hyödyntämällä haavoittuvuuksia. Heillä on laaja valikoima menetelmiä. Ohjelmiston haavoittuvuuksia, kuten muistivirheitä, voidaan käyttää muuttamaan koodiosoittimia tai dataa käyttöjärjestelmässä, jolloin eheys, luottamuksellisuus tai saatavuus särkyy. Koodiosoittimen muokkauksella hyökkääjä hallitsee, mistä ohjelman suoritus jatkuu rämettynyttä koodiosoitinta käyttävän kutsu-, hyppy- tai paluukäskyn jälkeen. Datan tai dataosoittimien muuttaminen avaa muita mahdollisuuksia, kuten tavallisen prosessin nostamisen root-prosessiksi (jolla on kaikki pääkäyttäjän oikeudet) tai sivutaulujen muokkaamisen, joka päästää prosessin mielivaltaisille muistisivuille. Samoin hyökkääjät voivat käyttää haavoittuvuuksia vuotaakseen tietoja käyttöjärjestelmästä muuttamalla, mitä tai minkä verran paljon dataa systeemikutsu tai verkkopyyntö palauttaa.

Hyökkääjät voivat hyödyntää laitteiston haavoittuvuuksia, kuten monissa DRAM-siruissa olevaa Rowhammer-bugia. Koska muistisirujen bitit on pakattu riveihin hyvin lähelle toisiaan, yhden rivin bitin käyttäminen voi saada viereisen rivin naapurin päästämään pienen määrän varausta kondensaattoriinsa, vaikka bitit ovat eri muistisivuilla. Kun rivillä käydään toistuvasti nopeaan tahtiin (“rivivasaroidaan”), häiriöt kerääntyvät niin, että joissakin tapauksissa viereinen bitti voi kääntyä. Etukäteen ei tiedä, mikä rivin biteistä kääntyy, mutta kun bitti kääntyy, se kääntyy uudelleen, jos koe toistetaan. Jos hyökkääjä onnistuu kääntämään bittejä ytimen muistissa, hänelle mahdollistuvat samanlaiset hyökkäykset kuin ne, jotka perustuvat ohjelmistopohjaiseen muistin rämettämiseen, esimerkiksi sivutaulujen vioittaminen muiden prosessien muistialueille pääsemiseksi.

Toisenlainen luokka hyökkäyksiä ovat samanaikaisuusvirheet ja kaksoishaku, joilla on se yhteinen piirre, että kaksi toisiinsa kytkeytyvää asiaa yhdistyvät väärin. Samanaikaisuusvirheitä (concurrency bug) kutsutaan myös kilpatilanteiksi (race conditions). Ne ovat yleinen ongelma hajautetussa tai verkottuneessa laskennassa. Turvallisuuden kannalta perusesimerkki on TOCTOU-hyökkäys (Time Of Check Time Of Use) jossa hyökkääjä muuttaa jotain attribuuttia vääränlaiseksi ennen käyttöä mutta sen jälkeen kun se on tarkistuksessa hyväksytty. Esimerkiksi haettavan tiedoston nimi voidaan tuossa välissä onnistua muuttamaan (esim. linkityksellä) tavallisesta sellaiseksi, johon pääsy saisi olla vain root-prosessilla (esim. salasanatiedosto). Myös kaksoishaku (double fetch) on tärkeä ongelma käyttöjärjestelmille ja se muistuttaa äskeistä, mutta tässä tapauksessa arvo haetaan kahdesti, ensin alkuperäinen, jonka perusteella esim. tila varataan ja sitten toisen kerran, kun tilaan kirjoitetaan ja sen rajoja vahditaan. Vahtimisen tavoite ei toteudu, jos hyökkääjä pääsee välillä kasvattamaan arvoa. TOCTOU-tapauksessahan ei tapahdu hakua, vaan käyttöjärjestelmä on myöntänyt oikeudet prosessille, joka pääsee käyttämään hyökkääjän muuttamaa arvoa.

Suorien hyökkäysten sijasta voidaan dataa saada vuotamaan epäsuoraan, sivukanavien kautta. Käyttöjärjestelmään liittyy laitteistotasolla monenlaisia sivukanavia. Tarkastellaan ensin välimuistin sivukanavia. Niitäkin on monenlaisia. Yleinen tapaus on, että hyökkääjä täyttää joukon välimuistialueita omalla datallaan tai koodillaan ja sen jälkeen ajoittain käyttää näitä osoitteita. Jos jokin pääsy on huomattavasti hitaampi, hyökkääjä tietää, että joku muu, oletettavasti uhri, on myös käyttänyt dataa/koodia, joka kuuluu samalle alueelle. Tämän paljastavuus on helppo ymmärtää kryptografisessa tapauksessa, jossa uhrikoodi kutsuu koodia eri alueilta salaisuudesta riippuvaisella tavalla. Jos prosessi käsittelee avainta bitti kerrallaan ja kutsuu koodia eri alueelta sen mukaan, onko bitti 0 vai 1, niin hyökkääjä oppii avaimen pian.

Toinen kuuluisa laitteistopohjainen sivukanavahyökkäys hyödyntää spekulatiivista ja epäjärjestyksessä tapahtuvaa toteutusta. Suorituskyvyn vuoksi nykyaikaiset prosessorit voivat suorittaa käskyjä tavanomaisesta kontrollivuosta poiketen. Esimerkiksi odottaessaan ehdollisen toteutushaaran ehdon ratkeamista haaran ennustaja voi ennakoida, että lopputulos on “haara ajetaan” (koska niin tehtiin viimeksikin monta kertaa), ja ryhtyä suorittamaan sen mukaisia käskyjä. Jos ratkaisu osoittautuu vääräksi, CPU tyhjentää kaikki spekulatiivisesti suoritettujen käskyjen tulokset. Mitään dataa ei säily rekistereissä tai muistissa. Mikroarkkitehtuurissa saattaa kuitenkin olla jälkiä suorituksesta. Tämä tarkoittaa muita paikkoja kuin niitä, jotka näkyvät käskyjen omassa rakenteessa. Paikkoja voivat olla haaran ennustajan oma data, välimuistit ja muistiviittauksia nopeuttavat taulut, TLB:t, jotka nekin ovat eräänlaisia välimuisteja (Translation lookaside buffer). Esimerkiksi jos spekulatiivinen käsky käyttäjän koodissa lukee arkaluonteisen ja normaalisti saavuttamattomissa olevan tavun muistista rekisteriin ja käyttää sitä myöhemmin offset-arvona jossain taulukossaan, kyseinen taulukkoelementti on välimuistissa, vaikka offset-arvo tyhjennetäänkin rekisteristä heti, kun CPU huomaa, että sen ei olisi pitänyt käsitellä kyseistä tavua. Hyökkääjä voi ajastaa pääsyn jokaiseen taulukon alkioon ja havaita, löytyykö se huomattavan nopeasti (eli tulee välimuistista). Tämän alkion offset on hyökkääjän tavoittelema tavu. Toisin sanoen, hyökkääjä voi löytää ennakoivassa suorituksessa käytettyä dataa välimuistin sivukanavaa (ajastuksella) hyödyntäen.

Vaikka spekulatiiviseen tai epäjärjestyksessä tapahtuvaan suoritukseen liittyvät haavoittuvuudet kuulostavat hankalilta hyödyntää, ne voivat olla varsin tuhoisia. Voit hakea esimerkkejä hakusanoilla “Foreshadow Intel” ja “Rogue In-Flight Data (RIDL)”. Tällaisten hyökkäysten lieventäminen edellyttää paitsi laitteistomuutoksia, myös käyttöjärjestelmän syvällistä ja usein monimutkaista osallistumista. Käyttöjärjestelmä saattaa esimerkiksi joutua tyhjentämään välimuistit ja puskurit, jotka voivat vuotaa tietoja, tarjota takeita siitä, että tiettyjen toteutushaarojen välillä ei tapahdu spekulointia, tai allokoida toisistaan erillään pidettävät prosessit erillisiin ytimiin jne.

Välimuistien lisäksi laitteistopuolen sivukanavat voivat käyttää kaikenlaisia jaettuja resursseja, mukaan lukien TLB:t, MMU:t ja monet muut komponentit. MMU, Memory management unit on koko keskusmuistia hallinnoiva järjestelmä, jonka osana TLB:tkin ovat. Sivukanavien ei tarvitse liittyä laitteistoon ollenkaan. Esimerkiksi muistin deduplikaatio ja sivuvälimuistit ovat tunnettuja sivukanavien lähteitä käyttöjärjestelmissä. Tarkastellaan esimerkkinä vain edellistä. Deduplikaatio tarkoittaa, että järjestelmä siivoaa toisteisia virtuaalimuistin sivuja. Kun kahdella sivulla on sama sisältö, se säätää molemmat osoittamaan samalle fyysiselle sivulle. Tällä tavalla se käyttää vain yhden fyysisen sivun säilöessään kahta muistisivua. Vasta kun toiselle kirjoitetaan, sen täytyy tehdä kopio. Tuolloin sivulle kirjoittaminen kuitenkin kestää tavallista kauemmin, ja hyökkääjä voi havaita tämän. Tällä tavoin hyökkääjä tietää, että myös jollakin muulla ohjelmalla on sama sisältö kuin se, johon hyökkääjä juuri kirjoitti. Tämä on sivukanava, joka kertoo hyökkääjälle jotain uhrin tiedoista. Tutkijat ovat osoittaneet (2016), että hyökkääjät voivat käyttää näinkin karkeita sivukanavia selvittääkseen jopa erittäin hienojakoisia salaisuuksia. Monissa sivukanavissa ongelmana on ohjelmiston ja laitteiston suojausalueiden välisen eristyksen puute (esim. laitteistolla toteutetun spekulatiivisen suorituksen aikana eristystä ei ehkä ole tai se voi olla liian vähän). On tärkeää ymmärtää, että toimialueen eristysongelmat ulottuvat laitteiston/ohjelmiston käyttöliittymään.

Etenkin luottamuksellisuuden kannalta tietovuodot voivat olla hienovaraisia ja näennäisen vaarattomia ja silti johtaa vakaviin tietoturvaongelmiin. Esimerkiksi olioiden fyysiset tai jopa virtuaaliset osoitteet eivät välttämättä näytä kovin arkaluontoiselta tiedolta, ennen kuin otetaan huomioon koodin uudelleenkäyttö tai Rowhammer-hyökkäykset. Näissä paljastuneita osoitteita käytetään ohjaamaan kontrollivuo tiettyihin osoitteisiin tai kääntämään tiettyjä bittejä.

Hyökkäysten lähteenä voi olla paikallinen koodi, joka toimii natiivisti uhrin koneella käyttäjätilassa, käyttöjärjestelmän laajennus, verkosta haettu ja paikallisesti suoritettu komentosarja (skripti, esim. JavaScript selaimessa), haitalliset oheislaitteet tai jopa etäjärjestelmät, joissa hyökkääjät käynnistävät hyväksikäyttönsä verkon yli. On selvää, että etähyökkäys on vaikeampi toteuttaa kuin paikallinen.

Joissakin tapauksissa hyökkääjäksi pitää mallintaa myös käyttöjärjestelmä itse tai virtuaalikoneen hypervisor. Tämä voi olla tarpeen pilvipohjaisissa järjestelmissä, kun pilvipalvelun tarjoajaan ei luoteta, tai tapauksissa, joissa käyttöjärjestelmä voi olla rämettynyt. Näissä tapauksissa tavoitteeksi tulee suojata arkaluonteinen sovellus (tai sen osa) ytimeltä tai hypervisorilta. Tällöin sovelluksen täytyy mahdollisesti toimia erityisessä laitteistollisesti suojatussa luotetussa ympäristössä tai erillisissä tiloissa.

Hyödyllinen mittari järjestelmän turvallisuuden arvioimiseksi on hyökkäyspinta. Se tarkoittaa kaikkia kohtia, joihin hyökkääjä voi päästä kirjoittamaan tai lukemaan dataa. Esimerkiksi paikallisesti ajettavan alkuperäisen koodin hyökkäyspinta sisältää kaikki järjestelmäkutsut, jotka hyökkääjä voi suorittaa, sekä järjestelmäkutsun argumentit ja paluuarvot sekä kaikki järjestelmäkutsuja toteuttava koodi, jota hyökkääjä voi käyttää. Etähyökkääjien hyökkäyspinta sisältää verkkolaiteohjaimet, osan verkkopinosta ja kaiken verkkopyyntöjä käsittelevän sovelluskoodin. Haitallisten laitteiden hyökkäyspinta voi sisältää kaiken muistin, jota laite voi käyttää DMA:n avulla, tai koodin ja laitteiston toiminnot, joiden kanssa laite voi olla vuorovaikutuksessa. Kuinka paljon koodia hyökkääjälle altistuu, riippuu koodin laadusta. Siinä on paljon vaihtelua, ja korkean turvatarpeen tapauksessa määrä minimoidaan verifioinnilla, jopa formaaleilla menetelmillä.

Luvun aihe liittyy uhkamalliin, joka tarkoittaa sitä, millaisia uhkia otetaan huomioon ja millaisia ei. Millaisia uhkia ei tässä luvussa otetaan huomioon lainkaan?
Millaisia uhkia voidaan joissain tapauksissa jättää huomiotta?
Mikä “juuri” se root oikein on?
Palautusta lähetetään...