Translated by Lauri Lyytinen (ITKST56 course assignment at JYU.FI)
♪ (36C3 intromusiikki) ♪
Juontaja: Seuraavan esityksen aihe on käytännön välimuistihyökkäykset verkossa
Puhujana on Michael Kurth. Hän tunnisti tämän hyökkäystavan. Hyökkäsytapa on
ensimmäinen laatuaan. Hän on tutkimuksen pääkirjoittaja ja hänen esityksensä
tulee olemaan suurenomoinen! Meille on luvattu huonoja sanaleikkejä kissoista ja
odotan niitä sinulta. Annetaan iso käsi Michael Kurthille!
(taputusta)
Michael: Hei kaikille ja paljon kiitoksia kun pääsitte kuuntelemaan esitystäni.
Nimeni on Michael ja haluan jakaa kansanne tutkimuksemme jonka toteuttamisen
mahdollisti mahtava VUSec grup osana Pro gradu -tutkimustani. Hieman itsetäni.
Suoritin tietotekniikan maisteriopintojani ETH Zürichin ja pystyin tekemään graduni
Amsterdamissa. Nykyään työskentelen turvallisuusanalyytikkona infoGuardilla.
Tässä näette ihmiset, jotka oikeasti mahdollistivat tämän tutkimuksen.
He ovat esimiehiäni ja tutkimus- kollegoitani, jotka tukivat minua
koko ajan ja panostivat aikaa ja vaivaa tutkimukseen. Joten he ovat oikeat
rokkistarat tämän tutkimuksen taustalla. Mutta aloitetaanpa välimuistiyökkäyksistä.
Tapa tunnettin paikallisesti suoritet- tavan koodin hyökkäyksenä. Esimerkiksi
vasemmalla näkyvässä virtuaaliympäristössä on kaksi virtuaalikonetta, jotka jakavat
laitteiston. Eli ne jakavat aikapaikat CPU:n ja välimuistin osalta. Siksi
VM2 käyttävä hyökkääjä voi suorittaa välimuistihyökkäyksen VM1 vastaan. Samoin
myös JavaScriptillä. Haitallinen skripti syötetään selaimelle, joka sitten
suorittaa sen. Koska se jakaa resursseja koneen kanssa se voi myös
hyökätä muihin prosesseihin. Tämä JavaScript tapa luo tunteen
verkon yli tapahtuvasta toiminnasta, eikö? Mutta se vaatii skriptin suorittamisen
koneellasi ollakseen oikeasti onnistunut. Joten halusimme kehittää tätä ja toteuttaa
oikean välimuistihyökkäyksen verkon yli. Tässä perusasetelmassa asiakas käyttää SSH
yhteyttä palvelimeen ja meillä on kolmas, hyökkääjän käyttämä kone. Kuten tulen
tänään todistamaan, voimme murtaa tämän SSH-istunnon luottamuksen käyttämällä
kolmatta konetta ilman haitallista koodia tai ohjelman suorittamista asiakkaalla
tai palvelimella. Lisäksi pavelimen CPU:lla ei ole mitään tekemistä tämän
välimuistihyökkäyksen kanssa. Joten se vain on, eikä huomaa kun siltä vuotaa
salaisuuksia. Katsotaanpa hieman tarkemmin. Tässä meillä on kiva kissa suorittamassa
SSH-istuntoa palvelimen kanssa ja aina, kun kissa painaa nappia yksi paketti
lähtee palvelimelle. Tämä toteutuu aina interaktiivisessa SSH-istunnossa. Kuten
nimikin kertoo, se luo interaktiivisuuden tunteen. Kun kurkkaamme hieman
konepellin alle nähdäksemme mitä palveli- mella tapahtuu, huomamme näiden pakettien
oikeasti aktivoivan viimeisen tason välimuistia (LLC). Tästä lisää hieman
myöhemmin. Nyt hyökkääjä toteuttaa saman- aikaisen välimuistihyökkäyksen LLC:een
vain lähettämällä verkkoliikennepaketteja. Ja näin voimme oikeasti vuotaa
saapumisajat yksittäisistä SSH-paketeista. Nyt varmaan kysyt itseltäsi miten
SSH-pakettien saapumisajat vaikuttavat SSH-istunnon luottamuksellisuuteen. No,
ihmisillä on omintakeisia tapoja kirjoit- taa. Ja tässä näemme esimerkin käyttäjän
kirjoittaessa sanaa "because". Huomamme, että E:n painallus B:n jälkeen on nopeampi
kuin esimerkiksi C A:n jälkeen. Tämä voidaan yleistää ja sitä voidaan käyttää
tilastollisessa analyysissä. Näillä orans- seilla pisteillä, jos saamme mallinnettua
saapumisajat moittettomasti — ja mitä moitteeton tarkoittaa: voimme mallintaa
tarkat ajat, kun käyttäjä näppäili —, voimme toteuttaa tämän tilastollisen
analyysin saapumisien välisistä ajoista. Ja näin voimme vuotaa mitä olit
kirjoittamssa yksityisessä SSH-istunnossa. Kuuolstaa pelottavalta ja futuristiselta,
mutta minä selkeytän asian esityksen aikana. Hyvä! Haluan tuoda yhden seikan
esille heti näin alussa: Kuten on tapana ja kirjoittamien helpottamiseksi
tutkimuskelle annetaan nimi. Ja jos olette seuranneet InfoSecin twitteriä tarkasti,
tunnistatte varmaan mistä olen puhumassa. Koska miedän tapauksessa nimesimme
tutkimuksen NetCAT:ksi. Tämä oli tietenkin sanaleikki. Tässä NetCAT tarkoittaa
"Network Cache Attack" ja se oli tietenkin huumoria, joka voi joskus kostautua.
Ja tässä tapauksessa se kostautui pahasti. Näin saimme aikaan himean twitter-draamaa
viime syyskuussa. Yksi tykätyimmistä twiiteistä tutkimukseen liittyen oli
Jakelta. Nämä esitykset ovat hyviä, koska tällaiset twiitit voidaan henkilöidä ja
kyllä: Minä olen tämä idiootti. Korjataanpa tämä! Intel tunnusti työmme palkitsemalla
ja lisäksi CVE-numerolla, joten nykyään voimme vain käyttää CVE-numeroa. Tai,
jos se on hankalaa, twitter draaman aikana joku lähetti meille tällaisen
kivan pienen vaihtoehtoisen nimen ja lisäsi logon, josta minä jopa pidän.
Sen nimi on NeoCAT. Jokatapuksessa, opimme läksymme nimeämisjutusta.
Siirrytäänpä eteenpäin. Palataan tukimuk- semme varsinaisesti kiinnostavimpiin
asioihin! Nopea hamottelu: Aion ensin kertoa taustoista eli
välimuistihyökkäykset yleisesti. Sitten DDIO ja RDMA, tärketä teknologiat joita
hyväksikäytimme verkon yli tapahtuvassa hyökkäyksessä. Sitten itse hyökkäys ja kuinka
käänteisesti suunnittelimme DDIO:n, päästä-päähän hyökkäys ja pieni demo.
Välimuistihyökkäykset perustuvat mikro- arkkitehtuurin tilan havainnointiin, jonka
pitäisi säilyä salassa ohjelmistolta. Tämä onnistuu pakottamlla jaetut resurssit
vuotamaan tietoa. Analogiana voidaan pitää kassakaapin murtamista stetoskoopilla,
jossa jeattuna resurssina on ilma, joka välittää lukosta tulevat äänet
kun sitä käsitellään. Tämä tapahtuu jokseenkin samalla tavalla
tietokoneissa. Mutta, nyt vain välimuis- tissa. Välimuisti ratkaisee pahatkin
viiveongelmat keskusmistista ladattaessa, eikö? Nämä tekevät karkeasti neljänneksen
kaikista komennoista. Ja välimuistin avulla voimme käyttää uudelleen datan ja käyttää
paikaktietoa ohjelmissa. Moderneissa CPU:issa on yleensä 3-kerroksinen välimusitihierarkia:
L1 on jaettu datan ja komentoväli- muistin kanssa. L2, ja sitten L3, joka
on jaettu ytimien kesken. Jos käsiteltävä data on jo ladattu välimuistiin, se
aiheittaa välimuistiosuman. Jos data pitää ladata keskusmuistista, sitä pidetään
välimuistihutina. Joten, miten saame oikeasti tietää milloin tapahtuu osuma tai
huti? Koska emme voi lukea dataa suoraan välimuistista. Voimme tehdä
tämän esimerkiksi alustamalla ja tutkaamalla. Se on tunnettu teknikka, jota
käytimme verkkoympäsristössä. Haluan paikaisesti kertoa siitä, mitä
tässä tapahtuu. Alustamisen ja tutkaamisen ensimmäisessä vaiheessa hyökkääjä saattaa
välimuistin tunnettuun tilaan. Periaat- teessa alustaa välimuistin. Se täyttää sen
omalla datallaan, jonka jälkeen hyökkääjä odottaa uhrin toimia. Viimeinen vaihe on
tutkaaminen, joka tekee alustamisen uudelleen, mutta tällä kertaa mittaa
kirjautumisajat. Nopeat osumat tar- koittavat ettei välimuistia oltu muutettu
välissä. Ja hutiosumat tuottavat, kuten nyt tiedämme, että uhri
on todella käyttänyt yhtä välimuistiriviä alustuksen ja tutkaamisen välissä.
Mitä voimme siis tehdä näillä osumilla ja hutiosumilla? Voimme analysoida niitä!
Tämä aikatieto kertoo meille paljon uhrin käyttäytymisestä ja ohjelmista.
Perustuen pelkästään osumiin ja huteihin voimme— tai tutkijat pystyivät —vuotamaan
salausavaimistoja, arvaamaan nettisaitteja tai muistin sisältöä. Näin siis SPECTRE:llä
ja MELTDOWN:lla. Katsotaanpa kuinka oike- astaan saamme toteutettua hyökkäyksen
verkon yli! Toinen tärkeistä teknologioista on DDIO. Mutta ensin haluan kertoa DMA:sta
koska se on kuin sen edeltäjä. DMA on periaatteessa teknologia, joka
sallii PCIe-laitteen, kuten esimerkiksi verkkokortin, vaikuttaa suoraan
keskusmuistiin ilman CPU:n keskeytystä. Joten esimerkiksi, jos paketti on
vastaanotettu, PCIe-laite vain laittaa sen keskusmuistiin ja sitten, kun
ohjelma tai sovellus haluaa käyttää dataa, silloin se voi hakea sen keskusmuistista.
Nyt DDIO:n kanssa tämä käy hieman toisella tavalla. DDIO:n avulla PCIe-laite voi
laittaa suoraan dataa viimeisen tasan välimuistiin. Tämä on hienoa, sillä nyt
kun sovellus työskentelee datan kanssa, sen ei tarvitse tehdä kallisarvoista hakua
keksusmuistista vaan se voi suoraan työstää dataa — tai noutaa sen —
LLC:sta. DDIO tarkoittaa "Data Direct I/O Technology" ja se on käytössä
kaikissa Intelin palvelintason prosesso- rissa vuodesta 2012 lähtien. Se on päällä
oletuksena ja läpinäkyvä ajureille ja käyttöjärjestelmille. Arvaan ettei monikaan
edes huomannut, että jokin muuttui kone- pellin alla. Muutos oli kuitenkin hyvin
merkittävä. Miksi oikeastaan DDIO:ta tarvitaan? Se on käytössä suorituskyvyn
takia. Tässä meillä on kiva Intelin tutkimus, joka alimpana osoittaa
NIC:n eriävät ajat. Tässä meillä on ase- telma, jossa on 2, 4, 6 ja 8 NIC:a
Ja meillä on läpimenoajat niille. Kuten voitte nähdä tässä tumman sinisellä
että ilman DDIO:ta se pysäyttää skaalautuvuuden 4 NIC:n jälkeen.
Vaaleansinisellä voimme nähdä että skaalau- tuvuus jatkuu verkkokortteja lisättäessä.
Niinpä DDIO on rakennettu erityisesti verkkosovellusten skaalutuvuudeksi. Toinen
teknologia, jota hyväksikäytämme on RDMA. Se tarkoittaa "Remote Direct Memory Access"
ja se pohjimmiltaan purkaa siirtokerroksen tehtävät piirilevylle.
Se on periaatteessa Kernelin ohitus. Eikä siinä ole CPU käyttöä, jolloin ohjelmisto
voi käyttää etänä muistia ilman, että kuluttaa CPU aikaa palvelimella.
Toin tähän lyhyen kuvauksen RDMA:sta tarkasteltavaksi. Tässä vasemmalla meillä
on toiminnon aloittaja ja oikealla meillä on kohdepalvelin. Muistialue
määräytyy palvelimen avauksessa ja tästä eteen päin ohjelmistot voivat tehdä
tiedonsiirtoa ilman vaikutusta verkko- ohjelmistopinoon. Eli nyt on tehty
TCP/IP pino kokonaisuudessaan. Yksipuoli- sissa RDMA operaatioissa sallitaan myös
toiminnon aloittajan lukea ja kirjoittaa mielivaltaisiin kohtiin määrätyssä tilassa
kohteessa. Lainaan nyt lausuntoa eräältä markkinajohtajalta näistä korkean
suorituskyvyn käärmeistä: "Lisäksi, välimuisti etä-CPU:ssa ei täyty
käytetyllä muistisisällöllä." No, tämä ei pidä enää paikkaansa DDIO:n kohdalta ja
se on juuri se johon hyökkäsimme. Saatat kysyä itseltäsi "missä RDMA:ta käytetään"?
Voin kertoa, että RDMA on yksi niistä teknologioista joista et kuule
kovinkaan usein, mutta ovat oikeasti laa- jassa käytössä datakeskusten backendissa
ja pilvi-infrastruktuurissa. Joten voit saada omat RDMA infastruktuurisi
julkisesta pilvestä, kuten Azurelta, Oraclelta, Huaweilta tai AliBabalta. Myös
mustiprotokollat kuten SMB ja NFS voivat tukea RDMA:ta. Muita ohjelmistoja ovat
Suurtehotietokoneet, Big Data, kone- oppiminen, datakeskukset, pilvi ja muut.
Mennäänpä tarkemmin tutkimuksen sisältöön ja siihen, kuinka hyväksikäytimme näitä
kahta teknologiaa. Tiedämme nyt, että meillä on verkolle avoin jeattu resurssi
DDIO:n ansiosta ja RDMA antaa meillä tar- vittavat luku- ja kirjoitusoikeudet tehdäksemme
välimuistihyökkäyksen verkon yli. Mutta ensin meidän täytyy selkeyttää pari asiaa.
Tietenkin teimme monia kokeita ja testasimme laajasti DDIO porttia
ymmärtääksemme sen salat. Mutta tässä toin mukanani kaksi isoa kysymystä,
joihin meidän on vastattava. Ensinnäkin tietysti, voimmeko erottaa välimuistin
osumat ja hutiosumat vekon yli? Meillä on edelleen verkkoviive ja pakettijonotus
ja niin edelleen. Olisiko todella mahdol- lista saada ajoitus oikein? Se on kuitenkin
ehdoton vaatimus avatakseen sivukanavan. Ja niinpä toinen kysymys on sitten:
Voimmeko oikeasti päästä käsiksi LLC:hen? Tämä liittyy ennemminkin
hyökkäyspintaan kuin itse hyökkäykseen. Niinpä ensimmäiseen kysymykseen voimme
vastata tällä yksinkertaisella kokeella: Vasemmalla meillä on erittäin pieni koodin
palanen. Meillä on ajastettu RDMA luku tiettyyn offsettiin. Sitten kirjoitamme
siihen offsettiin ja luemme sen uudelleen samasta offsetista. Kuten näette, kun
teemme tämän vaikka 50 000 kertaa useisiin eri offsetteihin, voimme selkeästi
erottaa kaksi eri jakaumaa. Sininen vastaa dataa, joka oli
haettu muistista ja oranssi on dataa, joka oli haettu LLC:sta
verkon yli. Voimme myös nähdä verkon vaikutukset toimintaan.
Esimerkiksi, voimem nähdä pitkät hännät, jotka liittyvät joihinkin paketteihin, jotka
hidastuivat verkossa tai olivat jonossa. Sivuhuomautuksena kaikille sivukanava
asiantuntijoille: Tarvitsemme todella kirjoitusoikeuden, koska DDIO luku ei
kohdenna mitään LLC:hen. Periaatteessa tämä on perusta jonka avulla
suoritamme alustamisen ja tutkaamisen verkon yli. Tarvitsemme kuitenkin vielä
todellisen kohteen profiilin rakenta- miseksi. Katsotaanpa millainen
hyökkäyspinta meillä onkaan. Tämä tuokin meidät kysymykseen: voimmeko päästä
täysin LLC:hen sisälle? Epäonneksemme näin ei tapahdu.
DDIO:ssa kohdennukset on rajoitettu kahteen kohtaan. Tässä esimerkissä 20:stä.
Joten noin 10%. Eikä se ole määritetty kohta, jota CPU käyttää. Meillä olisi
pääsy vain 10 prosenttiin CPU:n toimin- noista välimustin viiemisellä tasolla.
Tämäei toiminut kovin hyvinensimmäisenä hyökkäyksenä. Mutta hyvä uutinen on, että
muut PCIe-laitteet—kuten vaikkapa toinen verkkokortti—käyttävät samoja kahta
kahtavälimuistin kohtaa. Ja niinpä meillä on 100% näkyvyys mitä muut PCIe-laitteet
tekevät välimuistissa. Katsotaanpa päästä- päähän hyökkäystä! Kuten jo mainitsin
aiemmin, meillä on asiakkaan ja palvelimen perusjärjestely. Ja meillä on kone,
jota me, hyökkääjänä, hallitsemme. Niinpä asiakas vain lähettää tämän
paketin normaalisti ethernet NIC:nä ja siellä on myös toinen NIC liitettynä
palvelimeen, mikä sallii hyökkääjän suorittaa RDMA-operaatioita. Tiedämme myös
että kaikki paketit... tai kaikki näppäin- painallukset, jotka käyttäjä tekee,
lähtevät yksittäisinä paketteina, jotka aktivoituvat alimman tason välimuistissa
DDIO:n läpi. Mutta miten voimme nyt saada näiden pakettien tuloajat? Koksa
niistä me olemme kiinostuneita! Nyt meidän on katsottava tarkemmin miten
tämä verkkoliikenne pakettien saapuminen oikein toimii. IP pinossa on rengaspuskuri,
joka periaatteessa suorittaa asynkronisia operaatioita
laitteiston- eli NIC:N- ja CPU:n välissä. Kun paketti saapuu, se sijoittaa paketin
rengaspuskurin ensimmäiseen paikkaan. Oikealla näette näkymän hyökkääjän
näkökulmasta, joka voi vain seurata väli- muistin toimintaa. Näemme, että muistirivi
ensimmäisessä paikassa syttyy. Näemme siis toimintaa siinä. Voisi olla myös välimuistin
rivillä 2, tätä... emme tiedä mille riville tämä oikeastaan ilmestyy. Mutta,
tärkeintä on: Mitä tapahtuu toiselle paketille? Sillä toinen
paketti sytyttää myös yhden muistiriveistä, mutta toisen tällä kertaa. Se on oikeastaan
seuraava rivi ensimmäiseen pakettiin ver- rattuna. Jos teemme tämän kolmannelle
ja neljännelle paketille, huomamme, että meillä on kaunis porraskuvio. Nyt voimme
nähdä ennustettavan kaavan, jota voimme hyväksikäyttää saadaksemme tietoa pakettien
saapuessa. Ja tämä vain siksi, että rengaspuskuri on varattu tavalla,
joka ei kiellä itseään, eikö? Se ei kiellä kun toinen paketti saapuu. Se ei
kiellä ensimmäisen paketin välimuistin si- sältöä. Tämä on huikeaa meille hyökkääjänä
koska nyt voimme muodostaa laadukkaan pro- fiilin. Katsotaan elävän elämän esimerkki.
Tässä on välimuistin toiminta kun se vas- taanottaa jatkuvia pingejä. Voitte nähdä
hienon porraskuvion ja nette myös, että rengaspuskuri uudelleenkäyttää paikkoja
koska se on rengas. Nyt on tärkeää tietää, että rengaspuskuri
ei pidä datasisältöä vaan ainoastaan datakuvauksen. Ja se käytetään uudelleen
Epäonneksemme kun käyttäjä näppäilee SSH:lla, kuvio ei ole yhtä kaunis kuin tämä.
Koska muutenhan tämä olisi selvä peli ja voisimme edetä sillä.
Koska käyttäjä kirjoittaa, meillä on enemmän viivettä pakettien välillä.
Yleisesti ottaen emme voi tietää milloin käyttäjä näppäilee, joten täytyy profiloida
jatkuvasti saadaksemme ajoitukset kohdil- leen. Joten, meidän rakennettava hieman
kehittyneempi järjestely. Se on periaat- tessa kaksi-vaiheinen järjestely, joka
koostuu verkkotrackerista, joka vain seuraa useita välimuistirivejä
jatkuvasti. Ja kun se huomaa tietyn muistirivin tulevan
aktiiviseksi, se siirtää sen ikkunan eteenpäin seuraavaan kohtaan, jossa
se arvaa aktivoinnin tapahtuvan. Tämä onnistuu, koska meillä on etu nopeudessa.
Meidän on profiloitava paljon nopeammin kuin SSH-istunnon verkkopaketit saapuvat.
Tässä vasemmalla voitte nähdä kuvituksen siitä, mitä
verkkotrackeri tekee. Se vain profiloi tätä ikkunaa, joka näkyy punaisella.
Jos katsotte tarkasti, voitte nähdä kirkkaamman kohdan keskellä, joka
tarkoittaa saapuneitta verkkopaketteja. Voitte myös nähdä, että siellä on paljon
kohinaa mukana ja siksi emme voi suoraan saada pakettien
saapumisaikoja siitä. Siksi tarvitsemme toisen vaiheen. Offline poimijan.
Offline poimija vastaa todennököisimpien tapahtumien laskennasta, joissa tekijänä
on käyttäjän SSH-paketti. Se käyttää verkkotrackerin keräämää dataa ja
rengaspuskurin ennustettavuutta. Sitten se esittää pakettien
saapumisien väliajat eri sanoille kuten tässä oikealla. Hienoa. Nyt
olemme jälleen tilanteessa, jossa meillä on pelkät saapumisajat muttei sanoja,
joita me tarvitsemme rikkoaksemme SSH-istunnon luottamuksellisuuden.
Kuten totesin aiemmin, käyttäjillä tai oikeastaan ihmisillä on omalaatuinen
kirjoitustapa.