Kun odotin innolla keskustelua tästä aiheesta, haluan kertoa teille vähän historiaa, teoriaa ja käytäntöjä haavoittuvuuksista. Olemme kaikki jo kuulleet, että tietoturva-aukot voivat maksaa paljon, me kaikki tiedämme, että meidän on pidettävä ohjelmistomme ajan tasalla, me kaikki tiedämme, että monet päivitykset johtuvat tietoturvaongelmista. Mutta tänään kerron sinulle vähän siitä, miten nämä virheet löydetään ja hyödynnetään 🙂 Mutta ennen tätä selvitämme muutamia yksityiskohtia saadaksemme paremman yleiskuvan.
Ennen aloittamista
Ensin haluan kertoa teille, että keskitymme ensimmäiseen haavoittuvuuteen, jota opin oppimaan hyödyntämään, tunnettuun Puskurin ylivuoto, tässä haavoittuvuudessa hyödynnämme muistin puutteen tekemistä hauskojen asioiden tekemiseksi 🙂 Mutta selvennetään siitä hieman enemmän.
Tämä ei tule olemaan todellinen skenaario
Minulla ei ole varaa opettaa heitä rikkomaan mitä tahansa näkemää ohjelmaa - ensinnäkin koska se on vaarallista heidän tietokoneilleen, toiseksi koska se vie enemmän kuin tavallinen sanakiintiöni.
Menemme matkalle 80-luvulle
Mitä aion näyttää sinulle, voin tehdä kannettavalla tietokoneellani, mutta se ei tarkoita, että se voidaan tehdä tänään yksinkertaisella tavalla 🙂 monia näistä käsitteistä on jo käytetty niin monta kertaa, että uusia suojausmenetelmiä ja uusia menetelmiä niiden välttämiseksi on tullut esiin 😛 mutta se palauttaa meidät samaan paikkaan, ei ole tilaa kertoa kaikkea sitä 🙂
Se ei välttämättä toimi prosessorissasi
Vaikka aion käyttää hyvin yksinkertaista esimerkkiä, haluan sen olevan aivan alusta alkaen selvää, että tämän yksityiskohdat ovat niin monia ja niin erilaisia, että aivan kuten se voi tulla sama kuin minä, jos haluat kokeilla sitä , toivottua vaikutusta ei myöskään välttämättä saavuteta 🙂 Mutta voitte kuvitella, etten voi selittää sitä tässä tilassa, varsinkin koska tämän johdannon kanssa olen jo ottanut yli 300 sanaa, joten pääsemme suoraan kohtaamme.
Mikä on a Puskurin ylivuoto
Vastaamiseksi tähän meidän on ensin ymmärrettävä tämän yhdistelmän ensimmäinen puolisko.
puskureita
Koska kaikki koskee tietokoneen muistia, on loogista, että tietyn tyyppisen tietosäiliön on oltava. Kun puhumme tuloa o lähdöt, tulemme suoraan käsitteeseen puskureita. Jotta se pysyisi lyhyenä, a puskuri Se on määritetyn kokoinen muistitila, johon aiomme tallentaa yksinkertaisen määrän tietoa
Ylivuotoja esiintyy, kuten nimestä voi päätellä, kun puskuri täyttää enemmän tietoja kuin se pystyy käsittelemään. Mutta miksi tämä on tärkeää?
Pinota
Ne tunnetaan myös nimellä pinot, ne ovat abstrakti tietotyyppi, jossa voimme pino tietoja, niiden pääominaisuus on, että heillä on tilaus LIFO (viimeinen ensimmäisenä lähtöön). Ajattelemme sekunnin ajan levypinosta, laitamme ne päälle yksi kerrallaan, ja sitten otamme ne yksi kerrallaan ylhäältä, tämä tekee viimeisen laittamamme levyn (yläosassa olevan) ) on ensimmäinen levy, jonka aiomme ottaa pois, ilmeisesti, jos voimme ottaa vain yhden levyn kerrallaan ja päätämme tehdä sen siinä järjestyksessä: P.
Nyt kun tiedät nämä kaksi käsitettä, meidän on järjestettävä ne. Pinot ovat tärkeitä, koska jokaisella ohjelmassa on oma suorituspino. Mutta tällä pinolla on erityinen ominaisuus, kasvaa alas. Ainoa asia, joka sinun on tiedettävä tästä, on se, että ohjelman ollessa käynnissä, kun toimintoa kutsutaan, pino siirtyy muistin numerosta X numeroon (Xn). Mutta jatkaaksemme meidän on ymmärrettävä vielä yksi käsite.
Osoittimet
Tämä on käsite, joka ajaa monet ohjelmoijat hulluksi aloittaessaan C-maailmassa, itse asiassa C-ohjelmoinnin suuri voima johtuu osittain osoittimien käytöstä. Yksinkertaisuuden vuoksi osoitin osoittaa muistiosoitteeseen. Tämä kuulostaa monimutkaiselta, mutta se ei ole niin monimutkainen, meillä kaikilla on koneissamme RAM-muistia? No, tämä voidaan määritellä a lohkojen peräkkäinen järjestely, nämä sijainnit ilmaistaan normaalisti heksadesimaalilukuina (0-9 ja sitten A - F, kuten 0x0, 0x1, 0x6, 0xA, 0xF, 0x10). Tässä utelias muistiinpano, 0x10 EI on yhtä suuri kuin 10 😛, jos muunnamme sen desimaalijärjestykseen, se olisi sama kuin sanoa 15. Tämä sekoittaa myös ensin enemmän kuin yhden, mutta ryhdymme siihen.
asiakirjat
Suorittimet työskentelevät useiden kanssa asiakirjat, jotka toimivat siirtämään sijainteja fyysisestä muistista prosessoriin, 64-bittisiä arkkitehtuureja varten rekisterien lukumäärä on suuri ja vaikea kuvata tässä, mutta idean saamiseksi rekisterit ovat kuin osoittimia, ne osoittavat muun muassa , muistitila (sijainti).
Harjoittele nyt
Tiedän, että tähän mennessä on ollut paljon tietoa käsiteltävänä, mutta todellisuudessa ne ovat jonkin verran monimutkaisia asioita, jotka yritän selittää hyvin yksinkertaisella tavalla, näemme pienen puskuria käyttävän ohjelman ja aiomme hajota se ymmärtääksesi tämän ylivuotoista, ilmeisesti tämä ei ole. Se on todellinen ohjelma, ja aiomme "kiertää" monet nykyisin käytetyistä vastatoimenpiteistä vain osoittamaan, miten asiat tehtiin ennen 🙂 ja koska jotkut näistä periaatteet ovat välttämättömiä, jotta voidaan oppia monimutkaisempia asioita 😉
GDB
Suuri ohjelma, joka on epäilemättä yksi C-ohjelmoijien eniten käyttämistä. Monien hyveiden joukossa meillä on tosiasia, että sen avulla voimme nähdä kaiken tämän, josta olemme puhuneet, rekisterit, pino, puskurit jne. 🙂 Katsotaanpa ohjelma, jota aiomme käyttää esimerkissämme.
uudelleentulo. c
Tämä on melko yksinkertainen ohjelma, aiomme käyttää kirjastoa stdio.h
pystyä hankkimaan tietoja ja näyttämään ne päätelaitteessa. Voimme nähdä funktion nimeltä return_input
joka tuottaa a puskuri nimeltään ryhmä, jonka pituus on 30 tavua (char-tietotyyppi on 1 tavu pitkä).
Toiminto gets(array);
pyydä tietoja konsolin ja toiminnon mukaan printf()
palauttaa taulukon sisällön ja näyttää sen näytöllä.
Jokainen C-kirjain kirjoitettu ohjelma alkaa funktiolla main()
, tämä vastaa vain return_input-kutsusta, nyt aiomme koota ohjelma.
Otetaan vähän siitä, mitä juuri tein. Vaihtoehto -ggdb
käskee gcc: n kääntämään ohjelman tietoja gdb: lle, jotta se voi virheenkorjata oikein. -fno-stack-protector
Se on vaihtoehto, jota meidän ei tietenkään pitäisi käyttää, mutta jota aiomme käyttää, koska muuten olisi mahdollista tuottaa puskurin ylivuoto pinossa. Loppujen lopuksi olen testannut tuloksen. ./a.out
Se vain suorittaa juuri kokoamani tiedot, se pyytää minulta tietoja ja palauttaa ne. Juoksu 🙂
varoitukset
Toinen muistiinpano täällä. Näetkö varoitukset? on selvää, että se on jotain, joka on otettava huomioon työskenneltäessä koodin kanssa tai kääntäessä, tämä on vähän ilmeistä, ja harvoissa ohjelmissa on nykyisin toiminto gets()
Koodissa. Yksi Gentoon etu on, että kokoamalla jokaisen ohjelman näen mikä voi olla vialla, "ihanteellisella" ohjelmalla ei pitäisi olla niitä, mutta olisit yllättynyt siitä, kuinka monessa suuressa ohjelmassa nämä varoitukset ovat, koska ne ovat vain erittäin suuria ja niitä on vaikea seurata. vaarallisia toimintoja, kun varoituksia on useita samanaikaisesti. Nyt jos jatkamme
Ohjelman virheenkorjaus
Nyt tämä osa voi olla hieman hämmentävä, mutta koska olen jo kirjoittanut melko vähän, minulla ei ole varaa selittää kaikkea, joten anteeksi, jos näet menen liian nopeasti 🙂
Koodin poistaminen käytöstä
Aloitetaan katsomalla käännettyä konekieliohjelmaa.
Tämä on päätoiminnon koodi Kokoonpano, prosessorimme ymmärtää tämän, vasemmalla oleva viiva on muistissa oleva fyysinen osoite <+ n> tunnetaan offset, pohjimmiltaan etäisyys funktion (pää) alusta siihen lausekkeeseen (tunnetaan nimellä opkoodi). Sitten näemme käskyn tyypin (push / mov / callq…) ja yhden tai useamman rekisterin. Yhteenvetona voimme sanoa, että se on lähtö, jota seuraa lähde / alkuperä ja määränpää. <return_input>
viittaa toiseen toimintoon, katsotaanpa.
paluusyöttö
Tämä on hieman monimutkaisempi, mutta haluan vain, että tarkistat muutaman asian, on tunniste nimeltä <gets@plt>
ja viimeinen opcode kutsutaan retq
toiminnon loppu. Aiomme laittaa pari katkaisupistettä, yhden funktioon gets
ja toinen retq
.
ajaa
Nyt aiomme suorittaa ohjelman nähdäksesi, miten toiminta alkaa.
Voimme nähdä, että ilmestyy pieni nuoli, joka osoittaa opkoodin missä olemme, haluan heidän ottavan huomioon suunnan 0x000055555555469b
, tämä on osoite puhelun jälkeen return_input
toiminnassa main
, tämä on tärkeää, koska tässä ohjelman pitäisi palata, kun olet vastaanottanut panos, päästään toimintoon. Nyt aiomme tarkistaa muistin ennen toiminnon syöttämistä gets
.
Olen asettanut päätoiminnon takaisin sinulle ja korostanut koodin, johon viittasin, kuten näette, loppu on jaettu kahteen osaan, haluan niiden ottavan huomioon suunnan 0x7fffffffdbf0
(ensimmäinen vasemmalta komenton jälkeen x/20x $rsp
), koska tämä on paikka, jota meidän on käytettävä tarkistaaksemme hakemusten tuloksia, jatketaan:
Ohjelman rikkominen
Olen korostanut niitä 0x44444444
koska ne edustavat Ds: itämme 🙂 nyt olemme alkaneet lisätä panos ohjelmaan, ja kuten näette, olemme vain kaksi riviä haluamastamme osoitteesta, aiomme täyttää sen, kunnes olemme juuri edellisessä vaiheessa korostamiemme osoitteiden edessä.
Paluureitin muuttaminen
Nyt kun olemme onnistuneet syöttämään koodin tämän osan, jossa se ilmaisee funktion paluun, katsotaanpa, mitä tapahtuu, jos muutamme osoitetta of sen sijaan, että menisimme hetki sitten käytetyn opkoodin sijaintiin, mitä luulet, jos palaamme takaisin return_input
? Mutta tätä varten on tarpeen kirjoittaa haluamasi osoite binaariin, aiomme tehdä sen funktiolla printf
alkaen bash 🙂
Nyt olemme saaneet tiedot kahdesti - varmasti ohjelmaa ei ole tehty sitä varten, mutta olemme onnistuneet rikkomaan koodin ja saamaan sen toistamaan jotain, mitä sen ei pitänyt tehdä.
Heijastuksia
Tätä yksinkertaista muutosta voidaan pitää a hyödyntää hyvin yksinkertainen 🙂 hän on onnistunut rikkomaan ohjelman ja tekemään jotain mitä haluamme hänen tekevän.
Tämä on vasta ensimmäinen askel melkein rajattomassa luettelossa nähtävää ja lisättävää, on tapoja lisätä enemmän asioita kuin pelkkä tilauksen toistaminen, mutta tällä kertaa olen kirjoittanut paljon ja kaikkea, mikä liittyy simpukakoodaus on aihe kirjoittaa enemmän kuin artikkeleita, kokonaisia kirjoja sanoisin. Anteeksi, jos en ole pystynyt kaivamaan vähän enemmän aiheisiin, jotka olisin halunnut, mutta varmasti on mahdollisuus 🙂 Terveisiä ja kiitoksia tänne pääsemisestä.
Ole suorempi. Kirjoita vähemmän ja keskity siihen, mikä on tärkeää
Hei, kiitos kommentista.
Totta puhuen olen leikannut hyvän osan ideoista, mutta silti minusta tuntui siltä, että se jätti vähimmäismäärän, jotta joku, jolla ei ole ohjelmointitaitoa, voisi saada idean.
terveiset
Ongelmana on, että ne, joilla ei ole ohjelmointitietoa, eivät saa mitään selville, koska se on aluksi liian monimutkaista, mutta ne, jotka osaavat ohjelmoida, arvostavat suorempaa olemista.
Oletan, ettet voi tavoittaa kaikkia, sinun on valittava, ja tässä tapauksessa olet tehnyt syntiä haluamalla kattaa paljon.
Muuten, sanon teille rakentavan kritiikin, rakastan näitä aiheita ja haluaisin, että jatkat artikkeleiden kirjoittamista, onnittelut!
Mielestäni sama asia.
Paljon kiitoksia molemmille! On varmasti vaikeaa ymmärtää, miten tavoittaa kohdeyleisö, kun totuus on, että edistyneellä ohjelmointitasolla ihmisiä, jotka lukevat näitä artikkeleita, on vähän (ainakin se voidaan päätellä kommenttien perusteella)
Olen varmasti tehnyt syntiä halusta yksinkertaistaa jotain, joka edellyttää laajan tietopohjan ymmärtämistä. Toivon, että ymmärrät, että koska olen vasta aloittamassa bloggaamista, en ole vielä löytänyt tarkkaa kohtaa, jossa lukijani tietävät ja ymmärtävät mitä sanon. Se tekisi totuuden kertomisen paljon helpommaksi 🙂
Yritän olla lyhyempi, kun se ansaitsee ilman muodon hajauttamista, koska kirjoitustavan erottaminen sisällöstä on hieman monimutkaisempi kuin mitä voisi kuvitella, minulla on ainakin ne melko linkittyinä, mutta oletan, että viime kädessä pystyn lisätä viivoja sisällön leikkaamisen sijaan.
terveiset
Mistä voisit tietää aiheesta lisää? Onko suositeltavaa kirjaa?
Esimerkki, jonka sain Shellcoderin käsikirjasta, Chris Anley, John Heasman, Felix Linder ja Gerardo Richarte, mutta 64-bittisen käännöksen tekemiseksi minun piti oppia arkkitehtuuristani, intel-kehittäjän käsikirja, 2. ja 3. osa ovat melko luotettava lähde siihen. On myös hyvä lukea GDB-dokumentaatio, joka tulee `` info gdb '' -komennon kanssa. Kokoonpanon ja C: n oppimiseksi on monia erittäin hyviä kirjoja, paitsi että Assembly-kirjat ovat vähän vanhoja, joten toisella tyypillä on aukko dokumentointi.
Itse kuorikoodi ei ole nykyään enää yhtä tehokas useista syistä, mutta on silti mielenkiintoista oppia uusia tekniikoita.
Toivottavasti se auttaa hieman 🙂 Terveisiä
Buen artículo, el viejo blog desdelinux ha vuelto a renacer =)
Kun sanot, että etäkuori ei ole niin tehokas, tarkoitat vastatoimia, jotka on suunniteltu lieventämään hyökkäyksiä, he kutsuvat sitä loukkaavaksi turvallisuudeksi.
Terveisiä ja jatka sitä
Kiitos paljon Franz 🙂 erittäin ystävällisiä sanoja, itse asiassa tarkoitin, että Shellcoding on tänään paljon monimutkaisempi kuin mitä näemme täällä. Meillä on pinonsuoja ASLR (random memory location generator), erilaiset toimenpiteet ja vastatoimenpiteet, jotka rajoittavat ohjelmaan ruiskutettavien opkoodien määrää, ja se on vasta alkua.
Terveisin,
Hei, teetkö toisen osan laajentamalla aihetta? Se on kiinnostavaa
Hei, aihe on todellakin varsin mielenkiintoinen, mutta otaksumme monimutkaisuuden tason erittäin korkeaksi, ja siihen liittyy todennäköisesti suuri määrä viestejä, joissa selitetään eri edellytyksiä toisen ymmärtämiseksi. Kirjoitan todennäköisesti siitä, mutta se ei ole seuraava viesti, haluan kirjoittaa muutaman aiheen ennen kuin jatkan tämän kanssa.
Terveisiä ja kiitoksia jakamisesta
Erittäin hyvä che! Annat upeita viestejä! Yksi kysymys: Aloitan tämän tietoturva-asian lukemalla kirjan nimeltä "Turvallisuuden varmistaminen kynätestauksella". Onko tätä kirjaa suositeltava? Kuinka ehdotat minun aloittavan kysymyksen näistä asioista?
Hei kaktus, se on koko universumi, joka käsittelee haavoittuvuuksia, ja toiset, totuuden toteamiseksi, se riippuu paljon siitä, mikä kiinnittää huomiosi ja tarpeisiisi, IT-johtajan ei tarvitse tietää samaa kuin kynätestaaja, Tai haavoittuvuustutkijalla tai oikeuslääketieteen analyytikolla, hätäpalautusryhmällä on hyvin erilaiset taidot. Jokainen heistä vaatii tietysti erilaista teknistä tietämystä, suosittelen, että aloitat etsimisen juuri siitä, mistä pidät, ja alat syödä kirjoja, artikkeleita ja muita, ja mikä tärkeintä, harjoittele kaikkea lukemaasi, vaikka se olisi vanhentunutta , siitä tulee loppujen lopuksi ero.
Terveisin,
Hei.
Paljon kiitoksia tämän aiheen selittämisestä sekä kommentoinnista, että lisätietojen saamiseksi meillä on "The Shellcoder's Handbook". Minulla on jo odottava lukeminen 😉