< Return to Video

36C3 - SELECT code_execution FROM * USING SQLite;

  • 0:01 - 0:06
    [Translated by Jouko Voutilainen (KYBS2001 course assignment at JYU.FI)]
  • 0:18 - 0:29
    Vasemmallani on Omer Gull, ja hän puhuu meille aiheesta "SELECT code_execution FROM * USING SQLite".
  • 0:29 - 0:33
    Omer, Omer Gull, sinun esityksesi, sinun lavasi, pidä hauskaa!
  • 0:33 - 0:35
    Kiitos. Kiitos.
  • 0:35 - 0:39
    [Yleisö taputtaa]
  • 0:39 - 0:40
    Hei kaikille.
  • 0:40 - 0:46
    Tervetuloa esitykseeni "SELECT code_execution FROM * USING SQLite",
  • 0:46 - 0:52
    jossa saavutamme koodin suorittamisen (code execution) haavoittuvaisia SQLite-tietokantoja käyttäen.
  • 0:52 - 0:56
    Nimeni on Omer Gull. Olen haavoittuvuuksien tutkija Tel Avivista.
  • 0:56 - 1:01
    Olen työskennellyt Check Point Researchissa viimeiset kolme vuotta
  • 1:01 - 1:05
    ja olen äskettäin siirtynyt uuteen startupiin nimeltä Hunters.AI.
  • 1:06 - 1:08
    Agendamme tänään:
  • 1:08 - 1:12
    Aloitamme pienellä motivaatiolla ja taustatarinan kertomisella tästä tutkimuksesta.
  • 1:12 - 1:21
    Sen jälkeen meillä on lyhyt SQLite-johdanto ja tutkimme haitallisten tietokantojen hyökkäyspintaa.
  • 1:21 - 1:29
    Käsittelemme myös aiempaa työtä SQLite-hyödyntämisessä ja mietimme,
  • 1:29 - 1:34
    miten käyttää muistin korruptiohäiriöitä pelkästään SQL:n avulla.
  • 1:34 - 1:41
    Sitten esittelemme oman innovatiivisen tekniikkamme nimeltä "Query Oriented Programming" tai QOP,
  • 1:41 - 1:44
    ja demonstroimme sitä muutamassa esimerkissä.
  • 1:44 - 1:51
    Käärimme asiat yhteen tulevaisuuden mahdollisuuksien ja johtopäätösten kanssa.
  • 1:51 - 1:55
    Motivaatio tälle tutkimukselle on melko ilmeinen.
  • 1:55 - 2:00
    SQLite on yksi eniten käytetyistä ohjelmistoista.
  • 2:00 - 2:05
    Olipa kyse PHP 5:stä, PHP 7:stä, Androidista, iOS:stä,
  • 2:05 - 2:08
    Mac OS:stä, se on nyt sisäänrakennettu Windows 10:een.
  • 2:08 - 2:11
    Sitä on Firefoxissa ja Chromessa.
  • 2:12 - 2:14
    Tämä luettelo voisi jatkua loputtomiin.
  • 2:14 - 2:17
    Kuitenkin SQLite-tietokannan kyselyä pidetään
  • 2:17 - 2:21
    turvallisena. Toivottavasti tämän puheen lopussa tajuat,
  • 2:21 - 2:24
    miksi tämä ei välttämättä ole totta.
  • 2:24 - 2:28
    Kaikki alkoi salasanavarkaista,
  • 2:28 - 2:35
    mikä on melko outoa, ja niitä on paljon, paljon vapaana, mutta tarina on yleensä sama.
  • 2:36 - 2:39
    Ensinnäkin tietokone saa tartunnan.
  • 2:39 - 2:42
    Sitten haittaohjelma kerää tallennettuja käyttäjätunnuksia,
  • 2:42 - 2:45
    sillä niitä on tallennettuna eri asiakasohjelmistoihin.
  • 2:46 - 2:51
    Jotkut näistä asiakasohjelmista tallentavat salaisuutesi SQLite-tietokantoihin.
  • 2:51 - 3:00
    Haittaohjelma lähettää SQLite-tietokantoja C2-palvelimelle, jossa salaisuudet
    poimitaan
  • 3:00 - 3:02
    ja tallennetaan yhteiseen tietokantaan
  • 3:02 - 3:04
    muun saaliin kanssa.
  • 3:05 - 3:12
    Eräänä päivänä kollegani Omri ja minä tutkimme erittäin tunnetun salasanavarkaan vuodattamia lähdetiedostoja.
  • 3:13 - 3:20
    Ajattelimme: "Nämä kaverit vain keräävät tietokantojamme ja parsivat ne omaan back-endiinsä.
  • 3:20 - 3:27
    Voimmeko todella hyödyntää luotettamattoman tietokannan latausta ja kyselyä?"
  • 3:27 - 3:31
    Ja jos voimme, sillä voisi olla paljon suuremmat vaikutukset,
  • 3:31 - 3:41
    koska SQLiteä käytetään lukemattomissa skenaarioissa. Ja niin alkoi tähänastisen elämäni pisin CTF-haaste.
  • 3:42 - 3:50
    SQLite. Toisin kuin useimmat SQL-tietokannat, SQLite:llä ei ole asiakas-palvelinarkkitehtuuria.
  • 3:50 - 3:56
    Sen sijaan se lukee ja kirjoittaa tiedostoja suoraan tiedostojärjestelmään.
  • 3:56 - 4:02
    Joten sinulla on yksi täydellinen tietokanta, jossa on useita taulukoita, indeksejä, laukaisimia ja näkymiä,
  • 4:02 - 4:12
    ja kaikki sisältyvät yhteen tiedostoon. Tutkitaan siis hyökkäyspintaa, jonka potentiaalisesti haitallinen SQLite-tietokanta antaa.
  • 4:12 - 4:17
    Tämä on palanen koodia erittäin tunnetusta salasanavarkaasta,
  • 4:17 - 4:23
    ja meillä on kaksi tärkeintä kiinnostuksen kohdetta: Ensinnäkin meillä on sqlite3_open,
  • 4:23 - 4:27
    jossa potentiaalisesti haitallisen tietokanta ladataan,
  • 4:27 - 4:29
    ja jotain parsimista tapahtuu.
  • 4:29 - 4:34
    Ja ilmeisesti meillä on itse kysely. SELECT-lauseke.
  • 4:34 - 4:37
    Huomaa kuitenkin, että meillä ei ole hallintaa siitä lausekkeesta.
  • 4:37 - 4:40
    Se on kovakoodattu kohteeseemme.
  • 4:40 - 4:43
    Se yrittää poimia salaisuudet tietokannastamme.
  • 4:43 - 4:49
    Mutta me hallitsemme sisältöä, joten meillä voi olla vaikutusta siihen, mitä siellä tapahtuu.
  • 4:50 - 4:53
    Ensimmäinen asia on sqlite3_open,
  • 4:53 - 4:56
    joka on vain joukko asetus- ja kokoonpanokoodia.
  • 4:56 - 5:02
    Seuraavaksi siirrymme suoraviivaiseen otsikkotiedoston parsimiseen,
  • 5:02 - 5:05
    otsikkotiedosto itse ei ole kovin pitkä, vain 100 tavua.
  • 5:05 - 5:09
    Kolmanneksi, se on jo fuzzattu kuoliaaksi AFL:llä.
  • 5:09 - 5:14
    Joten se ei ehkä ole kovin lupaava polku jatkaa.
  • 5:14 - 5:19
    Mutta Sqlite3_query saattaa olla hieman mielenkiintoisempi,
  • 5:19 - 5:27
    koska SQLite:n tekijän mukaan "SELECT-lauseke on SQL-kielen monimutkaisin käsky".
  • 5:28 - 5:34
    Voit tietää, että taustalla SQLite on virtuaalikone.
  • 5:34 - 5:40
    Joten jokainen kysely on ensin käännettävä joksikin tavukoodin muotoon.
  • 5:40 - 5:43
    Tätä kutsutaan myös valmisteluvaiheeksi.
  • 5:43 - 5:47
    Joten sqlite3_prepare kulkee ja laajentaa tuon kyselyn.
  • 5:47 - 5:50
    Esimerkiksi joka kerta, kun valitset asteriskin,
  • 5:50 - 5:54
    se kirjoittaa tämän asteriskin kaikkien sarakkeiden nimiksi.
  • 5:56 - 6:00
    Joten sqlite3LocateTable() varmistaa,
  • 6:00 - 6:06
    että kaikki kyselyssä käytetyt taulut ja sarakkeet todella olemassa ja sijaitsevat muistissa.
  • 6:06 - 6:08
    Mistä se löytää ne?
  • 6:08 - 6:13
    Jokaisella SQLite-tietokannalla on taulu nimeltään sqlite_master,
  • 6:13 - 6:18
    joka määrittelee tietokannan skeeman.
  • 6:18 - 6:20
    Ja tämä on sen rakenne.
  • 6:20 - 6:24
    Joten jokaiselle tietokannan objektille sinulla on merkintä,
  • 6:24 - 6:33
    jossa on sen tyyppi, taulu tai näkymä, sen nimi ja aivan alareunassa jotain, jota kutsutaan SQL:ksi.
  • 6:33 - 6:39
    Ja SQL on itse asiassa DDL, joka kuvaa objektia.
  • 6:39 - 6:46
    DDL tarkoittaa datamäärittelykieltä, ja sitä voidaan verrata C-kielen otsikkotiedostoihin.
  • 6:46 - 6:53
    Ne määrittelevät tietokannan objektien rakenteen, nimet ja tyypit.
  • 6:53 - 6:57
    Lisäksi ne näkyvät selkokielisinä tiedostossa.
  • 6:57 - 7:05
    Annan esimerkin. Avasin SQLite-tulkin, loin taulun ja lisäsin siihen arvoja.
  • 7:05 - 7:10
    Sitten lopetin tulkin ja nyt avaamme tiedoston heksadesimaalimuodossa.
  • 7:10 - 7:18
    Voit nähdä keltaisella korostettuna näkyvän DDL-lauseke, joka on osa pääskeemaa.
  • 7:18 - 7:21
    Alhaalla voit myös nähdä arvot.
  • 7:21 - 7:24
    Palataan kyselyn valmisteluun.
  • 7:24 - 7:33
    Meillä on sqlite3LocateTable, joka yrittää löytää taulun rakenteen, jota haluamme kysellä.
  • 7:33 - 7:39
    Se lukee skeeman sqlite_masterista, jonka juuri kuvailimme.
  • 7:39 - 7:42
    Ja jos se tekee sen ensimmäistä kertaa,
  • 7:42 - 7:47
    sillä on joitakin takaisinkutsufunktioita jokaiselle näistä DDL-lausekkeista.
  • 7:47 - 7:57
    Takaisinkutsufunktio validoi DDL:n ja rakentaa sen jälkeen sisäiset rakenteet kyseisestä objektista.
  • 7:57 - 8:01
    Sitten ajattelimme DDL:n paikkaamista.
  • 8:01 - 8:06
    Entä jos vain korvaamme SQL-kyselyn DDL:ssä?
  • 8:06 - 8:09
    Tämä johtaa kuitenkin pieneen ongelmaan.
  • 8:09 - 8:14
    Tämä on aiemmin mainitsemani takaisinkutsufunktio, ja kuten näet,
  • 8:14 - 8:23
    DDL tarkistetaan ensin aloittavan "create ":lla. Vasta sen jälkeen valmistelu jatkuu.
  • 8:23 - 8:25
    Tämä on ehdottomasti rajoitus, eikö niin?
  • 8:25 - 8:28
    Meidän DDL:n on aloitettava "create ":lla.
  • 8:28 - 8:32
    Mutta tämä jättää jonkin verran tilaa joustavuudelle,
  • 8:32 - 8:37
    sillä SQLite-dokumentaation perusteella monia asioita voidaan luoda.
  • 8:37 - 8:42
    Voimme luoda indeksejä, taulukoita, laukaisimia, näkymiä ja jotain,
  • 8:42 - 8:46
    mitä emme vielä täysin ymmärrä, nimeltä virtuaaliset taulukot.
  • 8:46 - 8:55
    Niinpä ajattelimme "CREATE VIEW":ta, koska näkymä on vain esipakattu SELECT-lauseke,
  • 8:55 - 8:59
    ja näkymiä kysytään hyvin samalla tavalla kuin taulukoita.
  • 8:59 - 9:06
    Joten, taulukosta sarakkeen valitseminen on semanttisesti sama asia kuin sarakkeen valitseminen näkymästä.
  • 9:07 - 9:10
    Sitten, kun ajattelimme kyselyn kaappaamisen käsitettä.
  • 9:10 - 9:15
    Aiomme paikata sqlite_master DDL:n näkymillä taulukoiden sijaan.
  • 9:15 - 9:20
    Nyt paikatut näkymät voivat olla mitä tahansa SELECT-alilauseketta, jonka haluamme.
  • 9:20 - 9:26
    Ja nyt tällä alilausekkeella voin yhtäkkiä käyttää SQLite-tulkintaa.
  • 9:26 - 9:31
    Ja tämä on valtava askel eteenpäin! Muutimme juuri hallitsemattoman kyselyn joksikin,
  • 9:31 - 9:33
    jota voimme jonkin verran hallita.
  • 9:33 - 9:37
    Joten anna minun näyttää sinulle esimerkki kyselyn kaappaamisesta.
  • 9:37 - 9:41
    Sanotaan, että joissakin alkuperäisissä tietokannoissa oli yksi taulu,
  • 9:41 - 9:47
    ja tämä on DDL, joka määrittelee sen. Joten se on nimeltään "dummy" ja sillä on kaksi saraketta.
  • 9:47 - 9:52
    Joten ilmeisesti mikä tahansa kohdesovellus yrittäisi kysyä sitä seuraavasti:
  • 9:52 - 9:56
    Se vain yrittäisi valita nämä sarakkeet taulukosta, eikö niin.
  • 9:56 - 9:59
    Mutta seuraava näkymä voi todella kaapata tämän kyselyn.
  • 9:59 - 10:04
    Luon näkymän, se on juuri samanniminen ja sillä on sama määrä sarakkeita,
  • 10:04 - 10:07
    ja jokainen sarake on nimetty samalla tavalla, ja voit nähdä,
  • 10:07 - 10:10
    että nyt jokainen sarake voi sisältää minkä tahansa alilausekkeen,
  • 10:10 - 10:14
    jonka haluan, korostettuna sinisellä alareunassa.
  • 10:14 - 10:17
    Joten anna minun näyttää sinulle käytännön esimerkki siitä.
  • 10:17 - 10:21
    Tässä olen luonut näkymän nimeltä "dummy" col A ja col B:llä,
  • 10:21 - 10:26
    ja ensimmäinen sarake käyttää sqlite_version()-funktiota, ja se on sisäänrakennettu funktio,
  • 10:26 - 10:29
    joka palauttaa SQLite-version, ilmeisesti.
  • 10:29 - 10:35
    Toinen sarake käyttää SQLite:n omaa toteutusta printf:stä.
  • 10:35 - 10:40
    Juuri näin, niillä on kaikki nämä todella yllättävät ominaisuudet ja kyvyt.
  • 10:40 - 10:44
    Joten katsotaan sitä nyt oletetusti - kohdesivulta.
  • 10:44 - 10:48
    Joten kuka tahansa, joka yrittää valita näistä sarakkeista,
  • 10:48 - 10:51
    suorittaa yhtäkkiä meidän funktioitamme.
  • 10:51 - 10:57
    Vasemmalla voit nähdä SQLite-version, ja oikealla voit nähdä printf:n,
  • 10:57 - 11:02
    joka suoritettiin kohdesivulla. Joten taas tämä on valtava edistysaskel.
  • 11:02 - 11:06
    Me saavutimme juuri jonkin verran kontrollia sen kyselyn yli, eikö niin?
  • 11:06 - 11:10
    Ja kysymys kuuluu, mitä voimme tehdä tällä kontrollilla.
  • 11:10 - 11:13
    Onko SQLite:llä mitään järjestelmäkomentoja?
  • 11:13 - 11:18
    Voimmeko ehkä lukea ja kirjoittaa jotain muita tiedostoja tiedostojärjestelmässä?
  • 11:21 - 11:26
    Joten tämä oli hyvä kohta pysähtyä ja tarkastella jo tehtyä työtä alalla,
  • 11:26 - 11:29
    koska ilmeisesti emme ole ensimmäiset,
  • 11:29 - 11:34
    jotka ovat huomanneet SQLite:n valtavan potentiaalin hyväksikäytössä.
  • 11:34 - 11:38
    Järkevä paikka aloittaa on SQLite-injektio,
  • 11:38 - 11:40
    koska tämä on jonkinlainen vastaava tilanne, eikö niin?
  • 11:40 - 11:45
    Jollakulla haitallisella on jonkinlainen kontrolli SQL-kyselyssä.
  • 11:45 - 11:50
    Joten, on olemassa muutama tunnettu temppu SQL-injektiossa SQLite:llä.
  • 11:50 - 11:54
    Ensimmäisellä on tekemistä toisen tietokannan liittämisen kanssa
  • 11:54 - 11:58
    ja sen jälkeen taulun luomisen ja joitain merkkijonoja sen sisään laittamisen.
  • 11:58 - 12:03
    Ja koska, kuten mainitsin aiemmin, jokainen tietokanta on vain tiedosto,
  • 12:03 - 12:08
    tämä on jonkinlainen mielivaltainen tiedosto, tiedostojärjestelmässä.
  • 12:08 - 12:12
    Kuitenkin meillä on tämä rajoitus, muistattehan, että emme voi liittää,
  • 12:12 - 12:15
    koska DDL:n on aloitettava "CREATE"-sanalla.
  • 12:15 - 12:19
    Toinen hieno temppu on käyttää load extension -funktiota väärin.
  • 12:19 - 12:25
    Ja tässä voit nähdä, kuinka voit mahdollisesti ladata etä-DLL:n.
  • 12:25 - 12:27
    Tässä tapauksessa meterpreter.dll,
  • 12:27 - 12:31
    mutta ilmeisesti tämä erittäin vaarallinen funktio on oletuksena pois käytöstä.
  • 12:31 - 12:37
    Joten se taas ei onnistu. Entä muistin korruptio SQLite:ssä,
  • 12:37 - 12:42
    koska SQLite on todella monimutkainen ja se on kaikki kirjoitettu C:llä.
  • 12:42 - 12:47
    Hänen hämmästyttävässä blogikirjoituksessaan "Virheiden löytäminen SQLite:ssä helposti",
  • 12:47 - 12:50
    Michal Zalewski, AFL:n tekijä, kuvasi,
  • 12:50 - 12:56
    kuinka hän löysi 22 bugia alle 30 minuutissa fuzzingilla
  • 12:56 - 12:58
    Ja itse asiassa, sen jälkeen,
  • 12:58 - 13:02
    kun kyseessä oli versio 3.8.10 vuonna 2015,
  • 13:02 - 13:07
    SQLite alkoi käyttää AFL:ää osana huomattavaa testisarjaa.
  • 13:07 - 13:15
    Nämä muistin korruptiovirheet osoittautuivat kuitenkin erittäin vaikeiksi hyödyntää ilman sopivaa ympäristöä.
  • 13:15 - 13:20
    Turvallisuustutkimusyhteisö löysi kuitenkin pian täydellisen kohteen,
  • 13:20 - 13:22
    ja se oli nimeltään WebSQL.
  • 13:23 - 13:28
    Joten WebSQL on periaatteessa API tietojen tallentamiseen tietokantoihin,
  • 13:28 - 13:34
    ja sitä kysytään JavaScriptistä, ja sillä on SQLite-tausta.
  • 13:34 - 13:37
    Lisäksi se on saatavana Chromessa ja Safarissa.
  • 13:37 - 13:43
    Tässä voit nähdä hyvin yksinkertaisen esimerkin siitä, miten voit käyttää WebSQL:ää JavaScriptistä.
  • 13:47 - 13:50
    Mutta toisin sanoen, mitä täällä luulen, on se,
  • 13:50 - 13:53
    että meillä on joitakin luottamattomia syötteitä SQLite:lle,
  • 13:53 - 13:57
    ja se on saavutettavissa mistä tahansa Internetin verkkosivustosta
  • 13:57 - 14:00
    kahdessa maailman suosituimmassa selaimessa.
  • 14:00 - 14:02
    Ja yhtäkkiä nämä virheet,
  • 14:02 - 14:10
    nämä muistin korruptiot, voidaan nyt hyödyntää JavaScript-hyväksikäytön tiedosta ja mukavuudesta.
  • 14:10 - 14:15
    JavaScript-tulkin hyväksikäyttö, jossa olemme tulleet varsin hyviksi vuosien varrella.
  • 14:15 - 14:22
    Joten WebSQL:stä on julkaistu useita vaikuttavia tutkimuksia,
  • 14:22 - 14:24
    jotka vaihtelevat todella helppoista kohteista,
  • 14:24 - 14:27
    kuten CVE-2015-7036,
  • 14:27 - 14:32
    joka oli luottamattoman osoittimen purku fts3_tokenizer()-funktiossa,
  • 14:32 - 14:34
    monimutkaisempiin hyökkäyksiin,
  • 14:34 - 14:43
    kuten Blackhat 2017:ssä esitelty Chaitin-tiimin löytämä tyyppisekoittumisongelma FTS-optimoinnissa,
  • 14:43 - 14:46
    sekä hiljattain Magellan-bugit, jotka Tencent löysi,
  • 14:46 - 14:51
    jotka löysivät kokonaisluvun ylivuodon FTS-segmentinlukijassa.
  • 14:51 - 14:54
    Ja jos kiinnität nyt edes hieman huomiota,
  • 14:54 - 14:58
    niin näet mielenkiintoisen kaavan nousevan esiin.
  • 14:58 - 15:02
    Kaikki nämä haavoittuvat funktiot alkavat FTS:llä.
  • 15:02 - 15:03
    Joten mikä on FTS?
  • 15:03 - 15:05
    En ole koskaan kuullut siitä.
  • 15:05 - 15:06
    Ja kun etsin sitä Googlesta,
  • 15:06 - 15:08
    se vain hämmensi minua vielä enemmän.
  • 15:10 - 15:11
    Jonkin ajan kuluttua tajusin,
  • 15:11 - 15:19
    että FTS tarkoittaa "täysi tekstihaku" ja se on jotain nimeltään virtuaalinen taulukkomoduuli,
  • 15:19 - 15:24
    joka mahdollistaa todella hienovaraisen tekstin haun dokumenttien joukosta.
  • 15:24 - 15:27
    Tai kuten SQLite-tekijät kuvasivat sitä,
  • 15:27 - 15:30
    se on "kuin Google SQLite-tietokannoillesi".
  • 15:30 - 15:35
    Joten virtuaalitaulukot mahdollistavat joitain todella hienoja toimintoja SQLite:ssa,
  • 15:35 - 15:40
    olipa kyseessä tämä vapaa tekstin haku tai virtuaalitaulukkomoduuli nimeltään RTREE,
  • 15:40 - 15:43
    joka tekee todella fiksua maantieteellistä indeksointia,
  • 15:43 - 15:45
    tai virtuaalitaulukko nimeltään CSV,
  • 15:45 - 15:48
    joka antaa sinun käsitellä tietokantaasi CSV-tiedostona.
  • 15:48 - 15:52
    Ja näitä virtuaalitaulukoita kysytään itse asiassa ihan kuin normaaleja taulukoita.
  • 15:52 - 15:57
    Kuitenkin taustalla tapahtuu joitain pimeitä taikoja.
  • 15:57 - 16:01
    Ja jokaisen kyselyn jälkeen, kutsutaan jonkinlaista takaisinkutsufunktiota,
  • 16:01 - 16:06
    joka toimii niin kutsuttua shadow-taulukkoa vastaan.
  • 16:06 - 16:09
    Varjotaulukot olisi parasta selittää esimerkin avulla.
  • 16:09 - 16:16
    Joten sanotaan, että luon virtuaalitaulukon käyttäen sitä FTS-virtuaalitaulukkomoduulia
  • 16:16 - 16:18
    ja lisään siihen merkkijonon.
  • 16:18 - 16:23
    Ilmeisesti tehokkaan haun sallimiseksi minulla täytyy olla joitain metatietoja, okei?
  • 16:23 - 16:27
    Minun täytyy olla joitain offsetteja tai indeksejä tai merkkejä tai jotain sellaista.
  • 16:27 - 16:29
    Ja ilmeisesti kaikki ne ovat tekstiä, eikö niin?
  • 16:29 - 16:34
    Joten yksi virtuaalitaulukko on itse asiassa raakatekstiä,
  • 16:34 - 16:38
    ja metatiedot tallennetaan kolmen varjoshadow-taulukon joukkoon.
  • 16:38 - 16:43
    Joten raakateksti menisi vt_contentiin ja metatiedot menisivät vt_segmentsiin ja vt_segdiriin.
  • 16:44 - 16:49
    Ajan myötä nämä varjotaulukot ovat liittymäpintoja,
  • 16:49 - 16:52
    jotka siirtävät tietoa toistensa välillä.
  • 16:52 - 16:54
    Koska metatieto tallentaa kaikki nämä osoittimet,
  • 16:54 - 16:57
    sinun on siirrettävä ne toistensa välillä.
  • 16:57 - 16:59
    Ja nämä liittymäpinnat osoittautuivat todella,
  • 16:59 - 17:02
    todella luottavaisiksi luonteeltaan.
  • 17:02 - 17:07
    Ja se tekee niistä todella otollisen maaperän bugin metsästykseen.
  • 17:07 - 17:13
    Näytän teille nyt bugin, jonka löysin RTREE-virtuaalitaulukkomoduulista.
  • 17:15 - 17:19
    RTREE-virtuaalitaulumoduuli on nyt saatavilla MacOS- ja iOS-laitteille,
  • 17:19 - 17:23
    ja se on todella hieno, koska se on nyt myös osa Windows 10:ää.
  • 17:23 - 17:28
    Ja kuten mainitsin, se tekee todella fiksua maantieteellistä indeksointia.
  • 17:28 - 17:34
    DDL:n tulisi olla seuraava. Minkä tahansa RTREE-virtuaalitaulun tulisi alkaa "id":llä,
  • 17:34 - 17:39
    jonka täytyy olla kokonaisluku. Sen jälkeen sinulla on joitakin X- ja Y-koordinaatteja.
  • 17:39 - 17:45
    Joten jokainen RTREE-liitäntä odottaisi "id":n olevan kokonaisluku.
  • 17:45 - 17:49
    Mutta jos luon virtuaalitaulun ja lisään "id":hen jotain,
  • 17:49 - 17:55
    joka ei ole kokonaisluku, ja käytän yhtä näistä RTREE-liitännäisistä,
  • 17:55 - 17:59
    rtreenode, näet alhaalla, että saamme tämän kaatumisen,
  • 17:59 - 18:03
    tämän kekomuistin ulkopuolisen lukemisen.
  • 18:03 - 18:07
    Ja tämä esimerkki on kaatuminen Windows 10:ssä.
  • 18:07 - 18:11
    Joten se on aika hyvä. Olemme havainneet,
  • 18:11 - 18:14
    että virtuaalitaulussa on bugeja.
  • 18:14 - 18:17
    Ja nyt, käyttämällä kyselyn kaappaustekniikkaa,
  • 18:17 - 18:21
    voimme yhtäkkiä laukaista nämä bugit kohteellamme,
  • 18:21 - 18:26
    joka on salasanavaras C2, ja se kaatuu (segfault).
  • 18:26 - 18:30
    Ja tämä on hienoa, mutta varsinaisen ohjauksen saaminen kohteestamme
  • 18:30 - 18:34
    vaatii jonkinlaista skriptausta, eikö niin?
  • 18:34 - 18:37
    Haluamme ohittaa ASLR:n ja tehdä kaikenlaisia hulluja asioita.
  • 18:37 - 18:39
    Meillä ei kuitenkaan ole JavaScriptiä,
  • 18:39 - 18:44
    meillä ei ole JavaScript-taulukoita ja muuttujia ja logiikkalauseita,
  • 18:44 - 18:50
    kuten if ja and silmukoita ja sellaisia. Kuitenkin muistamme jostain kuulleemme,
  • 18:50 - 18:53
    että SQL on Turing-täydellinen.
  • 18:53 - 18:59
    Joten päätimme testata sitä hyökkäysnäkökulmasta
  • 18:59 - 19:04
    ja aloimme luoda omaa primitiivista toivelistaa hyökkäystä varten.
  • 19:04 - 19:06
    Joten jos se voisi luoda täyden hyökkäyksen,
  • 19:06 - 19:10
    jossa hyödynnetään muistin korruptiobugeja pelkästään SQL:llä,
  • 19:10 - 19:12
    mitä kyvykkyyksiä haluamme?
  • 19:12 - 19:15
    Joten ilmeisesti ohittaaksemme ASLR:n ja nämä asiat,
  • 19:15 - 19:17
    tarvitsemme vuodon muistista.
  • 19:17 - 19:19
    Meidän täytyy saada tietovuoto.
  • 19:19 - 19:21
    Jos olet tehnyt pwningia menneisyydessäsi,
  • 19:21 - 19:24
    sinun täytyy olla tuttu todella yleisten tehtävien suhteen,
  • 19:24 - 19:29
    kuten 64-bittisten osoittimen purkamisesta ja joitakin osoitinlaskutoimituksia, eikö niin?
  • 19:29 - 19:33
    Koska meillä oli tietovuoto, muunnamme - luemme tämän osoittimen,
  • 19:33 - 19:35
    ja se on little-endian, joten meidän täytyy kääntää se,
  • 19:35 - 19:39
    ja nyt haluamme laskea, missä on libsqlite-tiedoston perusta,
  • 19:39 - 19:41
    jotta voimme löytää ehkä lisää funktioita.
  • 19:41 - 19:44
    Joten tarvitsemme joitakin osoitinlaskutoimituksia.
  • 19:44 - 19:48
    Luonnollisesti, kun olemme lukeneet osoittimet ja manipuloineet niitä,
  • 19:48 - 19:52
    haluamme pakata ne uudelleen ja kirjoittaa ne jonnekin.
  • 19:52 - 19:56
    Yhden osoittimen kirjoittaminen ei koskaan riitä.
  • 19:56 - 19:59
    Haluamme luoda väärennettyjä objekteja muistissa,
  • 19:59 - 20:05
    monimutkaisempia kuin yksi osoitin. Lopuksi, haluaisimme heap sprayn,
  • 20:05 - 20:07
    koska se voi olla todella hyödyllinen.
  • 20:07 - 20:09
    Joten, kysymys kuuluu,
  • 20:09 - 20:13
    voiko kaikki tämä hyödyntäminen tehdä pelkästään SQL:llä?
  • 20:13 - 20:16
    Vastaus on "kyllä, se on mahdollista".
  • 20:16 - 20:21
    Ja esittelen teille ylpeänä Kysely-orientoitunut ohjelmointi tai QOP.
  • 20:21 - 20:30
    Demonstroidakseni QOP:ia hyväksikäytämme haavoittuvuutta CVE-2015-7036.
  • 20:33 - 20:35
    Ja saatatte kysyä itseltänne:
  • 20:35 - 20:39
    Miten neljä vuotta vanha bugi on edelleen korjaamatta?
  • 20:39 - 20:42
    Ja tämä on hieno asia argumenttiimme.
  • 20:42 - 20:49
    Tämä CVE koettiin vaaralliseksi vain luottamattomien Web-SQL:n suhteen.
  • 20:49 - 20:51
    Se siis kierrettiin oikein.
  • 20:51 - 20:56
    Se on blacklistattu ja SQL on käännetty tietyllä lipulla.
  • 20:56 - 20:59
    Joten selkeästi selaimet eivät enää ole kääntäneet tällä lipulla.
  • 20:59 - 21:01
    Mutta anna minun näyttää sinulle,
  • 21:01 - 21:02
    minkä kanssa nämä liput on käännetty.
  • 21:02 - 21:05
    Joten meillä on PHP 5 ja PHP 7,
  • 21:05 - 21:06
    jotka ovat vastuussa suurimmasta osasta Internetiä,
  • 21:06 - 21:10
    sekä iOS ja MacOS ja todennäköisesti niin monia muita kohteita,
  • 21:10 - 21:14
    joita emme vain ehtineet käydä läpi.
  • 21:14 - 21:17
    Joten selitetään hieman tätä haavoittuvuutta.
  • 21:17 - 21:20
    Olen maininnut, että se on FTS-tokenizerissa.
  • 21:20 - 21:25
    Joten tokenizer on vain joukko sääntöjä dokumenttien
  • 21:25 - 21:27
    tai kyselyjen termeistä erottamiseksi.
  • 21:27 - 21:31
    Ja oletustokenizeri, jota kutsutaan "yksinkertaiseksi",
  • 21:31 - 21:34
    vain jakaa merkkijonot tyhjien merkkien perusteella.
  • 21:34 - 21:39
    Kuitenkin, jos haluat, voit rekisteröidä oman mukautetun tokenizerin.
  • 21:39 - 21:42
    Voit vain siirtää C-funktion ja oikeastaan rekisteröit
  • 21:42 - 21:48
    tämän mukautetun tokenizerin fts3_tokenizer() -funktiolla SQL-kyselyssä.
  • 21:49 - 21:51
    Tässä on jonkin verran asiaa, mutta sanon sen hitaasti.
  • 21:51 - 21:56
    Siirrät riviosoittimen C-funktioon SQL-kyselyssä.
  • 21:56 - 21:57
    Tämä on täysin mielipuolista.
  • 21:57 - 22:01
    Rehellisesti sanottuna, vaikka olen tutkinut tätä jonkin aikaa,
  • 22:01 - 22:05
    en vieläkään ymmärrä, miten käyttää tätä ominaisuutta hyväksi muualla kuin hyökkäyksessäni.
  • 22:06 - 22:13
    [Yleisö taputtaa]
  • 22:16 - 22:20
    fts3_tokenizer() on ylikuormitettu funktio,
  • 22:20 - 22:22
    ja jos kutsut sen yhdellä argumentilla,
  • 22:22 - 22:27
    joka on tokenizerin nimi, saat takaisin kyseisen tokenizerin osoitteen.
  • 22:27 - 22:34
    Teemme sen hieman ihmiselle luettavammaksi käyttämällä heksadesimaalimuunnosta.
  • 22:34 - 22:39
    Voit nyt nähdä, että saimme tietovuodon libsqlite3:een.
  • 22:39 - 22:43
    Koska se on little-endian, meidän on käännettävä se ympäri,
  • 22:43 - 22:45
    mutta tämä on jo melko hienoa.
  • 22:45 - 22:48
    Jos kutsut fts3_tokenizer():ia kahdella argumentilla,
  • 22:48 - 22:55
    joista ensimmäinen on tokenizerin nimi ja toinen on raakaosoitin, ja tämä on täysin mielipuolista..
  • 22:55 - 22:58
    voit kirjoittaa kyseisen tokenizerin osoitteen uudelleen.
  • 22:58 - 23:02
    Joten aina kun joku yrittää käyttää virtuaalitaulua
  • 23:02 - 23:08
    ja se instantisoi oletusarvoisen tokenizerin, se kaatuu.
  • 23:08 - 23:11
    Tämä on melko hämmästyttävää.
  • 23:11 - 23:14
    Lyhyt kertaus: olemme vahvistaneet,
  • 23:14 - 23:18
    että SQLite on ihana yhden maalin kohde monille, eikö niin?
  • 23:18 - 23:20
    Se on kaikkialla.
  • 23:20 - 23:24
    Ja se on monimutkainen C:llä kirjoitettu kone.
  • 23:24 - 23:27
    Nyt, kyselyn kaappaamisen avulla voimme alkaa laukaista näitä bugeja
  • 23:27 - 23:35
    ja tavoitella täydellistä hyökkäystä käyttämällä SQL-kyselyjä.
  • 23:36 - 23:41
    Hyökkäysstrategiamme on seuraava: vuodatamme joitakin osoittimia
  • 23:41 - 23:45
    ja sitten laskemme joitakin funktio-osoitteita.
  • 23:45 - 23:48
    Luomme sitten väärennetyn tokenizer-objektin,
  • 23:48 - 23:50
    jolla on jokin osoitin system()-funktioon.
  • 23:50 - 23:55
    Ylikirjoitamme oletusarvoisen tokenizerin ja laukaisemme pahantahtoisen tokenizerimme.
  • 23:55 - 24:03
    Sitten tapahtuu jotain, ja lopussa meidän pitäisi pystyä hyötymään jotenkin, eikö niin?
  • 24:03 - 24:07
    Aloittaen muistivuodosta ja tietovuodosta libsqliteen.
  • 24:07 - 24:10
    Tiedät jo, miten tehdään, eikö niin?
  • 24:10 - 24:16
    Näimme fts3_tokenizer():in, mutta meillä on vielä pieni ongelma little-endian osoittimen kanssa.
  • 24:16 - 24:18
    Joten meidän on käännettävä se ympäri.
  • 24:18 - 24:21
    Varmaan voimme käyttää SUBSTR-funktiota
  • 24:21 - 24:25
    ja lukea tämän osoittimen kaksi merkkiä kerrallaan käänteisessä järjestyksessä
  • 24:25 - 24:29
    ja yhdistää kaiken koko osoittimen läpi.
  • 24:29 - 24:33
    Joten saamme SELECT-kyselyn, joka näyttää seuraavalta,
  • 24:33 - 24:35
    mutta nyt meillä on osoitin.
  • 24:35 - 24:37
    Tämä on hienoa.
  • 24:37 - 24:39
    Entä tietovuoto kekomuistiin?
  • 24:39 - 24:41
    Haluamme tietää, missä keko sijaitsee.
  • 24:41 - 24:43
    Aloitetaanpa tekemään temppua,
  • 24:43 - 24:47
    joka on melko samankaltainen kuin RTREE-bugi, jonka olemme löytäneet.
  • 24:47 - 24:51
    Joten jälleen kerran, aiomme sekoittaa joitakin shadow-taulukkojen käyttöliittymiä.
  • 24:51 - 24:56
    Luomme siis virtuaalitaulukon ja lisäämme siihen joitakin arvoja.
  • 24:56 - 25:00
    Nyt aiomme hämmentää match-käyttöliittymää.
  • 25:00 - 25:03
    Match-käyttöliittymä tekee monia asioita,
  • 25:03 - 25:09
    mutta taustalla se vain palvelee osoittimen muistissa, jossa tekstin sijainti sijaitsee.
  • 25:09 - 25:13
    Se on tätä metadataa, hienoja asioita, joita virtuaalitaululla on.
  • 25:13 - 25:15
    Joten aiomme hämmentää sitä ja sen sijaan,
  • 25:15 - 25:18
    että siirtäisimme sen toiselle virtuaalitaulun käyttöliittymälle,
  • 25:18 - 25:21
    siirrämme sen yksinkertaisesti heksadekooderille,
  • 25:21 - 25:24
    joten puramme tämän raakanosoittimen.
  • 25:24 - 25:26
    Ja voit nähdä, jälleen kerran little-endianin,
  • 25:26 - 25:28
    mutta nyt meillä on linkki kekoon.
  • 25:29 - 25:31
    Voimme yliviivata sen listalta.
  • 25:31 - 25:34
    Ja ennen kuin siirrymme eteenpäin tämän osoittimen purkamiseen,
  • 25:34 - 25:37
    meillä on hyvin perustavanlaatuinen ongelma.
  • 25:37 - 25:40
    Kuinka edes tallennamme näitä asioita?
  • 25:40 - 25:45
    Koska toisin kuin selaimen WebSQL:ssä, meillä ei ole JavaScript-muuttujia tai taulukoita,
  • 25:45 - 25:47
    joita voimme käyttää ja hyväksikäyttää myöhemmin,
  • 25:47 - 25:50
    mutta meidän on luotava joitakin monimutkaisia logiikoita, eikö niin?
  • 25:50 - 25:55
    Meidän on laskettava funktio-osoite ja luotava asioita muistissa, mutta kuinka voimme tehdä sen?
  • 25:55 - 25:58
    Ilmeisesti SQLite:llä, kun haluat tallentaa joitakin arvoja,
  • 25:58 - 26:05
    sinun on oltava insert-lausekkeita, mutta voimme vain luoda tauluja, näkymiä, indeksejä ja laukaisimia.
  • 26:06 - 26:12
    Sitten ajattelimme ketjuttaa tämän näkymän yhteen käyttääksemme niitä jonkinlaisena pseudomuuttujana.
  • 26:12 - 26:14
    Joten jälleen kerran, anna minun näyttää sinulle esimerkki.
  • 26:14 - 26:18
    Tässä luon näkymän, jota kutsutaan "little-endian leak", okei?
  • 26:18 - 26:22
    Ja taas hyväksikäytän fts3_tokenizer() -funktiota.
  • 26:22 - 26:25
    Nyt luon toisen näkymän sen päälle, ja tätä kutsutaan "leakiksi"
  • 26:25 - 26:28
    ja kääntyy käyttämällä SUBSTR-temppua,
  • 26:28 - 26:29
    jonka tiedät jo aikaisemmasta.
  • 26:29 - 26:33
    Mutta huomaa, kuinka viittasin ensimmäiseen näkymään, viittasin "little-endian leak":iin.
  • 26:33 - 26:40
    Joten teen sen koko osoittimen läpi, ja lopulta minulla on pseudomuuttuja nimeltä "leak".
  • 26:40 - 26:45
    Kun valitsen sen, saan odotetun tuloksen.
  • 26:45 - 26:48
    Joten nyt voimme todella edetä.
  • 26:48 - 26:52
    Nyt voimme aloittaa monimutkaisempien asioiden rakentamisen tämän logiikan perusteella.
  • 26:52 - 26:55
    Ja nyt voimme siirtyä purkamaan osoittimia.
  • 26:55 - 27:01
    Haluamme esimerkiksi laskea kuvan perustan tai löytää keon alun.
  • 27:01 - 27:06
    Joten ensinnäkin haluamme muuntaa osoittimemme kokonaisluvuiksi.
  • 27:06 - 27:12
    Joten jälleen kerran aloitamme lukemalla nämä osoittimet yhden merkin kerrallaan
  • 27:12 - 27:15
    ja käänteisessä järjestyksessä käyttäen SUBSTRia.
  • 27:15 - 27:21
    Ja saadaksemme heksadesimaalimerkin arvon, käytämme INSTR-funktiota,
  • 27:21 - 27:27
    joka on kuin strchar, ja käyttämällä seuraavaa merkkijonoa saamme heksadesimaalimerkin arvon.
  • 27:27 - 27:32
    Koska se on yksipohjainen, on oikealla miinus yksi.
  • 27:32 - 27:37
    Sitten minun täytyy tehdä hieman siirtämistä, kuten jotain pimeää magiaa,
  • 27:37 - 27:42
    ja sitten yhdistän kaiken yhteen osoittimessa.
  • 27:42 - 27:45
    Joten tulos on tämä hirviömäinen kysely.
  • 27:45 - 27:53
    Mutta kun kaikki tämä on tehty, saan kokonaisluvun, joka on purkamaton versio alkuperäisestä vuodosta.
  • 27:53 - 27:57
    Joten onnistuin purkamaan tämän osoittimen,
  • 27:57 - 28:01
    ja meillä on nyt käsillä kokonaislukuja, joten voimme yliviivata sen listalta myös.
  • 28:01 - 28:04
    Tiedämme nyt, miten muuntaa osoittimet kokonaisluvuiksi.
  • 28:04 - 28:11
    Nyt osoitinlaskentaa, koska haluamme saada joitain toimintojen osoitteita muistissa,
  • 28:11 - 28:14
    ja itse asiassa kokonaislukuilla tämä on erittäin yksinkertaista.
  • 28:14 - 28:18
    Kaikki mitä meidän tarvitsee tehdä on käyttää joitakin alikyselyjä.
  • 28:18 - 28:21
    Vasemmalla voit nähdä, että viittaan nyt pseudomuuttujiin,
  • 28:21 - 28:24
    joita meillä on nyt, vuotanut tieto,
  • 28:24 - 28:30
    ja oikealla voin joko vähentää hölmön vakion kuten tein täällä,
  • 28:30 - 28:38
    tai voin todella käyttää toista pseudomuuttujaa tehdäkseni sen hieman dynaamisemmaksi ja luotettavammaksi.
  • 28:38 - 28:45
    Lopulta, mihin päädyin, on libsqlite-perusta kokonaislukumuodossa.
  • 28:45 - 28:50
    Joten, olemme lukeneet joitakin osoittimia ja manipuloineet niitä.
  • 28:50 - 28:56
    Nyt on hyvä aika kirjoittaa ne takaisin. Ja tietysti olemme tottuneet siihen,
  • 28:56 - 28:59
    että "char" on täysin päinvastainen kuin "hex".
  • 28:59 - 29:04
    Ja voit nähdä, että se toimii melko hyvin useimmilla arvoilla,
  • 29:04 - 29:09
    mutta suuremmat kokonaisluvut todella käännettiin niiden kahden tavun koodipisteisiin.
  • 29:09 - 29:12
    Joten tämä oli suuri este meille.
  • 29:15 - 29:20
    Joten, kun olimme viettäneet dokumentaation parissa jonkin aikaa,
  • 29:20 - 29:23
    yhtäkkiä meille valkeni kummallinen oivallus.
  • 29:23 - 29:26
    Tajusimme, että hyökkäyksemme on itse asiassa tietokanta.
  • 29:26 - 29:29
    Ja jos haluan minkä tahansa muunnoksen tapahtuvan,
  • 29:29 - 29:34
    voin yksinkertaisesti luoda etukäteen tämän avain-arvo-kartan ja yksinkertaisesti
  • 29:34 - 29:41
    kysyä sitä käännettäväksi millä tahansa arvolla toiseksi arvoksi alikyselyillä.
  • 29:41 - 29:43
    Tämä on se Python-funktio, jonka olen käyttänyt,
  • 29:43 - 29:46
    ja voit nähdä, että siinä on hyvin yksinkertainen for-silmukka,
  • 29:46 - 29:50
    joka menee 0:sta FF:ään ja vain lisää arvoja tauluun,
  • 29:50 - 29:52
    jota kutsutaan "hex_map", sen avain-kartan arvoilla.
  • 29:52 - 29:59
    Ja nyt muunnoksemme käyttävät alikyselyjä. Joten anna minun jälleen näyttää esimerkki.
  • 30:00 - 30:02
    Voit nähdä, että valitsen "val" heksakartasta,
  • 30:02 - 30:07
    tästä avain-arvo-kartasta, jossa "int" on yhtä suuri kuin,
  • 30:07 - 30:11
    ja sitten teen hieman enemmän kaikenlaista, kuten siirtämistä ja modulo pimeää magiaa,
  • 30:11 - 30:17
    mutta lopulta päädyin pakattuun versioon libsqlite-tietokannasta.
  • 30:17 - 30:23
    Nyt meillä on pakattu little-endian osoitin, joten sen voi ruksata listalta pois.
  • 30:25 - 30:30
    Kuten mainitsin, yksittäisen osoittimen kirjoittaminen on ehdottomasti hyödyllistä,
  • 30:30 - 30:31
    mutta se ei riitä.
  • 30:31 - 30:34
    Haluamme väärentää kokonaisia objekteja, eikö niin?
  • 30:34 - 30:38
    Kaikki coolit tyypit tekevät niin, ja se on melko voimakas primitiivi.
  • 30:38 - 30:41
    Ja jos muistat, meidän on tehtävä se,
  • 30:41 - 30:46
    koska fts3_tokenizer() edellyttää meidän määrittävän tokenizer moduulin.
  • 30:46 - 30:51
    No, mikä on tokenizer-moduuli? Miltä se näyttää? Joten tämä on sen rakenteen alku,
  • 30:51 - 30:54
    ja siinä on "iVersion", joka on kokonaisluku alussa,
  • 30:54 - 30:56
    meillä ei ole oikeastaan mitään tekemistä sen kanssa,
  • 30:56 - 30:59
    mutta sen jälkeen on kolme funktio-osoitinta.
  • 31:00 - 31:06
    Meillä on "xCreate", joka on jakelijan rakentaja, ja "xDestroy", joka on purkaja.
  • 31:06 - 31:12
    Meidän on tehtävä molemmat kelvollisiksi, jotta sovellus ei kaadu hyökätessämme.
  • 31:12 - 31:15
    Kolmas funktio-osoitin on todella mielenkiintoinen, koska tämä on se,
  • 31:15 - 31:17
    joka todella jakaa merkkijonon osiksi.
  • 31:17 - 31:21
    Joten meillä on funktio-osoitin, johon ohjataan hallittavissa oleva merkkijono.
  • 31:21 - 31:26
    Tämä olisi täydellinen paikka laittaa system-vimpaimemme, eikö niin.
  • 31:27 - 31:32
    Tähän mennessä olen käyttänyt melkoisesti SQL-osaamistani, eikö niin?
  • 31:32 - 31:37
    Mutta minulla on vielä yksi temppu hihassani ja se on JOIN-kyselyt, eikö niin?
  • 31:37 - 31:41
    Koska olen oppinut siitä menneessä ajassa.
  • 31:41 - 31:44
    Joten nyt luomme väärennetyn tokenizer-näkymän
  • 31:44 - 31:49
    ja yhdistämme joukon "A"-kirjaimia ja sitten käyttäen JOIN-kyselyä
  • 31:49 - 31:54
    ja yhdistämme sen osoittimeen simple_create ja osoittimeen simple_destroy
  • 31:54 - 31:59
    ja sitten joukon "B":itä. Nyt tarkistetaan se alhaisen tason debuggerissa
  • 31:59 - 32:03
    ja voit itse asiassa nähdä, että jossain muistipaikassa meillä on joukko "A":ita,
  • 32:03 - 32:06
    jonka perässä on osoitin simple_createen,
  • 32:06 - 32:10
    jonka perässä on osoitin simple_destroyiin ja sitten joukko "B":iä.
  • 32:11 - 32:16
    Joten olemme melkein valmiit. Mutta tarvitsemme vielä yhden primitiivin tätä hyödyntääksemme.
  • 32:16 - 32:21
    Ja tämä johtuu siitä, että meillä on jo haitallinen tokenizerimme,
  • 32:21 - 32:26
    ja tiedämme, missä keko sijaitsee, mutta emme ole aivan varmoja, missä tokenizerimme sijaitsee.
  • 32:26 - 32:30
    Tämä on hieno aika heap sprayinglle, eikö olekin.
  • 32:30 - 32:35
    Ja ihanteellisesti tämä olisi jonkin toistuva muoto meidän fakeobj -primitiivistämme.
  • 32:35 - 32:44
    Olemme siis ajatelleet toistoa, mutta valitettavasti SQLite ei ole toteuttanut sitä kuten mySQL.
  • 32:44 - 32:46
    Joten kuten kuka tahansa muukin,
  • 32:46 - 32:50
    menimme Stack Overflowiin ja löysimme tämän todella elegantin ratkaisun.
  • 32:50 - 32:58
    Käytämme siis zeroblob-funktiota, joka yksinkertaisesti palauttaa nollista koostuvan läjän.
  • 32:58 - 33:03
    Sitten korvaamme jokaisen nollan väärennetyllä tokenisaattorillamme.
  • 33:03 - 33:06
    Ja teemme sen kymmenentuhatta kertaa, kuten näette yllä.
  • 33:06 - 33:09
    Uudelleen, varmistaaksemme sen debuggerilla,
  • 33:09 - 33:12
    näet paljon "A":ita ja se on vähän vaikea nähdä,
  • 33:12 - 33:16
    koska nämä ovat todella huonoja värejä, mutta meillä on myös täydellinen johdonmukaisuus,
  • 33:16 - 33:21
    koska nämä rakenteet toistuvat joka 20. heksadesimaalitavussa.
  • 33:21 - 33:26
    Joten loimme melko hyvät heap-spraying -kyvyt,
  • 33:27 - 33:31
    ja olemme valmiit exploitti -toiveluettelomme kanssa,
  • 33:31 - 33:34
    joten voimme palata alkuperäiseen kohteeseemme.
  • 33:34 - 33:40
    Tämä on koodisegmentti erittäin tunnetusta salasanavarkaasta,
  • 33:40 - 33:43
    ja lopussa voit nähdä, että se yrittää valita
  • 33:43 - 33:50
    ja poimia salaisuuksia valitsemalla sarakkeen nimeltä "BodyRich" taulusta nimeltä "Notes".
  • 33:50 - 33:54
    Joten valmistelemme hänelle pienen yllätyksen, okei?
  • 33:54 - 33:57
    Luomme näkymän, jota kutsutaan nimellä "Notes".
  • 33:57 - 34:01
    Ja siinä on kolme alikyselyä sarakkeessa nimeltä "BodyRich".
  • 34:01 - 34:05
    Jokainen näistä alikyselyistä on itse asiassa QOP-ketju.
  • 34:05 - 34:09
    Jos muistat hyökkäyssuunnitelmani,
  • 34:09 - 34:14
    aloitamme heap-spray sitten korvaamme oletustokenisaattorin
  • 34:14 - 34:17
    ja laukaisemme lopuksi haitallisen tokenisaattorin.
  • 34:17 - 34:20
    Ja sinä saatat kysyä itseltäsi, mikä on heap_spray?
  • 34:20 - 34:27
    Ilmeisesti heap_spray on QOP-ketju, joka hyödyntää heap-spraying -kykyjämme, eikö niin.
  • 34:27 - 34:33
    Me ruiskutamme kymmenentuhatta esimerkkiä väärennetystä tokenizeristamme,
  • 34:33 - 34:40
    joka on JOIN-kysely joukosta "A":ita ja joitain osoittimia, kuten p64_simple_create.
  • 34:40 - 34:48
    Ja bileet jatkuvat, koska p64_simple_create on itse asiassa peräisin u64_simple_createsta, oikein,
  • 34:48 - 34:51
    käyttäen osoittimenpakkauskykyjämme.
  • 34:51 - 34:55
    Ja tämä on kuin maatuska-nukke,
  • 34:55 - 35:02
    koska sinulla on u64_simple_create, joka on peräisin libsqlite_basesta plus joistakin vakioista.
  • 35:02 - 35:07
    Ja tämä menee takaisin purkamattomaan vuotoversioon,
  • 35:07 - 35:08
    miinus joitain vakioita.
  • 35:08 - 35:13
    Joten jälleen kerran käytämme osoitinlaskentakykyjämme.
  • 35:13 - 35:18
    Voimme jatkaa u64_leak:illa, joka on peräisin lähes alkuperäisestä vuodosta.
  • 35:18 - 35:22
    Ja me päätämme näyttämällä,
  • 35:22 - 35:28
    kuinka vuoto on itse asiassa peräisin alkuperäisestä haavoittuvuudesta käyttäen fts3_tokenizeria.
  • 35:28 - 35:33
    Ja tämä oli vain yksi kolmesta QOP-ketjusta, joita käytimme tässä hyökkäyksessä.
  • 35:33 - 35:39
    Ja tällä hetkellä joka kerta, kun kuvaan tätä hyökkäystä, tämä on miltä minä varmasti näytän.
  • 35:39 - 35:41
    Ja ollakseni rehellinen, tämä on juurikin mitä tunnen.
  • 35:41 - 35:45
    Mutta onneksi teidän ei tarvitse näyttää tai tuntea samalta kuin minä,
  • 35:45 - 35:50
    koska loimme QOP.py:n, ja se on saatavilla Checkpoint Researchin GitHubissa.
  • 35:50 - 35:57
    Ja yhtäkkiä nämä hullun pitkät ketjut voidaan luoda neljällä helpolla Python-rivillä.
  • 35:57 - 36:00
    Ja tuntuu pwntoolsilta, jos olet perehtynyt siihen,
  • 36:00 - 36:05
    joten voit mennä eteenpäin ja leikkiä sillä etkä näytä hullulta lavalla.
  • 36:05 - 36:08
    Siirrymme ensimmäiseen demoomme.
  • 36:08 - 36:13
    Ownaamme salasanan varastavaa taustapalvelinta, joka toimii uusimmalla PHP 7:llä.
  • 36:13 - 36:17
    Tietenkin tämä on malli, jonka loimme vuotaneista lähteistä,
  • 36:17 - 36:20
    ja näet kaikki tartunnan saaneet uhrit
  • 36:25 - 36:25
    Coolia
  • 36:25 - 36:28
    Nyt yritämme mennä web-shelliin, p.php:hen.
  • 36:29 - 36:32
    Tietenkään sitä ei vielä ole olemassa, saamme 404.
  • 36:32 - 36:35
    Siirrymme hyökkääjän tietokoneelle.
  • 36:35 - 36:38
    Näemme täällä kaksi skriptiä.
  • 36:38 - 36:44
    Ensin käytämme QOP.py:ä, joka luo ilkeämielisen tietokannan.
  • 36:44 - 36:47
    Katsotaanpa, tietokanta luotiin.
  • 36:47 - 36:49
    Nyt emuloimme saastuttamisen.
  • 36:49 - 36:53
    Aloitamme lähettämällä ilkeämielisen tietokantamme C2-palvelimelle
  • 36:53 - 36:55
    kuin olisimme tartunnan saaneet salasanavarkaan kautta.
  • 36:55 - 37:00
    Koska tämä prosessi vie hieman aikaa, voimme tarkastella kaikkia hienoja DDL-lauseita, oikein?
  • 37:00 - 37:05
    Näet siis, että aloitimme jonkin bin-vuodon ja heap-vuodon kanssa ja sitten purimme ne.
  • 37:05 - 37:12
    Ja aivan lopussa voit nähdä, että ohjelmamme luo yksinkertaisen webshellin p.php:lle.
  • 37:12 - 37:15
    Ja tämä on sama sivu, jota juuri yritimme tavoittaa.
  • 37:15 - 37:22
    Joten toivottavasti, joo - hienoa, se on tehty.
  • 37:22 - 37:26
    Nyt palaamme salasanavarkaan back-endiin.
  • 37:26 - 37:28
    Menemme p.php:hen ja saamme vastauksen 200.
  • 37:28 - 37:34
    Nyt suoritamme jotain koodia siinä. whoami. www-data.
  • 37:34 - 37:37
    Ja ilmeisesti meidän täytyy mennä /etc/passwordiin.
  • 37:40 - 37:41
    Jippii.
  • 37:42 - 37:51
    [Yleisö taputtaa]
  • 37:51 - 37:55
    Joten mitä juuri tapahtui, on se, että osoitimme,
  • 37:55 - 38:00
    että annetun kyselyn avulla ilkeämielisessä tietokannassa,
  • 38:00 - 38:04
    voimme suorittaa koodia kyselyprosessissa.
  • 38:04 - 38:07
    Nyt, kun otetaan huomioon, että SQLite on niin suosittu,
  • 38:07 - 38:11
    tämä todella avaa oven laajalle valikoimalle hyökkäyksiä.
  • 38:11 - 38:16
    Tutkitaan toista täysin erilaista käyttötapaa. Joka on täysin erilainen
  • 38:16 - 38:20
    Seuraava kohde on iOS pysyvyys.
  • 38:21 - 38:27
    iOS käyttää SQLiteä laajalti ja pysyvyyden saavuttaminen on todella vaikeaa,
  • 38:27 - 38:32
    koska kaikkien suoritettavien tiedostojen on oltava allekirjoitettuja.
  • 38:32 - 38:36
    Silti SQLite-tietokantoja ei ole allekirjoitettu, eikö niin, ne ovat vain dataa.
  • 38:36 - 38:38
    Niitä ei tarvitse allekirjoittaa.
  • 38:38 - 38:43
    Ja iOS ja MacOS ovat molemmat käännetty käyttäen ENABLE_FTS3_TOKENIZER:ia.
  • 38:43 - 38:46
    Se on se vaarallinen käännöshetken lippu.
  • 38:46 - 38:51
    Suunnitelmani on saada koodin suoritus uudelleenkäynnistyksen
  • 38:51 - 38:54
    jälkeen korvaamalla mielivaltainen SQLite-tietokanta.
  • 38:54 - 39:01
    Tämän saavuttamiseksi aion kohdistaa hyökkäyksen "AddressBook.sqlite" -nimiseen yhteystietokantaan.
  • 39:01 - 39:06
    Alkuperäisessä tietokannassa on kaksi taulua,
  • 39:06 - 39:09
    joilla ei ole merkittävää merkitystä, vaan ne ovat esimerkkejä.
  • 39:09 - 39:17
    Aion luoda haitallisen yhteystietokannan, ja aloitan kahdella haitallisella DDL-lausekkeella,
  • 39:17 - 39:19
    jotka ovat teille jo tuttuja.
  • 39:19 - 39:25
    Ensin korvaamme oletustokenizerin "simple" joukolla "A":ita.
  • 39:25 - 39:31
    Sitten toinen DDL-lauseke toteuttaa tämän haitallisen laukaisimen,
  • 39:31 - 39:35
    joten se kaataa ohjelman, koska joka kerta, kun luodaan virtuaalitaulumoduuli,
  • 39:35 - 39:39
    joku yrittää mennä tokenizerin rakentajan luokse.
  • 39:39 - 39:41
    Joten se kaatuu.
  • 39:41 - 39:47
    Seuraavaksi käyn läpi jokaisen alkuperäisen taulun
  • 39:47 - 39:50
    ja kirjoitan ne uudelleen käyttäen kyselykaappauksen tekniikkaa.
  • 39:50 - 39:54
    Sen sijaan että käytämme odotettuja sarakkeita,
  • 39:54 - 39:59
    ohjaamme suorituksen ylikirjoituslauseeseen ja kaatumislauseeseen.
  • 39:59 - 40:02
    Teimme sen yhdelle taululle, teemme sen myös muille.
  • 40:03 - 40:06
    Nyt käynnistämme uudelleen ja voilà,
  • 40:06 - 40:10
    saamme seuraavan CVE:n ja turvallinen käynnistys ohitettiin.
  • 40:10 - 40:12
    Ja jos kiinnität huomiota tarkasti, tämä on todella hienoa,
  • 40:12 - 40:18
    koska näemme että kaatuminen tapahtui osoitteessa 0x414141...49.
  • 40:18 - 40:24
    Tämä on juuri mitä odotimme tapahtuvan, koska tässä pitäisi olla konstruktorimme,
  • 40:24 - 40:28
    kahdeksan tavua version ensimmäisen kokonaisluvun jälkeen.
  • 40:29 - 40:32
    Mutta todellisuudessa tässä on enemmän. Saamme pienen bonuksen tässä.
  • 40:32 - 40:38
    Koska yhteystietokanta on itse asiassa käytössä monien eri prosessien kautta.
  • 40:38 - 40:45
    Joten Yhteystiedot, FaceTime, Springboard, WhatsApp, Telegram, XPCProxy ja monet muut.
  • 40:45 - 40:48
    Ja monilla näistä prosesseista on enemmän oikeuksia kuin toisilla.
  • 40:48 - 40:53
    Ja olemme osoittaneet, että voimme nyt suorittaa koodia prosessissa,
  • 40:53 - 40:55
    joka kysyy ilkeämielistä tietokantaamme.
  • 40:55 - 40:59
    Joten saimme myös oikeuksen kohottamisen tässä prosessissa.
  • 40:59 - 41:03
    Tämä on todella hienoa. Ja yhteystietokannassa ei ole mitään erityistä.
  • 41:03 - 41:06
    Itse asiassa mitä tahansa jaettua tietokantaa voidaan käyttää.
  • 41:06 - 41:09
    Tarvitsemme vain jotain, joka on kirjoitettavissa heikolla käyttäjällä
  • 41:09 - 41:16
    ja jota vahvempi käyttäjä sitten kysyy. Ja ilmeisesti kaikki nämä tekniikat
  • 41:16 - 41:19
    ja virheet ilmoitettiin Applelle, ja ne kaikki on korjattu.
  • 41:19 - 41:22
    Ja tässä ovat CVE:t, jos haluat lukea siitä myöhemmin.
  • 41:22 - 41:27
    Nyt, ynnätäkseni asioita, jos haluat oppia jotain tästä esityksestä,
  • 41:27 - 41:33
    en halua sen olevan hullua SQL-voimistelua tai joukko CVE-numeroita.
  • 41:33 - 41:35
    Haluan sen olevan seuraavaa.
  • 41:35 - 41:40
    Tietokannan kysely ei välttämättä ole turvallista, oli kyse sitten käynnistyksen yli,
  • 41:40 - 41:43
    käyttäjien välillä tai prosessien välillä,
  • 41:43 - 41:48
    tietokannan kysely ei välttämättä ole turvallista kyselyn kaappauksen vuoksi.
  • 41:48 - 41:51
    Ja nyt, kun on kyse kyselyjen kaappauksesta ja kyselykeskeisestä ohjelmoinnista,
  • 41:51 - 41:57
    nämä muistin korruptiot, joita voimme laukaista, voidaan todella hyödyntää luotettavasti pelkällä SQL:llä.
  • 41:57 - 42:01
    Emme tarvitse enää JavaScriptiä. Emme tarvitse WebSQL:ää.
  • 42:01 - 42:05
    Ja uskomme todella, että tämä on vain jäävuoren huippu.
  • 42:05 - 42:07
    Tähän mennessä SQLite on ollut erittäin suosittu,
  • 42:07 - 42:13
    mutta sitä on arvioitu vain WebSQL:n kapealta alueelta,
  • 42:13 - 42:19
    ja vaikka selaimen pwnaus on jännittävää, SQLite:lla on paljon enemmän potentiaalia.
  • 42:19 - 42:24
    Meillä on siis joitain ajatuksia mahdollisesta tulevasta työstä tämän kanssa.
  • 42:25 - 42:31
    Ilmeisesti todella hienoa olisi laajentaa primitiivejämme joitain vahvempia primitiivejä kohti, oikein.
  • 42:31 - 42:36
    Haluamme saada asioita, kuten absoluuttinen luku- ja kirjoituskyky.
  • 42:36 - 42:41
    Ja minun hatara POC-hyökkäykseni oli melko typerä,
  • 42:41 - 42:44
    koska siinä oli paljon vakioita, kuten olette nähneet,
  • 42:44 - 42:49
    mutta itse asiassa jos käytät SQLite:n sisäistä toimintoa,
  • 42:49 - 42:53
    jos hyökkäyksen aikana käytät funktiota kuten sqlite3_version(),
  • 42:53 - 42:57
    voit kysyä tulkilta, mikä versio sinulla on, millä käännösvalinnoilla se on käännetty,
  • 42:57 - 43:01
    voit dynaamisesti rakentaa näitä QOP-ketjuja
  • 43:01 - 43:07
    ja kohdistaa ne tiettyyn kohdeympäristöön, jota hyökkäät.
  • 43:07 - 43:10
    Itse asiassa hyödyntämällä sitä tosiasiaa, että hyökkäyksemme on tietokanta,
  • 43:10 - 43:14
    voimme luoda tämän todella coolin hyökkäyspolyglotin, ja ajattelemme,
  • 43:14 - 43:19
    että näitä tekniikoita voidaan käyttää oikeuksien kohottamiseen monissa tilanteissa,
  • 43:19 - 43:22
    koska kehittäjät eivät koskaan ajatelleet,
  • 43:22 - 43:28
    että nyt voimme ottaa minkä tahansa tietokannan, jota heikko käyttäjä voi kirjoittaa,
  • 43:28 - 43:33
    ja jota vahva käyttäjä voi kysyä, ja yhtäkkiä voimme yrittää kohottaa oikeuksiamme.
  • 43:33 - 43:39
    Toisaalta olisi todella mielenkiintoista huomata, että monet niistä primitiiveistä,
  • 43:39 - 43:42
    joita olen teille näyttänyt, eivät ole yksinomaan SQLite:n omaisuutta, eikö niin?
  • 43:42 - 43:46
    Osoitinpakkaus ja -purku sekä heap spraying
  • 43:46 - 43:49
    ja kaikki nämä asiat eivät ole yksinomaan SQLite:n omaisuutta.
  • 43:49 - 43:52
    Olisi todella mielenkiintoista ottaa nämä primitiivit ja nähdä,
  • 43:52 - 43:59
    voimmeko mennä eteenpäin ja hyödyntää muita muistin korruption bugia eri tietokanta-moottoreissa.
  • 44:00 - 44:01
    Kiitos paljon.
  • 44:02 - 44:09
    [Yleisö taputtaa]
  • 44:10 - 44:12
    Omer Gull, kiitos paljon.
  • 44:12 - 44:14
    Siinä oli paljon aikaa kysymyksille.
  • 44:14 - 44:17
    Meillä on kolme mikrofonia täällä salissa:
  • 44:17 - 44:19
    Numero yksi, Numero kaksi ja Numero kolme.
  • 44:19 - 44:22
    Jos sinulla on kysymyksiä, ole hyvä ja jonota.
  • 44:22 - 44:25
    Onko meillä joitakin kysymyksiä verkosta?
  • 44:28 - 44:30
    Ei ole. Ookei.
  • 44:30 - 44:32
    Aloittakaamme sitten mikrofonista numero kaksi.
  • 44:32 - 44:39
    Joo. Kysymys koskee sitä "CREATE-jotakin" kaappaamista.
  • 44:39 - 44:44
    Mainitsit, että alussa tutkimus oletti,
  • 44:44 - 44:50
    että CREATE oli ensimmäinen tarkistusjärjestys
  • 44:50 - 44:55
    ja sitten välilyönti CREATE-sanalla ja sen jälkeen se voisi luoda kaikki muut asiat.
  • 44:55 - 45:00
    Nyt kysymykseni on: Jos se muuttui raporttisi jälkeen,
  • 45:00 - 45:08
    koska tämä vaikuttaa tavalta altistaa suurempi hyökkäyspinta kuin useimmat muut bugit.
  • 45:08 - 45:10
    Joten haluaisin tietää, jos he muuttivat sitä.
  • 45:10 - 45:14
    Ja mitä oli lopulta se lieventäminen, jos sitä oli?
  • 45:14 - 45:19
    Joo. Niin, meidän escalate-henkilöt ovat enemmän huolissaan tiettyjen virheiden
  • 45:19 - 45:21
    kuin hyökkäystekniikoiden suhteen.
  • 45:21 - 45:24
    Tämä on todella surullista, koska tiedämme kaikki,
  • 45:24 - 45:27
    että virheet voidaan korjata, mutta hyökkäystekniikat jäävät käyttöön.
  • 45:27 - 45:29
    Joten ei, he eivät muuttaneet tätä tarkistusta.
  • 45:29 - 45:37
    Itse asiassa tämä "create "-validoinnin lisäys tehtiin vasta äskettäin.
  • 45:37 - 45:40
    Sitä ennen pystyit käyttämään mitä tahansa DDL-lauseketta haluat.
  • 45:40 - 45:43
    Joten tilanne ei ole todella hyvä siellä.
  • 45:43 - 45:45
    Hyvä heille ja onnea tulevaisuudelle.
  • 45:46 - 45:47
    Ja siinä oli kysymys.
  • 45:48 - 45:51
    Okei. Sitten siirrymme mikrofoni ykköseen, kiitos.
  • 45:51 - 45:56
    Oletko ehkä vahingossa hyökännyt palvelimelle, jota käytetään salasanan varastamiseen?
  • 45:56 - 45:58
    Ei, tietenkään en tekisi niin.
  • 45:58 - 46:00
    En hyökkäisi kenenkään kimppuun.
  • 46:00 - 46:04
    Tämä on vain meidän laboratoriossamme POC:na. Okei.
  • 46:04 - 46:05
    Kiitos.
  • 46:05 - 46:08
    Salasanasi ovat turvassa varkailta.
  • 46:08 - 46:10
    [Naurua] . Noniin
  • 46:10 - 46:11
    Kukaan ei enää jonota.
  • 46:11 - 46:15
    Onko meillä kysymyksiä verkosta? Ei mitään siellä.
  • 46:15 - 46:16
    No, tästä lähdetään.
  • 46:16 - 46:16
    Kiitos.
  • 46:16 - 46:17
    Omer Gull, kiitos paljon.
  • 46:17 - 46:20
    [Yleisö taputtaa]
  • 46:22 - 46:32
    [Translated by Jouko Voutilainen (KYBS2001 course assignment at JYU.FI)]
Title:
36C3 - SELECT code_execution FROM * USING SQLite;
Description:

more » « less
Video Language:
English
Duration:
46:47

Finnish subtitles

Revisions