0:00:00.782,0:00:05.786 [Translated by Jouko Voutilainen (KYBS2001 course assignment at JYU.FI)] 0:00:18.231,0:00:29.299 Vasemmallani on Omer Gull, ja hän puhuu meille aiheesta "SELECT code_execution FROM * USING SQLite". 0:00:29.299,0:00:33.381 Omer, Omer Gull, sinun esityksesi, sinun lavasi, pidä hauskaa! 0:00:33.381,0:00:34.728 Kiitos. Kiitos. 0:00:34.728,0:00:39.233 [Yleisö taputtaa] 0:00:39.259,0:00:40.459 Hei kaikille. 0:00:40.459,0:00:46.329 Tervetuloa esitykseeni "SELECT code_execution FROM * USING SQLite", 0:00:46.329,0:00:51.849 jossa saavutamme koodin suorittamisen (code execution) haavoittuvaisia SQLite-tietokantoja käyttäen. 0:00:52.113,0:00:55.850 Nimeni on Omer Gull. Olen haavoittuvuuksien tutkija Tel Avivista. 0:00:55.850,0:01:00.905 Olen työskennellyt Check Point Researchissa viimeiset kolme vuotta 0:01:00.905,0:01:05.346 ja olen äskettäin siirtynyt uuteen startupiin nimeltä Hunters.AI. 0:01:05.738,0:01:07.554 Agendamme tänään: 0:01:07.554,0:01:12.332 Aloitamme pienellä motivaatiolla ja taustatarinan kertomisella tästä tutkimuksesta. 0:01:12.332,0:01:21.100 Sen jälkeen meillä on lyhyt SQLite-johdanto ja tutkimme haitallisten tietokantojen hyökkäyspintaa. 0:01:21.485,0:01:28.559 Käsittelemme myös aiempaa työtä SQLite-hyödyntämisessä ja mietimme, 0:01:28.559,0:01:33.948 miten käyttää muistin korruptiohäiriöitä pelkästään SQL:n avulla. 0:01:33.948,0:01:41.007 Sitten esittelemme oman innovatiivisen tekniikkamme nimeltä "Query Oriented Programming" tai QOP, 0:01:41.007,0:01:44.240 ja demonstroimme sitä muutamassa esimerkissä. 0:01:44.320,0:01:50.513 Käärimme asiat yhteen tulevaisuuden mahdollisuuksien ja johtopäätösten kanssa. 0:01:50.598,0:01:55.415 Motivaatio tälle tutkimukselle on melko ilmeinen. 0:01:55.415,0:02:00.346 SQLite on yksi eniten käytetyistä ohjelmistoista. 0:02:00.346,0:02:04.527 Olipa kyse PHP 5:stä, PHP 7:stä, Androidista, iOS:stä, 0:02:04.527,0:02:08.009 Mac OS:stä, se on nyt sisäänrakennettu Windows 10:een. 0:02:08.009,0:02:10.947 Sitä on Firefoxissa ja Chromessa. 0:02:11.517,0:02:13.704 Tämä luettelo voisi jatkua loputtomiin. 0:02:13.704,0:02:16.923 Kuitenkin SQLite-tietokannan kyselyä pidetään 0:02:16.923,0:02:21.044 turvallisena. Toivottavasti tämän puheen lopussa tajuat, 0:02:21.044,0:02:23.855 miksi tämä ei välttämättä ole totta. 0:02:24.410,0:02:27.917 Kaikki alkoi salasanavarkaista, 0:02:27.917,0:02:35.276 mikä on melko outoa, ja niitä on paljon, paljon vapaana, mutta tarina on yleensä sama. 0:02:35.567,0:02:38.601 Ensinnäkin tietokone saa tartunnan. 0:02:39.311,0:02:42.500 Sitten haittaohjelma kerää tallennettuja käyttäjätunnuksia, 0:02:42.500,0:02:45.453 sillä niitä on tallennettuna eri asiakasohjelmistoihin. 0:02:45.642,0:02:50.782 Jotkut näistä asiakasohjelmista tallentavat salaisuutesi SQLite-tietokantoihin. 0:02:51.434,0:02:59.934 Haittaohjelma lähettää SQLite-tietokantoja C2-palvelimelle, jossa salaisuudet[br]poimitaan 0:02:59.934,0:03:02.295 ja tallennetaan yhteiseen tietokantaan 0:03:02.295,0:03:03.875 muun saaliin kanssa. 0:03:04.596,0:03:12.283 Eräänä päivänä kollegani Omri ja minä tutkimme erittäin tunnetun salasanavarkaan vuodattamia lähdetiedostoja. 0:03:12.613,0:03:20.123 Ajattelimme: "Nämä kaverit vain keräävät tietokantojamme ja parsivat ne omaan back-endiinsä. 0:03:20.333,0:03:27.446 Voimmeko todella hyödyntää luotettamattoman tietokannan latausta ja kyselyä?" 0:03:27.446,0:03:31.215 Ja jos voimme, sillä voisi olla paljon suuremmat vaikutukset, 0:03:31.215,0:03:40.653 koska SQLiteä käytetään lukemattomissa skenaarioissa. Ja niin alkoi tähänastisen elämäni pisin CTF-haaste. 0:03:42.093,0:03:50.088 SQLite. Toisin kuin useimmat SQL-tietokannat, SQLite:llä ei ole asiakas-palvelinarkkitehtuuria. 0:03:50.088,0:03:55.527 Sen sijaan se lukee ja kirjoittaa tiedostoja suoraan tiedostojärjestelmään. 0:03:55.527,0:04:02.258 Joten sinulla on yksi täydellinen tietokanta, jossa on useita taulukoita, indeksejä, laukaisimia ja näkymiä, 0:04:02.258,0:04:11.794 ja kaikki sisältyvät yhteen tiedostoon. Tutkitaan siis hyökkäyspintaa, jonka potentiaalisesti haitallinen SQLite-tietokanta antaa. 0:04:12.144,0:04:17.074 Tämä on palanen koodia erittäin tunnetusta salasanavarkaasta, 0:04:17.074,0:04:23.388 ja meillä on kaksi tärkeintä kiinnostuksen kohdetta: Ensinnäkin meillä on sqlite3_open, 0:04:23.388,0:04:26.942 jossa potentiaalisesti haitallisen tietokanta ladataan, 0:04:26.942,0:04:29.492 ja jotain parsimista tapahtuu. 0:04:29.492,0:04:34.362 Ja ilmeisesti meillä on itse kysely. SELECT-lauseke. 0:04:34.362,0:04:37.427 Huomaa kuitenkin, että meillä ei ole hallintaa siitä lausekkeesta. 0:04:37.427,0:04:39.780 Se on kovakoodattu kohteeseemme. 0:04:39.780,0:04:42.908 Se yrittää poimia salaisuudet tietokannastamme. 0:04:42.908,0:04:48.990 Mutta me hallitsemme sisältöä, joten meillä voi olla vaikutusta siihen, mitä siellä tapahtuu. 0:04:49.864,0:04:53.278 Ensimmäinen asia on sqlite3_open, 0:04:53.278,0:04:56.399 joka on vain joukko asetus- ja kokoonpanokoodia. 0:04:56.399,0:05:01.692 Seuraavaksi siirrymme suoraviivaiseen otsikkotiedoston parsimiseen, 0:05:01.692,0:05:05.425 otsikkotiedosto itse ei ole kovin pitkä, vain 100 tavua. 0:05:05.425,0:05:09.445 Kolmanneksi, se on jo fuzzattu kuoliaaksi AFL:llä. 0:05:09.445,0:05:13.776 Joten se ei ehkä ole kovin lupaava polku jatkaa. 0:05:14.476,0:05:18.939 Mutta Sqlite3_query saattaa olla hieman mielenkiintoisempi, 0:05:18.939,0:05:27.178 koska SQLite:n tekijän mukaan "SELECT-lauseke on SQL-kielen monimutkaisin käsky". 0:05:28.138,0:05:33.788 Voit tietää, että taustalla SQLite on virtuaalikone. 0:05:33.788,0:05:39.751 Joten jokainen kysely on ensin käännettävä joksikin tavukoodin muotoon. 0:05:39.751,0:05:42.968 Tätä kutsutaan myös valmisteluvaiheeksi. 0:05:43.278,0:05:46.851 Joten sqlite3_prepare kulkee ja laajentaa tuon kyselyn. 0:05:46.851,0:05:50.174 Esimerkiksi joka kerta, kun valitset asteriskin, 0:05:50.174,0:05:53.683 se kirjoittaa tämän asteriskin kaikkien sarakkeiden nimiksi. 0:05:56.003,0:05:59.758 Joten sqlite3LocateTable() varmistaa, 0:05:59.758,0:06:06.454 että kaikki kyselyssä käytetyt taulut ja sarakkeet todella olemassa ja sijaitsevat muistissa. 0:06:06.454,0:06:08.412 Mistä se löytää ne? 0:06:08.412,0:06:12.921 Jokaisella SQLite-tietokannalla on taulu nimeltään sqlite_master, 0:06:12.921,0:06:17.980 joka määrittelee tietokannan skeeman. 0:06:17.980,0:06:19.990 Ja tämä on sen rakenne. 0:06:19.990,0:06:23.527 Joten jokaiselle tietokannan objektille sinulla on merkintä, 0:06:23.527,0:06:33.019 jossa on sen tyyppi, taulu tai näkymä, sen nimi ja aivan alareunassa jotain, jota kutsutaan SQL:ksi. 0:06:33.019,0:06:38.550 Ja SQL on itse asiassa DDL, joka kuvaa objektia. 0:06:38.975,0:06:46.016 DDL tarkoittaa datamäärittelykieltä, ja sitä voidaan verrata C-kielen otsikkotiedostoihin. 0:06:46.016,0:06:52.881 Ne määrittelevät tietokannan objektien rakenteen, nimet ja tyypit. 0:06:52.881,0:06:57.227 Lisäksi ne näkyvät selkokielisinä tiedostossa. 0:06:57.272,0:07:05.264 Annan esimerkin. Avasin SQLite-tulkin, loin taulun ja lisäsin siihen arvoja. 0:07:05.264,0:07:10.003 Sitten lopetin tulkin ja nyt avaamme tiedoston heksadesimaalimuodossa. 0:07:10.003,0:07:18.260 Voit nähdä keltaisella korostettuna näkyvän DDL-lauseke, joka on osa pääskeemaa. 0:07:18.260,0:07:21.004 Alhaalla voit myös nähdä arvot. 0:07:21.439,0:07:23.900 Palataan kyselyn valmisteluun. 0:07:24.382,0:07:33.219 Meillä on sqlite3LocateTable, joka yrittää löytää taulun rakenteen, jota haluamme kysellä. 0:07:33.219,0:07:39.030 Se lukee skeeman sqlite_masterista, jonka juuri kuvailimme. 0:07:39.030,0:07:41.534 Ja jos se tekee sen ensimmäistä kertaa, 0:07:41.534,0:07:47.097 sillä on joitakin takaisinkutsufunktioita jokaiselle näistä DDL-lausekkeista. 0:07:47.097,0:07:56.723 Takaisinkutsufunktio validoi DDL:n ja rakentaa sen jälkeen sisäiset rakenteet kyseisestä objektista. 0:07:56.723,0:08:00.944 Sitten ajattelimme DDL:n paikkaamista. 0:08:00.944,0:08:05.941 Entä jos vain korvaamme SQL-kyselyn DDL:ssä? 0:08:05.941,0:08:09.036 Tämä johtaa kuitenkin pieneen ongelmaan. 0:08:09.036,0:08:13.883 Tämä on aiemmin mainitsemani takaisinkutsufunktio, ja kuten näet, 0:08:13.883,0:08:23.158 DDL tarkistetaan ensin aloittavan "create ":lla. Vasta sen jälkeen valmistelu jatkuu. 0:08:23.158,0:08:25.249 Tämä on ehdottomasti rajoitus, eikö niin? 0:08:25.249,0:08:27.981 Meidän DDL:n on aloitettava "create ":lla. 0:08:27.981,0:08:31.750 Mutta tämä jättää jonkin verran tilaa joustavuudelle, 0:08:31.750,0:08:37.216 sillä SQLite-dokumentaation perusteella monia asioita voidaan luoda. 0:08:37.216,0:08:42.154 Voimme luoda indeksejä, taulukoita, laukaisimia, näkymiä ja jotain, 0:08:42.154,0:08:45.874 mitä emme vielä täysin ymmärrä, nimeltä virtuaaliset taulukot. 0:08:45.874,0:08:54.556 Niinpä ajattelimme "CREATE VIEW":ta, koska näkymä on vain esipakattu SELECT-lauseke, 0:08:54.556,0:08:58.637 ja näkymiä kysytään hyvin samalla tavalla kuin taulukoita. 0:08:58.637,0:09:05.669 Joten, taulukosta sarakkeen valitseminen on semanttisesti sama asia kuin sarakkeen valitseminen näkymästä. 0:09:06.509,0:09:10.264 Sitten, kun ajattelimme kyselyn kaappaamisen käsitettä. 0:09:10.264,0:09:15.338 Aiomme paikata sqlite_master DDL:n näkymillä taulukoiden sijaan. 0:09:15.338,0:09:20.074 Nyt paikatut näkymät voivat olla mitä tahansa SELECT-alilauseketta, jonka haluamme. 0:09:20.074,0:09:25.506 Ja nyt tällä alilausekkeella voin yhtäkkiä käyttää SQLite-tulkintaa. 0:09:25.506,0:09:30.986 Ja tämä on valtava askel eteenpäin! Muutimme juuri hallitsemattoman kyselyn joksikin, 0:09:30.986,0:09:32.997 jota voimme jonkin verran hallita. 0:09:32.997,0:09:36.775 Joten anna minun näyttää sinulle esimerkki kyselyn kaappaamisesta. 0:09:36.775,0:09:41.138 Sanotaan, että joissakin alkuperäisissä tietokannoissa oli yksi taulu, 0:09:41.138,0:09:46.535 ja tämä on DDL, joka määrittelee sen. Joten se on nimeltään "dummy" ja sillä on kaksi saraketta. 0:09:46.535,0:09:51.616 Joten ilmeisesti mikä tahansa kohdesovellus yrittäisi kysyä sitä seuraavasti: 0:09:51.616,0:09:55.587 Se vain yrittäisi valita nämä sarakkeet taulukosta, eikö niin. 0:09:55.587,0:09:59.197 Mutta seuraava näkymä voi todella kaapata tämän kyselyn. 0:09:59.197,0:10:04.104 Luon näkymän, se on juuri samanniminen ja sillä on sama määrä sarakkeita, 0:10:04.104,0:10:07.225 ja jokainen sarake on nimetty samalla tavalla, ja voit nähdä, 0:10:07.225,0:10:10.252 että nyt jokainen sarake voi sisältää minkä tahansa alilausekkeen, 0:10:10.252,0:10:13.789 jonka haluan, korostettuna sinisellä alareunassa. 0:10:13.789,0:10:16.509 Joten anna minun näyttää sinulle käytännön esimerkki siitä. 0:10:16.509,0:10:20.688 Tässä olen luonut näkymän nimeltä "dummy" col A ja col B:llä, 0:10:20.688,0:10:26.308 ja ensimmäinen sarake käyttää sqlite_version()-funktiota, ja se on sisäänrakennettu funktio, 0:10:26.308,0:10:29.136 joka palauttaa SQLite-version, ilmeisesti. 0:10:29.356,0:10:35.496 Toinen sarake käyttää SQLite:n omaa toteutusta printf:stä. 0:10:35.496,0:10:39.650 Juuri näin, niillä on kaikki nämä todella yllättävät ominaisuudet ja kyvyt. 0:10:39.650,0:10:44.013 Joten katsotaan sitä nyt oletetusti - kohdesivulta. 0:10:44.013,0:10:47.993 Joten kuka tahansa, joka yrittää valita näistä sarakkeista, 0:10:47.993,0:10:50.971 suorittaa yhtäkkiä meidän funktioitamme. 0:10:50.971,0:10:56.628 Vasemmalla voit nähdä SQLite-version, ja oikealla voit nähdä printf:n, 0:10:56.628,0:11:01.806 joka suoritettiin kohdesivulla. Joten taas tämä on valtava edistysaskel. 0:11:01.806,0:11:05.509 Me saavutimme juuri jonkin verran kontrollia sen kyselyn yli, eikö niin? 0:11:05.509,0:11:10.018 Ja kysymys kuuluu, mitä voimme tehdä tällä kontrollilla. 0:11:10.018,0:11:13.257 Onko SQLite:llä mitään järjestelmäkomentoja? 0:11:13.257,0:11:18.454 Voimmeko ehkä lukea ja kirjoittaa jotain muita tiedostoja tiedostojärjestelmässä? 0:11:21.274,0:11:26.460 Joten tämä oli hyvä kohta pysähtyä ja tarkastella jo tehtyä työtä alalla, 0:11:26.460,0:11:29.220 koska ilmeisesti emme ole ensimmäiset, 0:11:29.220,0:11:34.117 jotka ovat huomanneet SQLite:n valtavan potentiaalin hyväksikäytössä. 0:11:34.117,0:11:37.765 Järkevä paikka aloittaa on SQLite-injektio, 0:11:37.765,0:11:40.497 koska tämä on jonkinlainen vastaava tilanne, eikö niin? 0:11:40.497,0:11:45.106 Jollakulla haitallisella on jonkinlainen kontrolli SQL-kyselyssä. 0:11:45.106,0:11:50.440 Joten, on olemassa muutama tunnettu temppu SQL-injektiossa SQLite:llä. 0:11:50.440,0:11:54.420 Ensimmäisellä on tekemistä toisen tietokannan liittämisen kanssa 0:11:54.420,0:11:58.457 ja sen jälkeen taulun luomisen ja joitain merkkijonoja sen sisään laittamisen. 0:11:58.457,0:12:03.163 Ja koska, kuten mainitsin aiemmin, jokainen tietokanta on vain tiedosto, 0:12:03.163,0:12:08.200 tämä on jonkinlainen mielivaltainen tiedosto, tiedostojärjestelmässä. 0:12:08.200,0:12:11.703 Kuitenkin meillä on tämä rajoitus, muistattehan, että emme voi liittää, 0:12:11.703,0:12:14.776 koska DDL:n on aloitettava "CREATE"-sanalla. 0:12:15.436,0:12:19.497 Toinen hieno temppu on käyttää load extension -funktiota väärin. 0:12:19.497,0:12:24.995 Ja tässä voit nähdä, kuinka voit mahdollisesti ladata etä-DLL:n. 0:12:24.995,0:12:26.863 Tässä tapauksessa meterpreter.dll, 0:12:26.863,0:12:31.293 mutta ilmeisesti tämä erittäin vaarallinen funktio on oletuksena pois käytöstä. 0:12:31.293,0:12:36.514 Joten se taas ei onnistu. Entä muistin korruptio SQLite:ssä, 0:12:36.514,0:12:41.849 koska SQLite on todella monimutkainen ja se on kaikki kirjoitettu C:llä. 0:12:42.478,0:12:47.343 Hänen hämmästyttävässä blogikirjoituksessaan "Virheiden löytäminen SQLite:ssä helposti", 0:12:47.343,0:12:50.098 Michal Zalewski, AFL:n tekijä, kuvasi, 0:12:50.098,0:12:55.635 kuinka hän löysi 22 bugia alle 30 minuutissa fuzzingilla 0:12:55.635,0:12:58.246 Ja itse asiassa, sen jälkeen, 0:12:58.246,0:13:01.583 kun kyseessä oli versio 3.8.10 vuonna 2015, 0:13:01.583,0:13:07.306 SQLite alkoi käyttää AFL:ää osana huomattavaa testisarjaa. 0:13:07.306,0:13:15.081 Nämä muistin korruptiovirheet osoittautuivat kuitenkin erittäin vaikeiksi hyödyntää ilman sopivaa ympäristöä. 0:13:15.081,0:13:19.834 Turvallisuustutkimusyhteisö löysi kuitenkin pian täydellisen kohteen, 0:13:19.834,0:13:22.400 ja se oli nimeltään WebSQL. 0:13:22.660,0:13:28.402 Joten WebSQL on periaatteessa API tietojen tallentamiseen tietokantoihin, 0:13:28.402,0:13:33.835 ja sitä kysytään JavaScriptistä, ja sillä on SQLite-tausta. 0:13:33.835,0:13:37.305 Lisäksi se on saatavana Chromessa ja Safarissa. 0:13:37.305,0:13:43.475 Tässä voit nähdä hyvin yksinkertaisen esimerkin siitä, miten voit käyttää WebSQL:ää JavaScriptistä. 0:13:46.525,0:13:49.523 Mutta toisin sanoen, mitä täällä luulen, on se, 0:13:49.523,0:13:53.248 että meillä on joitakin luottamattomia syötteitä SQLite:lle, 0:13:53.248,0:13:56.992 ja se on saavutettavissa mistä tahansa Internetin verkkosivustosta 0:13:56.992,0:13:59.596 kahdessa maailman suosituimmassa selaimessa. 0:13:59.596,0:14:02.265 Ja yhtäkkiä nämä virheet, 0:14:02.265,0:14:10.449 nämä muistin korruptiot, voidaan nyt hyödyntää JavaScript-hyväksikäytön tiedosta ja mukavuudesta. 0:14:10.499,0:14:14.875 JavaScript-tulkin hyväksikäyttö, jossa olemme tulleet varsin hyviksi vuosien varrella. 0:14:14.875,0:14:22.066 Joten WebSQL:stä on julkaistu useita vaikuttavia tutkimuksia, 0:14:22.066,0:14:23.870 jotka vaihtelevat todella helppoista kohteista, 0:14:23.870,0:14:26.933 kuten CVE-2015-7036, 0:14:26.933,0:14:31.556 joka oli luottamattoman osoittimen purku fts3_tokenizer()-funktiossa, 0:14:31.556,0:14:33.978 monimutkaisempiin hyökkäyksiin, 0:14:33.978,0:14:42.593 kuten Blackhat 2017:ssä esitelty Chaitin-tiimin löytämä tyyppisekoittumisongelma FTS-optimoinnissa, 0:14:42.593,0:14:46.225 sekä hiljattain Magellan-bugit, jotka Tencent löysi, 0:14:46.225,0:14:50.842 jotka löysivät kokonaisluvun ylivuodon FTS-segmentinlukijassa. 0:14:50.842,0:14:53.911 Ja jos kiinnität nyt edes hieman huomiota, 0:14:53.911,0:14:57.598 niin näet mielenkiintoisen kaavan nousevan esiin. 0:14:57.598,0:15:01.677 Kaikki nämä haavoittuvat funktiot alkavat FTS:llä. 0:15:01.677,0:15:03.087 Joten mikä on FTS? 0:15:03.087,0:15:04.573 En ole koskaan kuullut siitä. 0:15:04.573,0:15:05.826 Ja kun etsin sitä Googlesta, 0:15:05.826,0:15:08.063 se vain hämmensi minua vielä enemmän. 0:15:09.565,0:15:10.820 Jonkin ajan kuluttua tajusin, 0:15:10.820,0:15:19.104 että FTS tarkoittaa "täysi tekstihaku" ja se on jotain nimeltään virtuaalinen taulukkomoduuli, 0:15:19.104,0:15:23.999 joka mahdollistaa todella hienovaraisen tekstin haun dokumenttien joukosta. 0:15:23.999,0:15:27.269 Tai kuten SQLite-tekijät kuvasivat sitä, 0:15:27.269,0:15:29.748 se on "kuin Google SQLite-tietokannoillesi". 0:15:29.748,0:15:34.970 Joten virtuaalitaulukot mahdollistavat joitain todella hienoja toimintoja SQLite:ssa, 0:15:34.970,0:15:39.574 olipa kyseessä tämä vapaa tekstin haku tai virtuaalitaulukkomoduuli nimeltään RTREE, 0:15:39.574,0:15:42.652 joka tekee todella fiksua maantieteellistä indeksointia, 0:15:42.652,0:15:44.922 tai virtuaalitaulukko nimeltään CSV, 0:15:44.922,0:15:47.967 joka antaa sinun käsitellä tietokantaasi CSV-tiedostona. 0:15:47.967,0:15:52.395 Ja näitä virtuaalitaulukoita kysytään itse asiassa ihan kuin normaaleja taulukoita. 0:15:52.395,0:15:56.534 Kuitenkin taustalla tapahtuu joitain pimeitä taikoja. 0:15:56.534,0:16:01.112 Ja jokaisen kyselyn jälkeen, kutsutaan jonkinlaista takaisinkutsufunktiota, 0:16:01.112,0:16:05.736 joka toimii niin kutsuttua shadow-taulukkoa vastaan. 0:16:05.736,0:16:09.172 Varjotaulukot olisi parasta selittää esimerkin avulla. 0:16:09.172,0:16:15.774 Joten sanotaan, että luon virtuaalitaulukon käyttäen sitä FTS-virtuaalitaulukkomoduulia 0:16:15.774,0:16:18.081 ja lisään siihen merkkijonon. 0:16:18.081,0:16:22.974 Ilmeisesti tehokkaan haun sallimiseksi minulla täytyy olla joitain metatietoja, okei? 0:16:22.974,0:16:26.823 Minun täytyy olla joitain offsetteja tai indeksejä tai merkkejä tai jotain sellaista. 0:16:26.823,0:16:29.117 Ja ilmeisesti kaikki ne ovat tekstiä, eikö niin? 0:16:29.117,0:16:34.037 Joten yksi virtuaalitaulukko on itse asiassa raakatekstiä, 0:16:34.037,0:16:37.704 ja metatiedot tallennetaan kolmen varjoshadow-taulukon joukkoon. 0:16:37.704,0:16:43.339 Joten raakateksti menisi vt_contentiin ja metatiedot menisivät vt_segmentsiin ja vt_segdiriin. 0:16:44.078,0:16:49.379 Ajan myötä nämä varjotaulukot ovat liittymäpintoja, 0:16:49.379,0:16:51.521 jotka siirtävät tietoa toistensa välillä. 0:16:51.521,0:16:54.075 Koska metatieto tallentaa kaikki nämä osoittimet, 0:16:54.075,0:16:56.528 sinun on siirrettävä ne toistensa välillä. 0:16:56.528,0:16:59.464 Ja nämä liittymäpinnat osoittautuivat todella, 0:16:59.464,0:17:02.083 todella luottavaisiksi luonteeltaan. 0:17:02.083,0:17:06.997 Ja se tekee niistä todella otollisen maaperän bugin metsästykseen. 0:17:06.997,0:17:13.433 Näytän teille nyt bugin, jonka löysin RTREE-virtuaalitaulukkomoduulista. 0:17:14.639,0:17:18.841 RTREE-virtuaalitaulumoduuli on nyt saatavilla MacOS- ja iOS-laitteille, 0:17:18.841,0:17:22.504 ja se on todella hieno, koska se on nyt myös osa Windows 10:ää. 0:17:22.504,0:17:27.617 Ja kuten mainitsin, se tekee todella fiksua maantieteellistä indeksointia. 0:17:27.617,0:17:34.032 DDL:n tulisi olla seuraava. Minkä tahansa RTREE-virtuaalitaulun tulisi alkaa "id":llä, 0:17:34.032,0:17:39.448 jonka täytyy olla kokonaisluku. Sen jälkeen sinulla on joitakin X- ja Y-koordinaatteja. 0:17:39.448,0:17:44.591 Joten jokainen RTREE-liitäntä odottaisi "id":n olevan kokonaisluku. 0:17:44.591,0:17:48.716 Mutta jos luon virtuaalitaulun ja lisään "id":hen jotain, 0:17:48.716,0:17:54.662 joka ei ole kokonaisluku, ja käytän yhtä näistä RTREE-liitännäisistä, 0:17:54.662,0:17:59.150 rtreenode, näet alhaalla, että saamme tämän kaatumisen, 0:17:59.150,0:18:03.328 tämän kekomuistin ulkopuolisen lukemisen. 0:18:03.328,0:18:07.499 Ja tämä esimerkki on kaatuminen Windows 10:ssä. 0:18:07.499,0:18:11.128 Joten se on aika hyvä. Olemme havainneet, 0:18:11.128,0:18:13.978 että virtuaalitaulussa on bugeja. 0:18:13.978,0:18:16.992 Ja nyt, käyttämällä kyselyn kaappaustekniikkaa, 0:18:16.992,0:18:21.313 voimme yhtäkkiä laukaista nämä bugit kohteellamme, 0:18:21.313,0:18:25.832 joka on salasanavaras C2, ja se kaatuu (segfault). 0:18:25.832,0:18:30.050 Ja tämä on hienoa, mutta varsinaisen ohjauksen saaminen kohteestamme 0:18:30.050,0:18:33.593 vaatii jonkinlaista skriptausta, eikö niin? 0:18:33.593,0:18:37.003 Haluamme ohittaa ASLR:n ja tehdä kaikenlaisia hulluja asioita. 0:18:37.003,0:18:39.079 Meillä ei kuitenkaan ole JavaScriptiä, 0:18:39.079,0:18:43.787 meillä ei ole JavaScript-taulukoita ja muuttujia ja logiikkalauseita, 0:18:43.787,0:18:50.369 kuten if ja and silmukoita ja sellaisia. Kuitenkin muistamme jostain kuulleemme, 0:18:50.369,0:18:53.257 että SQL on Turing-täydellinen. 0:18:53.257,0:18:58.880 Joten päätimme testata sitä hyökkäysnäkökulmasta 0:18:58.880,0:19:03.622 ja aloimme luoda omaa primitiivista toivelistaa hyökkäystä varten. 0:19:03.622,0:19:06.490 Joten jos se voisi luoda täyden hyökkäyksen, 0:19:06.490,0:19:09.712 jossa hyödynnetään muistin korruptiobugeja pelkästään SQL:llä, 0:19:09.712,0:19:11.896 mitä kyvykkyyksiä haluamme? 0:19:11.896,0:19:15.208 Joten ilmeisesti ohittaaksemme ASLR:n ja nämä asiat, 0:19:15.208,0:19:16.659 tarvitsemme vuodon muistista. 0:19:16.659,0:19:18.777 Meidän täytyy saada tietovuoto. 0:19:18.777,0:19:20.955 Jos olet tehnyt pwningia menneisyydessäsi, 0:19:20.955,0:19:24.051 sinun täytyy olla tuttu todella yleisten tehtävien suhteen, 0:19:24.051,0:19:29.339 kuten 64-bittisten osoittimen purkamisesta ja joitakin osoitinlaskutoimituksia, eikö niin? 0:19:29.339,0:19:33.126 Koska meillä oli tietovuoto, muunnamme - luemme tämän osoittimen, 0:19:33.126,0:19:35.412 ja se on little-endian, joten meidän täytyy kääntää se, 0:19:35.412,0:19:38.867 ja nyt haluamme laskea, missä on libsqlite-tiedoston perusta, 0:19:38.867,0:19:40.959 jotta voimme löytää ehkä lisää funktioita. 0:19:40.959,0:19:43.869 Joten tarvitsemme joitakin osoitinlaskutoimituksia. 0:19:43.869,0:19:48.042 Luonnollisesti, kun olemme lukeneet osoittimet ja manipuloineet niitä, 0:19:48.042,0:19:52.424 haluamme pakata ne uudelleen ja kirjoittaa ne jonnekin. 0:19:52.424,0:19:55.959 Yhden osoittimen kirjoittaminen ei koskaan riitä. 0:19:55.959,0:19:59.370 Haluamme luoda väärennettyjä objekteja muistissa, 0:19:59.370,0:20:04.514 monimutkaisempia kuin yksi osoitin. Lopuksi, haluaisimme heap sprayn, 0:20:04.514,0:20:06.551 koska se voi olla todella hyödyllinen. 0:20:06.551,0:20:09.317 Joten, kysymys kuuluu, 0:20:09.317,0:20:13.427 voiko kaikki tämä hyödyntäminen tehdä pelkästään SQL:llä? 0:20:13.427,0:20:16.075 Vastaus on "kyllä, se on mahdollista". 0:20:16.075,0:20:21.231 Ja esittelen teille ylpeänä Kysely-orientoitunut ohjelmointi tai QOP. 0:20:21.231,0:20:30.153 Demonstroidakseni QOP:ia hyväksikäytämme haavoittuvuutta CVE-2015-7036. 0:20:33.273,0:20:34.580 Ja saatatte kysyä itseltänne: 0:20:34.580,0:20:38.685 Miten neljä vuotta vanha bugi on edelleen korjaamatta? 0:20:38.685,0:20:42.473 Ja tämä on hieno asia argumenttiimme. 0:20:42.473,0:20:48.962 Tämä CVE koettiin vaaralliseksi vain luottamattomien Web-SQL:n suhteen. 0:20:48.962,0:20:51.274 Se siis kierrettiin oikein. 0:20:51.274,0:20:55.820 Se on blacklistattu ja SQL on käännetty tietyllä lipulla. 0:20:55.820,0:20:59.299 Joten selkeästi selaimet eivät enää ole kääntäneet tällä lipulla. 0:20:59.299,0:21:00.504 Mutta anna minun näyttää sinulle, 0:21:00.504,0:21:02.362 minkä kanssa nämä liput on käännetty. 0:21:02.362,0:21:04.678 Joten meillä on PHP 5 ja PHP 7, 0:21:04.678,0:21:06.397 jotka ovat vastuussa suurimmasta osasta Internetiä, 0:21:06.397,0:21:10.000 sekä iOS ja MacOS ja todennäköisesti niin monia muita kohteita, 0:21:10.000,0:21:14.275 joita emme vain ehtineet käydä läpi. 0:21:14.275,0:21:16.698 Joten selitetään hieman tätä haavoittuvuutta. 0:21:16.698,0:21:19.591 Olen maininnut, että se on FTS-tokenizerissa. 0:21:19.911,0:21:24.658 Joten tokenizer on vain joukko sääntöjä dokumenttien 0:21:24.658,0:21:26.751 tai kyselyjen termeistä erottamiseksi. 0:21:26.751,0:21:30.938 Ja oletustokenizeri, jota kutsutaan "yksinkertaiseksi", 0:21:30.938,0:21:33.918 vain jakaa merkkijonot tyhjien merkkien perusteella. 0:21:33.918,0:21:38.637 Kuitenkin, jos haluat, voit rekisteröidä oman mukautetun tokenizerin. 0:21:38.637,0:21:42.429 Voit vain siirtää C-funktion ja oikeastaan rekisteröit 0:21:42.429,0:21:47.763 tämän mukautetun tokenizerin fts3_tokenizer() -funktiolla SQL-kyselyssä. 0:21:48.793,0:21:51.125 Tässä on jonkin verran asiaa, mutta sanon sen hitaasti. 0:21:51.125,0:21:55.514 Siirrät riviosoittimen C-funktioon SQL-kyselyssä. 0:21:55.514,0:21:57.448 Tämä on täysin mielipuolista. 0:21:57.448,0:22:00.641 Rehellisesti sanottuna, vaikka olen tutkinut tätä jonkin aikaa, 0:22:00.641,0:22:05.098 en vieläkään ymmärrä, miten käyttää tätä ominaisuutta hyväksi muualla kuin hyökkäyksessäni. 0:22:05.515,0:22:12.663 [Yleisö taputtaa] 0:22:15.826,0:22:20.277 fts3_tokenizer() on ylikuormitettu funktio, 0:22:20.277,0:22:22.243 ja jos kutsut sen yhdellä argumentilla, 0:22:22.243,0:22:27.303 joka on tokenizerin nimi, saat takaisin kyseisen tokenizerin osoitteen. 0:22:27.303,0:22:33.760 Teemme sen hieman ihmiselle luettavammaksi käyttämällä heksadesimaalimuunnosta. 0:22:33.760,0:22:38.916 Voit nyt nähdä, että saimme tietovuodon libsqlite3:een. 0:22:38.916,0:22:42.970 Koska se on little-endian, meidän on käännettävä se ympäri, 0:22:42.970,0:22:44.755 mutta tämä on jo melko hienoa. 0:22:44.755,0:22:48.326 Jos kutsut fts3_tokenizer():ia kahdella argumentilla, 0:22:48.326,0:22:55.022 joista ensimmäinen on tokenizerin nimi ja toinen on raakaosoitin, ja tämä on täysin mielipuolista.. 0:22:55.022,0:22:58.010 voit kirjoittaa kyseisen tokenizerin osoitteen uudelleen. 0:22:58.010,0:23:01.748 Joten aina kun joku yrittää käyttää virtuaalitaulua 0:23:01.748,0:23:08.188 ja se instantisoi oletusarvoisen tokenizerin, se kaatuu. 0:23:08.188,0:23:10.739 Tämä on melko hämmästyttävää. 0:23:10.739,0:23:14.174 Lyhyt kertaus: olemme vahvistaneet, 0:23:14.174,0:23:18.140 että SQLite on ihana yhden maalin kohde monille, eikö niin? 0:23:18.140,0:23:19.741 Se on kaikkialla. 0:23:19.741,0:23:23.652 Ja se on monimutkainen C:llä kirjoitettu kone. 0:23:23.652,0:23:27.458 Nyt, kyselyn kaappaamisen avulla voimme alkaa laukaista näitä bugeja 0:23:27.458,0:23:35.231 ja tavoitella täydellistä hyökkäystä käyttämällä SQL-kyselyjä. 0:23:35.631,0:23:40.698 Hyökkäysstrategiamme on seuraava: vuodatamme joitakin osoittimia 0:23:40.698,0:23:44.708 ja sitten laskemme joitakin funktio-osoitteita. 0:23:44.708,0:23:47.519 Luomme sitten väärennetyn tokenizer-objektin, 0:23:47.519,0:23:50.414 jolla on jokin osoitin system()-funktioon. 0:23:50.414,0:23:55.161 Ylikirjoitamme oletusarvoisen tokenizerin ja laukaisemme pahantahtoisen tokenizerimme. 0:23:55.161,0:24:02.684 Sitten tapahtuu jotain, ja lopussa meidän pitäisi pystyä hyötymään jotenkin, eikö niin? 0:24:02.684,0:24:07.281 Aloittaen muistivuodosta ja tietovuodosta libsqliteen. 0:24:07.281,0:24:09.780 Tiedät jo, miten tehdään, eikö niin? 0:24:09.780,0:24:16.480 Näimme fts3_tokenizer():in, mutta meillä on vielä pieni ongelma little-endian osoittimen kanssa. 0:24:16.480,0:24:18.051 Joten meidän on käännettävä se ympäri. 0:24:18.051,0:24:20.745 Varmaan voimme käyttää SUBSTR-funktiota 0:24:20.745,0:24:25.473 ja lukea tämän osoittimen kaksi merkkiä kerrallaan käänteisessä järjestyksessä 0:24:25.473,0:24:29.212 ja yhdistää kaiken koko osoittimen läpi. 0:24:29.212,0:24:32.957 Joten saamme SELECT-kyselyn, joka näyttää seuraavalta, 0:24:32.957,0:24:35.410 mutta nyt meillä on osoitin. 0:24:35.410,0:24:36.801 Tämä on hienoa. 0:24:36.801,0:24:38.796 Entä tietovuoto kekomuistiin? 0:24:38.796,0:24:40.856 Haluamme tietää, missä keko sijaitsee. 0:24:40.856,0:24:43.375 Aloitetaanpa tekemään temppua, 0:24:43.375,0:24:46.588 joka on melko samankaltainen kuin RTREE-bugi, jonka olemme löytäneet. 0:24:46.588,0:24:50.736 Joten jälleen kerran, aiomme sekoittaa joitakin shadow-taulukkojen käyttöliittymiä. 0:24:50.736,0:24:56.023 Luomme siis virtuaalitaulukon ja lisäämme siihen joitakin arvoja. 0:24:56.023,0:24:59.718 Nyt aiomme hämmentää match-käyttöliittymää. 0:24:59.718,0:25:02.921 Match-käyttöliittymä tekee monia asioita, 0:25:02.921,0:25:09.193 mutta taustalla se vain palvelee osoittimen muistissa, jossa tekstin sijainti sijaitsee. 0:25:09.193,0:25:12.546 Se on tätä metadataa, hienoja asioita, joita virtuaalitaululla on. 0:25:12.546,0:25:14.657 Joten aiomme hämmentää sitä ja sen sijaan, 0:25:14.657,0:25:17.892 että siirtäisimme sen toiselle virtuaalitaulun käyttöliittymälle, 0:25:17.892,0:25:21.194 siirrämme sen yksinkertaisesti heksadekooderille, 0:25:21.194,0:25:23.519 joten puramme tämän raakanosoittimen. 0:25:23.519,0:25:25.708 Ja voit nähdä, jälleen kerran little-endianin, 0:25:25.708,0:25:28.036 mutta nyt meillä on linkki kekoon. 0:25:28.526,0:25:30.691 Voimme yliviivata sen listalta. 0:25:30.691,0:25:34.110 Ja ennen kuin siirrymme eteenpäin tämän osoittimen purkamiseen, 0:25:34.110,0:25:37.493 meillä on hyvin perustavanlaatuinen ongelma. 0:25:37.493,0:25:39.870 Kuinka edes tallennamme näitä asioita? 0:25:39.870,0:25:44.888 Koska toisin kuin selaimen WebSQL:ssä, meillä ei ole JavaScript-muuttujia tai taulukoita, 0:25:44.888,0:25:46.699 joita voimme käyttää ja hyväksikäyttää myöhemmin, 0:25:46.699,0:25:49.668 mutta meidän on luotava joitakin monimutkaisia logiikoita, eikö niin? 0:25:49.668,0:25:55.465 Meidän on laskettava funktio-osoite ja luotava asioita muistissa, mutta kuinka voimme tehdä sen? 0:25:55.465,0:25:58.037 Ilmeisesti SQLite:llä, kun haluat tallentaa joitakin arvoja, 0:25:58.037,0:26:04.801 sinun on oltava insert-lausekkeita, mutta voimme vain luoda tauluja, näkymiä, indeksejä ja laukaisimia. 0:26:05.901,0:26:11.754 Sitten ajattelimme ketjuttaa tämän näkymän yhteen käyttääksemme niitä jonkinlaisena pseudomuuttujana. 0:26:11.754,0:26:13.908 Joten jälleen kerran, anna minun näyttää sinulle esimerkki. 0:26:13.908,0:26:18.147 Tässä luon näkymän, jota kutsutaan "little-endian leak", okei? 0:26:18.147,0:26:21.873 Ja taas hyväksikäytän fts3_tokenizer() -funktiota. 0:26:21.873,0:26:25.153 Nyt luon toisen näkymän sen päälle, ja tätä kutsutaan "leakiksi" 0:26:25.153,0:26:27.775 ja kääntyy käyttämällä SUBSTR-temppua, 0:26:27.775,0:26:29.148 jonka tiedät jo aikaisemmasta. 0:26:29.148,0:26:33.095 Mutta huomaa, kuinka viittasin ensimmäiseen näkymään, viittasin "little-endian leak":iin. 0:26:33.095,0:26:40.419 Joten teen sen koko osoittimen läpi, ja lopulta minulla on pseudomuuttuja nimeltä "leak". 0:26:40.419,0:26:44.847 Kun valitsen sen, saan odotetun tuloksen. 0:26:45.131,0:26:47.666 Joten nyt voimme todella edetä. 0:26:47.666,0:26:51.761 Nyt voimme aloittaa monimutkaisempien asioiden rakentamisen tämän logiikan perusteella. 0:26:52.491,0:26:54.934 Ja nyt voimme siirtyä purkamaan osoittimia. 0:26:55.474,0:27:01.211 Haluamme esimerkiksi laskea kuvan perustan tai löytää keon alun. 0:27:01.211,0:27:05.677 Joten ensinnäkin haluamme muuntaa osoittimemme kokonaisluvuiksi. 0:27:05.677,0:27:11.740 Joten jälleen kerran aloitamme lukemalla nämä osoittimet yhden merkin kerrallaan 0:27:11.740,0:27:14.821 ja käänteisessä järjestyksessä käyttäen SUBSTRia. 0:27:14.821,0:27:20.835 Ja saadaksemme heksadesimaalimerkin arvon, käytämme INSTR-funktiota, 0:27:20.835,0:27:27.207 joka on kuin strchar, ja käyttämällä seuraavaa merkkijonoa saamme heksadesimaalimerkin arvon. 0:27:27.207,0:27:32.238 Koska se on yksipohjainen, on oikealla miinus yksi. 0:27:32.238,0:27:36.577 Sitten minun täytyy tehdä hieman siirtämistä, kuten jotain pimeää magiaa, 0:27:36.577,0:27:42.332 ja sitten yhdistän kaiken yhteen osoittimessa. 0:27:42.332,0:27:45.100 Joten tulos on tämä hirviömäinen kysely. 0:27:45.100,0:27:53.060 Mutta kun kaikki tämä on tehty, saan kokonaisluvun, joka on purkamaton versio alkuperäisestä vuodosta. 0:27:53.060,0:27:56.621 Joten onnistuin purkamaan tämän osoittimen, 0:27:56.621,0:28:01.093 ja meillä on nyt käsillä kokonaislukuja, joten voimme yliviivata sen listalta myös. 0:28:01.093,0:28:03.948 Tiedämme nyt, miten muuntaa osoittimet kokonaisluvuiksi. 0:28:04.198,0:28:10.886 Nyt osoitinlaskentaa, koska haluamme saada joitain toimintojen osoitteita muistissa, 0:28:10.886,0:28:14.430 ja itse asiassa kokonaislukuilla tämä on erittäin yksinkertaista. 0:28:14.430,0:28:17.658 Kaikki mitä meidän tarvitsee tehdä on käyttää joitakin alikyselyjä. 0:28:17.658,0:28:21.199 Vasemmalla voit nähdä, että viittaan nyt pseudomuuttujiin, 0:28:21.199,0:28:23.990 joita meillä on nyt, vuotanut tieto, 0:28:23.990,0:28:29.572 ja oikealla voin joko vähentää hölmön vakion kuten tein täällä, 0:28:29.572,0:28:37.688 tai voin todella käyttää toista pseudomuuttujaa tehdäkseni sen hieman dynaamisemmaksi ja luotettavammaksi. 0:28:37.688,0:28:45.327 Lopulta, mihin päädyin, on libsqlite-perusta kokonaislukumuodossa. 0:28:45.327,0:28:50.272 Joten, olemme lukeneet joitakin osoittimia ja manipuloineet niitä. 0:28:50.272,0:28:55.740 Nyt on hyvä aika kirjoittaa ne takaisin. Ja tietysti olemme tottuneet siihen, 0:28:55.740,0:28:59.101 että "char" on täysin päinvastainen kuin "hex". 0:28:59.101,0:29:03.840 Ja voit nähdä, että se toimii melko hyvin useimmilla arvoilla, 0:29:03.840,0:29:08.928 mutta suuremmat kokonaisluvut todella käännettiin niiden kahden tavun koodipisteisiin. 0:29:08.928,0:29:12.016 Joten tämä oli suuri este meille. 0:29:15.196,0:29:20.186 Joten, kun olimme viettäneet dokumentaation parissa jonkin aikaa, 0:29:20.186,0:29:22.642 yhtäkkiä meille valkeni kummallinen oivallus. 0:29:22.642,0:29:25.919 Tajusimme, että hyökkäyksemme on itse asiassa tietokanta. 0:29:25.919,0:29:28.929 Ja jos haluan minkä tahansa muunnoksen tapahtuvan, 0:29:28.929,0:29:33.986 voin yksinkertaisesti luoda etukäteen tämän avain-arvo-kartan ja yksinkertaisesti 0:29:33.986,0:29:41.297 kysyä sitä käännettäväksi millä tahansa arvolla toiseksi arvoksi alikyselyillä. 0:29:41.297,0:29:43.405 Tämä on se Python-funktio, jonka olen käyttänyt, 0:29:43.405,0:29:45.808 ja voit nähdä, että siinä on hyvin yksinkertainen for-silmukka, 0:29:45.808,0:29:49.705 joka menee 0:sta FF:ään ja vain lisää arvoja tauluun, 0:29:49.705,0:29:52.416 jota kutsutaan "hex_map", sen avain-kartan arvoilla. 0:29:52.416,0:29:58.782 Ja nyt muunnoksemme käyttävät alikyselyjä. Joten anna minun jälleen näyttää esimerkki. 0:29:59.732,0:30:02.310 Voit nähdä, että valitsen "val" heksakartasta, 0:30:02.310,0:30:06.702 tästä avain-arvo-kartasta, jossa "int" on yhtä suuri kuin, 0:30:06.702,0:30:11.368 ja sitten teen hieman enemmän kaikenlaista, kuten siirtämistä ja modulo pimeää magiaa, 0:30:11.368,0:30:17.059 mutta lopulta päädyin pakattuun versioon libsqlite-tietokannasta. 0:30:17.059,0:30:23.304 Nyt meillä on pakattu little-endian osoitin, joten sen voi ruksata listalta pois. 0:30:24.644,0:30:29.929 Kuten mainitsin, yksittäisen osoittimen kirjoittaminen on ehdottomasti hyödyllistä, 0:30:29.929,0:30:31.020 mutta se ei riitä. 0:30:31.295,0:30:34.272 Haluamme väärentää kokonaisia objekteja, eikö niin? 0:30:34.272,0:30:38.046 Kaikki coolit tyypit tekevät niin, ja se on melko voimakas primitiivi. 0:30:38.046,0:30:40.897 Ja jos muistat, meidän on tehtävä se, 0:30:40.897,0:30:46.086 koska fts3_tokenizer() edellyttää meidän määrittävän tokenizer moduulin. 0:30:46.086,0:30:51.454 No, mikä on tokenizer-moduuli? Miltä se näyttää? Joten tämä on sen rakenteen alku, 0:30:51.454,0:30:54.483 ja siinä on "iVersion", joka on kokonaisluku alussa, 0:30:54.483,0:30:56.456 meillä ei ole oikeastaan mitään tekemistä sen kanssa, 0:30:56.456,0:30:59.273 mutta sen jälkeen on kolme funktio-osoitinta. 0:30:59.573,0:31:06.237 Meillä on "xCreate", joka on jakelijan rakentaja, ja "xDestroy", joka on purkaja. 0:31:06.237,0:31:11.538 Meidän on tehtävä molemmat kelvollisiksi, jotta sovellus ei kaadu hyökätessämme. 0:31:11.538,0:31:15.198 Kolmas funktio-osoitin on todella mielenkiintoinen, koska tämä on se, 0:31:15.198,0:31:16.645 joka todella jakaa merkkijonon osiksi. 0:31:16.645,0:31:20.784 Joten meillä on funktio-osoitin, johon ohjataan hallittavissa oleva merkkijono. 0:31:20.784,0:31:25.620 Tämä olisi täydellinen paikka laittaa system-vimpaimemme, eikö niin. 0:31:26.510,0:31:31.737 Tähän mennessä olen käyttänyt melkoisesti SQL-osaamistani, eikö niin? 0:31:31.737,0:31:37.251 Mutta minulla on vielä yksi temppu hihassani ja se on JOIN-kyselyt, eikö niin? 0:31:37.251,0:31:40.663 Koska olen oppinut siitä menneessä ajassa. 0:31:40.663,0:31:44.217 Joten nyt luomme väärennetyn tokenizer-näkymän 0:31:44.217,0:31:48.887 ja yhdistämme joukon "A"-kirjaimia ja sitten käyttäen JOIN-kyselyä 0:31:48.887,0:31:53.900 ja yhdistämme sen osoittimeen simple_create ja osoittimeen simple_destroy 0:31:53.900,0:31:58.951 ja sitten joukon "B":itä. Nyt tarkistetaan se alhaisen tason debuggerissa 0:31:58.951,0:32:03.394 ja voit itse asiassa nähdä, että jossain muistipaikassa meillä on joukko "A":ita, 0:32:03.394,0:32:05.537 jonka perässä on osoitin simple_createen, 0:32:05.537,0:32:10.045 jonka perässä on osoitin simple_destroyiin ja sitten joukko "B":iä. 0:32:10.815,0:32:16.314 Joten olemme melkein valmiit. Mutta tarvitsemme vielä yhden primitiivin tätä hyödyntääksemme. 0:32:16.314,0:32:20.865 Ja tämä johtuu siitä, että meillä on jo haitallinen tokenizerimme, 0:32:20.865,0:32:26.217 ja tiedämme, missä keko sijaitsee, mutta emme ole aivan varmoja, missä tokenizerimme sijaitsee. 0:32:26.217,0:32:29.654 Tämä on hieno aika heap sprayinglle, eikö olekin. 0:32:29.654,0:32:35.204 Ja ihanteellisesti tämä olisi jonkin toistuva muoto meidän fakeobj -primitiivistämme. 0:32:35.204,0:32:44.031 Olemme siis ajatelleet toistoa, mutta valitettavasti SQLite ei ole toteuttanut sitä kuten mySQL. 0:32:44.031,0:32:45.599 Joten kuten kuka tahansa muukin, 0:32:45.599,0:32:50.346 menimme Stack Overflowiin ja löysimme tämän todella elegantin ratkaisun. 0:32:50.346,0:32:57.886 Käytämme siis zeroblob-funktiota, joka yksinkertaisesti palauttaa nollista koostuvan läjän. 0:32:57.886,0:33:02.641 Sitten korvaamme jokaisen nollan väärennetyllä tokenisaattorillamme. 0:33:02.641,0:33:05.721 Ja teemme sen kymmenentuhatta kertaa, kuten näette yllä. 0:33:05.861,0:33:08.764 Uudelleen, varmistaaksemme sen debuggerilla, 0:33:08.764,0:33:12.024 näet paljon "A":ita ja se on vähän vaikea nähdä, 0:33:12.024,0:33:16.414 koska nämä ovat todella huonoja värejä, mutta meillä on myös täydellinen johdonmukaisuus, 0:33:16.414,0:33:20.842 koska nämä rakenteet toistuvat joka 20. heksadesimaalitavussa. 0:33:21.222,0:33:25.823 Joten loimme melko hyvät heap-spraying -kyvyt, 0:33:26.773,0:33:30.952 ja olemme valmiit exploitti -toiveluettelomme kanssa, 0:33:30.952,0:33:34.489 joten voimme palata alkuperäiseen kohteeseemme. 0:33:34.489,0:33:39.709 Tämä on koodisegmentti erittäin tunnetusta salasanavarkaasta, 0:33:39.709,0:33:42.646 ja lopussa voit nähdä, että se yrittää valita 0:33:42.646,0:33:50.414 ja poimia salaisuuksia valitsemalla sarakkeen nimeltä "BodyRich" taulusta nimeltä "Notes". 0:33:50.414,0:33:54.203 Joten valmistelemme hänelle pienen yllätyksen, okei? 0:33:54.397,0:33:56.811 Luomme näkymän, jota kutsutaan nimellä "Notes". 0:33:56.811,0:34:00.766 Ja siinä on kolme alikyselyä sarakkeessa nimeltä "BodyRich". 0:34:00.766,0:34:05.193 Jokainen näistä alikyselyistä on itse asiassa QOP-ketju. 0:34:05.193,0:34:08.598 Jos muistat hyökkäyssuunnitelmani, 0:34:08.598,0:34:14.137 aloitamme heap-spray sitten korvaamme oletustokenisaattorin 0:34:14.137,0:34:17.148 ja laukaisemme lopuksi haitallisen tokenisaattorin. 0:34:17.148,0:34:20.408 Ja sinä saatat kysyä itseltäsi, mikä on heap_spray? 0:34:20.408,0:34:26.735 Ilmeisesti heap_spray on QOP-ketju, joka hyödyntää heap-spraying -kykyjämme, eikö niin. 0:34:26.735,0:34:32.856 Me ruiskutamme kymmenentuhatta esimerkkiä väärennetystä tokenizeristamme, 0:34:32.856,0:34:39.564 joka on JOIN-kysely joukosta "A":ita ja joitain osoittimia, kuten p64_simple_create. 0:34:40.044,0:34:47.601 Ja bileet jatkuvat, koska p64_simple_create on itse asiassa peräisin u64_simple_createsta, oikein, 0:34:47.601,0:34:51.218 käyttäen osoittimenpakkauskykyjämme. 0:34:51.218,0:34:54.646 Ja tämä on kuin maatuska-nukke, 0:34:54.646,0:35:02.059 koska sinulla on u64_simple_create, joka on peräisin libsqlite_basesta plus joistakin vakioista. 0:35:02.059,0:35:06.573 Ja tämä menee takaisin purkamattomaan vuotoversioon, 0:35:06.573,0:35:07.792 miinus joitain vakioita. 0:35:07.792,0:35:12.764 Joten jälleen kerran käytämme osoitinlaskentakykyjämme. 0:35:13.354,0:35:18.485 Voimme jatkaa u64_leak:illa, joka on peräisin lähes alkuperäisestä vuodosta. 0:35:18.485,0:35:21.802 Ja me päätämme näyttämällä, 0:35:21.802,0:35:27.869 kuinka vuoto on itse asiassa peräisin alkuperäisestä haavoittuvuudesta käyttäen fts3_tokenizeria. 0:35:27.869,0:35:33.350 Ja tämä oli vain yksi kolmesta QOP-ketjusta, joita käytimme tässä hyökkäyksessä. 0:35:33.350,0:35:38.533 Ja tällä hetkellä joka kerta, kun kuvaan tätä hyökkäystä, tämä on miltä minä varmasti näytän. 0:35:38.533,0:35:41.443 Ja ollakseni rehellinen, tämä on juurikin mitä tunnen. 0:35:41.443,0:35:44.721 Mutta onneksi teidän ei tarvitse näyttää tai tuntea samalta kuin minä, 0:35:44.721,0:35:49.892 koska loimme QOP.py:n, ja se on saatavilla Checkpoint Researchin GitHubissa. 0:35:49.892,0:35:56.825 Ja yhtäkkiä nämä hullun pitkät ketjut voidaan luoda neljällä helpolla Python-rivillä. 0:35:56.825,0:35:59.818 Ja tuntuu pwntoolsilta, jos olet perehtynyt siihen, 0:35:59.818,0:36:04.757 joten voit mennä eteenpäin ja leikkiä sillä etkä näytä hullulta lavalla. 0:36:05.377,0:36:07.751 Siirrymme ensimmäiseen demoomme. 0:36:07.751,0:36:12.684 Ownaamme salasanan varastavaa taustapalvelinta, joka toimii uusimmalla PHP 7:llä. 0:36:12.684,0:36:16.983 Tietenkin tämä on malli, jonka loimme vuotaneista lähteistä, 0:36:16.983,0:36:20.354 ja näet kaikki tartunnan saaneet uhrit 0:36:24.535,0:36:25.295 Coolia 0:36:25.295,0:36:28.245 Nyt yritämme mennä web-shelliin, p.php:hen. 0:36:28.765,0:36:31.871 Tietenkään sitä ei vielä ole olemassa, saamme 404. 0:36:32.239,0:36:34.878 Siirrymme hyökkääjän tietokoneelle. 0:36:34.878,0:36:37.524 Näemme täällä kaksi skriptiä. 0:36:37.524,0:36:43.650 Ensin käytämme QOP.py:ä, joka luo ilkeämielisen tietokannan. 0:36:43.650,0:36:46.510 Katsotaanpa, tietokanta luotiin. 0:36:46.510,0:36:49.149 Nyt emuloimme saastuttamisen. 0:36:49.149,0:36:52.537 Aloitamme lähettämällä ilkeämielisen tietokantamme C2-palvelimelle 0:36:52.537,0:36:54.939 kuin olisimme tartunnan saaneet salasanavarkaan kautta. 0:36:54.939,0:37:00.078 Koska tämä prosessi vie hieman aikaa, voimme tarkastella kaikkia hienoja DDL-lauseita, oikein? 0:37:00.078,0:37:05.059 Näet siis, että aloitimme jonkin bin-vuodon ja heap-vuodon kanssa ja sitten purimme ne. 0:37:05.059,0:37:11.623 Ja aivan lopussa voit nähdä, että ohjelmamme luo yksinkertaisen webshellin p.php:lle. 0:37:11.623,0:37:15.019 Ja tämä on sama sivu, jota juuri yritimme tavoittaa. 0:37:15.019,0:37:21.784 Joten toivottavasti, joo - hienoa, se on tehty. 0:37:21.784,0:37:26.004 Nyt palaamme salasanavarkaan back-endiin. 0:37:26.004,0:37:28.157 Menemme p.php:hen ja saamme vastauksen 200. 0:37:28.157,0:37:34.006 Nyt suoritamme jotain koodia siinä. whoami. www-data. 0:37:34.006,0:37:37.174 Ja ilmeisesti meidän täytyy mennä /etc/passwordiin. 0:37:39.994,0:37:41.193 Jippii. 0:37:42.253,0:37:50.683 [Yleisö taputtaa] 0:37:50.683,0:37:55.304 Joten mitä juuri tapahtui, on se, että osoitimme, 0:37:55.304,0:38:00.315 että annetun kyselyn avulla ilkeämielisessä tietokannassa, 0:38:00.315,0:38:04.004 voimme suorittaa koodia kyselyprosessissa. 0:38:04.004,0:38:07.199 Nyt, kun otetaan huomioon, että SQLite on niin suosittu, 0:38:07.199,0:38:11.344 tämä todella avaa oven laajalle valikoimalle hyökkäyksiä. 0:38:11.344,0:38:15.878 Tutkitaan toista täysin erilaista käyttötapaa. Joka on täysin erilainen 0:38:15.878,0:38:20.252 Seuraava kohde on iOS pysyvyys. 0:38:21.462,0:38:27.433 iOS käyttää SQLiteä laajalti ja pysyvyyden saavuttaminen on todella vaikeaa, 0:38:27.433,0:38:32.322 koska kaikkien suoritettavien tiedostojen on oltava allekirjoitettuja. 0:38:32.322,0:38:36.478 Silti SQLite-tietokantoja ei ole allekirjoitettu, eikö niin, ne ovat vain dataa. 0:38:36.478,0:38:38.346 Niitä ei tarvitse allekirjoittaa. 0:38:38.346,0:38:43.259 Ja iOS ja MacOS ovat molemmat käännetty käyttäen ENABLE_FTS3_TOKENIZER:ia. 0:38:43.259,0:38:45.507 Se on se vaarallinen käännöshetken lippu. 0:38:45.507,0:38:50.581 Suunnitelmani on saada koodin suoritus uudelleenkäynnistyksen 0:38:50.581,0:38:53.912 jälkeen korvaamalla mielivaltainen SQLite-tietokanta. 0:38:53.912,0:39:01.160 Tämän saavuttamiseksi aion kohdistaa hyökkäyksen "AddressBook.sqlite" -nimiseen yhteystietokantaan. 0:39:01.160,0:39:05.506 Alkuperäisessä tietokannassa on kaksi taulua, 0:39:05.506,0:39:09.050 joilla ei ole merkittävää merkitystä, vaan ne ovat esimerkkejä. 0:39:09.050,0:39:16.831 Aion luoda haitallisen yhteystietokannan, ja aloitan kahdella haitallisella DDL-lausekkeella, 0:39:16.831,0:39:19.227 jotka ovat teille jo tuttuja. 0:39:19.227,0:39:24.696 Ensin korvaamme oletustokenizerin "simple" joukolla "A":ita. 0:39:24.816,0:39:31.117 Sitten toinen DDL-lauseke toteuttaa tämän haitallisen laukaisimen, 0:39:31.117,0:39:35.387 joten se kaataa ohjelman, koska joka kerta, kun luodaan virtuaalitaulumoduuli, 0:39:35.387,0:39:39.341 joku yrittää mennä tokenizerin rakentajan luokse. 0:39:39.341,0:39:41.094 Joten se kaatuu. 0:39:41.094,0:39:46.584 Seuraavaksi käyn läpi jokaisen alkuperäisen taulun 0:39:46.584,0:39:50.462 ja kirjoitan ne uudelleen käyttäen kyselykaappauksen tekniikkaa. 0:39:50.462,0:39:53.890 Sen sijaan että käytämme odotettuja sarakkeita, 0:39:53.890,0:39:58.895 ohjaamme suorituksen ylikirjoituslauseeseen ja kaatumislauseeseen. 0:39:58.895,0:40:01.740 Teimme sen yhdelle taululle, teemme sen myös muille. 0:40:02.503,0:40:06.218 Nyt käynnistämme uudelleen ja voilà, 0:40:06.218,0:40:09.822 saamme seuraavan CVE:n ja turvallinen käynnistys ohitettiin. 0:40:09.822,0:40:12.168 Ja jos kiinnität huomiota tarkasti, tämä on todella hienoa, 0:40:12.168,0:40:18.088 koska näemme että kaatuminen tapahtui osoitteessa 0x414141...49. 0:40:18.088,0:40:24.136 Tämä on juuri mitä odotimme tapahtuvan, koska tässä pitäisi olla konstruktorimme, 0:40:24.136,0:40:28.304 kahdeksan tavua version ensimmäisen kokonaisluvun jälkeen. 0:40:29.064,0:40:32.196 Mutta todellisuudessa tässä on enemmän. Saamme pienen bonuksen tässä. 0:40:32.196,0:40:37.749 Koska yhteystietokanta on itse asiassa käytössä monien eri prosessien kautta. 0:40:37.749,0:40:44.716 Joten Yhteystiedot, FaceTime, Springboard, WhatsApp, Telegram, XPCProxy ja monet muut. 0:40:44.716,0:40:48.219 Ja monilla näistä prosesseista on enemmän oikeuksia kuin toisilla. 0:40:48.219,0:40:52.735 Ja olemme osoittaneet, että voimme nyt suorittaa koodia prosessissa, 0:40:52.735,0:40:54.965 joka kysyy ilkeämielistä tietokantaamme. 0:40:54.965,0:40:58.621 Joten saimme myös oikeuksen kohottamisen tässä prosessissa. 0:40:58.621,0:41:03.233 Tämä on todella hienoa. Ja yhteystietokannassa ei ole mitään erityistä. 0:41:03.233,0:41:05.835 Itse asiassa mitä tahansa jaettua tietokantaa voidaan käyttää. 0:41:05.835,0:41:08.930 Tarvitsemme vain jotain, joka on kirjoitettavissa heikolla käyttäjällä 0:41:08.930,0:41:15.570 ja jota vahvempi käyttäjä sitten kysyy. Ja ilmeisesti kaikki nämä tekniikat 0:41:15.570,0:41:18.563 ja virheet ilmoitettiin Applelle, ja ne kaikki on korjattu. 0:41:18.563,0:41:21.832 Ja tässä ovat CVE:t, jos haluat lukea siitä myöhemmin. 0:41:22.102,0:41:27.423 Nyt, ynnätäkseni asioita, jos haluat oppia jotain tästä esityksestä, 0:41:27.423,0:41:33.371 en halua sen olevan hullua SQL-voimistelua tai joukko CVE-numeroita. 0:41:33.371,0:41:35.055 Haluan sen olevan seuraavaa. 0:41:35.055,0:41:40.365 Tietokannan kysely ei välttämättä ole turvallista, oli kyse sitten käynnistyksen yli, 0:41:40.365,0:41:43.185 käyttäjien välillä tai prosessien välillä, 0:41:43.185,0:41:47.616 tietokannan kysely ei välttämättä ole turvallista kyselyn kaappauksen vuoksi. 0:41:47.616,0:41:51.307 Ja nyt, kun on kyse kyselyjen kaappauksesta ja kyselykeskeisestä ohjelmoinnista, 0:41:51.307,0:41:57.478 nämä muistin korruptiot, joita voimme laukaista, voidaan todella hyödyntää luotettavasti pelkällä SQL:llä. 0:41:57.478,0:42:00.758 Emme tarvitse enää JavaScriptiä. Emme tarvitse WebSQL:ää. 0:42:00.758,0:42:04.827 Ja uskomme todella, että tämä on vain jäävuoren huippu. 0:42:04.827,0:42:07.370 Tähän mennessä SQLite on ollut erittäin suosittu, 0:42:07.370,0:42:12.842 mutta sitä on arvioitu vain WebSQL:n kapealta alueelta, 0:42:12.842,0:42:19.319 ja vaikka selaimen pwnaus on jännittävää, SQLite:lla on paljon enemmän potentiaalia. 0:42:19.319,0:42:24.347 Meillä on siis joitain ajatuksia mahdollisesta tulevasta työstä tämän kanssa. 0:42:24.717,0:42:31.070 Ilmeisesti todella hienoa olisi laajentaa primitiivejämme joitain vahvempia primitiivejä kohti, oikein. 0:42:31.070,0:42:35.607 Haluamme saada asioita, kuten absoluuttinen luku- ja kirjoituskyky. 0:42:35.607,0:42:40.851 Ja minun hatara POC-hyökkäykseni oli melko typerä, 0:42:40.851,0:42:44.371 koska siinä oli paljon vakioita, kuten olette nähneet, 0:42:44.371,0:42:49.026 mutta itse asiassa jos käytät SQLite:n sisäistä toimintoa, 0:42:49.026,0:42:52.967 jos hyökkäyksen aikana käytät funktiota kuten sqlite3_version(), 0:42:52.967,0:42:57.316 voit kysyä tulkilta, mikä versio sinulla on, millä käännösvalinnoilla se on käännetty, 0:42:57.316,0:43:00.824 voit dynaamisesti rakentaa näitä QOP-ketjuja 0:43:00.824,0:43:06.591 ja kohdistaa ne tiettyyn kohdeympäristöön, jota hyökkäät. 0:43:06.591,0:43:09.792 Itse asiassa hyödyntämällä sitä tosiasiaa, että hyökkäyksemme on tietokanta, 0:43:09.792,0:43:14.140 voimme luoda tämän todella coolin hyökkäyspolyglotin, ja ajattelemme, 0:43:14.140,0:43:18.903 että näitä tekniikoita voidaan käyttää oikeuksien kohottamiseen monissa tilanteissa, 0:43:18.903,0:43:22.404 koska kehittäjät eivät koskaan ajatelleet, 0:43:22.404,0:43:27.529 että nyt voimme ottaa minkä tahansa tietokannan, jota heikko käyttäjä voi kirjoittaa, 0:43:27.529,0:43:32.906 ja jota vahva käyttäjä voi kysyä, ja yhtäkkiä voimme yrittää kohottaa oikeuksiamme. 0:43:33.236,0:43:38.858 Toisaalta olisi todella mielenkiintoista huomata, että monet niistä primitiiveistä, 0:43:38.858,0:43:42.194 joita olen teille näyttänyt, eivät ole yksinomaan SQLite:n omaisuutta, eikö niin? 0:43:42.194,0:43:45.839 Osoitinpakkaus ja -purku sekä heap spraying 0:43:45.839,0:43:48.800 ja kaikki nämä asiat eivät ole yksinomaan SQLite:n omaisuutta. 0:43:48.800,0:43:51.945 Olisi todella mielenkiintoista ottaa nämä primitiivit ja nähdä, 0:43:51.945,0:43:58.939 voimmeko mennä eteenpäin ja hyödyntää muita muistin korruption bugia eri tietokanta-moottoreissa. 0:44:00.109,0:44:01.419 Kiitos paljon. 0:44:02.248,0:44:08.858 [Yleisö taputtaa] 0:44:09.766,0:44:11.973 Omer Gull, kiitos paljon. 0:44:11.973,0:44:14.425 Siinä oli paljon aikaa kysymyksille. 0:44:14.425,0:44:17.301 Meillä on kolme mikrofonia täällä salissa: 0:44:17.301,0:44:19.460 Numero yksi, Numero kaksi ja Numero kolme. 0:44:19.460,0:44:22.153 Jos sinulla on kysymyksiä, ole hyvä ja jonota. 0:44:22.153,0:44:24.774 Onko meillä joitakin kysymyksiä verkosta? 0:44:28.220,0:44:29.560 Ei ole. Ookei. 0:44:29.560,0:44:32.016 Aloittakaamme sitten mikrofonista numero kaksi. 0:44:32.016,0:44:39.442 Joo. Kysymys koskee sitä "CREATE-jotakin" kaappaamista. 0:44:39.442,0:44:44.147 Mainitsit, että alussa tutkimus oletti, 0:44:44.147,0:44:49.656 että CREATE oli ensimmäinen tarkistusjärjestys 0:44:49.656,0:44:55.474 ja sitten välilyönti CREATE-sanalla ja sen jälkeen se voisi luoda kaikki muut asiat. 0:44:55.474,0:44:59.690 Nyt kysymykseni on: Jos se muuttui raporttisi jälkeen, 0:44:59.690,0:45:08.233 koska tämä vaikuttaa tavalta altistaa suurempi hyökkäyspinta kuin useimmat muut bugit. 0:45:08.233,0:45:09.779 Joten haluaisin tietää, jos he muuttivat sitä. 0:45:09.779,0:45:14.102 Ja mitä oli lopulta se lieventäminen, jos sitä oli? 0:45:14.102,0:45:19.078 Joo. Niin, meidän escalate-henkilöt ovat enemmän huolissaan tiettyjen virheiden 0:45:19.078,0:45:21.462 kuin hyökkäystekniikoiden suhteen. 0:45:21.462,0:45:23.976 Tämä on todella surullista, koska tiedämme kaikki, 0:45:23.976,0:45:26.688 että virheet voidaan korjata, mutta hyökkäystekniikat jäävät käyttöön. 0:45:26.688,0:45:29.470 Joten ei, he eivät muuttaneet tätä tarkistusta. 0:45:29.470,0:45:36.735 Itse asiassa tämä "create "-validoinnin lisäys tehtiin vasta äskettäin. 0:45:36.735,0:45:40.043 Sitä ennen pystyit käyttämään mitä tahansa DDL-lauseketta haluat. 0:45:40.043,0:45:42.915 Joten tilanne ei ole todella hyvä siellä. 0:45:42.915,0:45:45.167 Hyvä heille ja onnea tulevaisuudelle. 0:45:45.787,0:45:46.738 Ja siinä oli kysymys. 0:45:48.030,0:45:50.667 Okei. Sitten siirrymme mikrofoni ykköseen, kiitos. 0:45:50.667,0:45:56.205 Oletko ehkä vahingossa hyökännyt palvelimelle, jota käytetään salasanan varastamiseen? 0:45:56.205,0:45:58.143 Ei, tietenkään en tekisi niin. 0:45:58.143,0:46:00.171 En hyökkäisi kenenkään kimppuun. 0:46:00.171,0:46:03.968 Tämä on vain meidän laboratoriossamme POC:na. Okei. 0:46:03.968,0:46:04.963 Kiitos. 0:46:04.963,0:46:08.004 Salasanasi ovat turvassa varkailta. 0:46:08.074,0:46:10.154 [Naurua] . Noniin 0:46:10.154,0:46:10.973 Kukaan ei enää jonota. 0:46:10.973,0:46:14.894 Onko meillä kysymyksiä verkosta? Ei mitään siellä. 0:46:14.894,0:46:15.622 No, tästä lähdetään. 0:46:15.622,0:46:16.122 Kiitos. 0:46:16.122,0:46:17.232 Omer Gull, kiitos paljon. 0:46:17.232,0:46:19.842 [Yleisö taputtaa] 0:46:22.237,0:46:31.641 [Translated by Jouko Voutilainen (KYBS2001 course assignment at JYU.FI)]