Puskurin ylivuoto

Puskurin ylivuotoja ( Englanti puskurin ylivuoto ), tai - erityisesti - myös pino ylivuotoja (Englanti , pino ylivuotoja ' ) kutsutaan, yksi yleisimmistä heikkouksia nykyisessä ohjelmisto , joka muun muassa .. voidaan hyödyntää Internetin kautta . Jos puskurin ylivuoto johtuu ohjelman virheistä, liian suuria määriä dataa kirjoitetaan tätä tarkoitusta varten varatulle muistialueelle - puskurille tai pinolle  - joka korvaa muistipaikat kohdemuistialueen jälkeen.

Ei-toivottu kirjoittaminen puskurin ulkopuolelle ei voi johtua vain liiallisesta datamäärästä, vaan myös kohdeosoitteen ylivuotosta (tai muusta virheellisestä laskutoimituksesta), joka osoittaa, mihin datatietue on kirjoitettava puskuriin. Tällöin jota , osoitin ylivuoto " (pois Englanti osoitin , sillä ' osoitin ') puhutaan.

Puskurin ylivuotojen vaara

Puskurin ylivuoto voi aiheuttaa kyseisen ohjelman kaatumisen, tietojen vioittumisen tai vahingon ohjelman ajonaikaisen ympäristön tietorakenteille . Kanssa Jälkimmäisessä paluu osoite alirutiini voidaan korvata millä tahansa tietoja, jolloin hyökkääjä voi suorittaa mitään komentoja kanssa oikeudet prosessin alttiita puskurin ylivuodon lähettämällä tahansa konekielelle . Tämän koodin tarkoituksena on yleensä antaa hyökkääjälle helpompi pääsy järjestelmään, jotta hän voi sitten käyttää järjestelmää omiin tarkoituksiinsa. Puskurin ylivuotoja yhteisessä palvelimessa - ja asiakasohjelmistoja käyttävät myös hyödynnetyt Internet-matot .

Erityisen suosittu kohde Unix- järjestelmissä on pääkäyttö , joka antaa hyökkääjälle kaikki käyttöoikeudet. Tämä ei kuitenkaan tarkoita, kuten usein väärin ymmärretään, että puskurin ylivuoto, joka "vain" johtaa "normaalin" käyttäjän oikeuksiin, ei ole vaarallinen. Halutun juurihakemiston saavuttaminen on usein paljon helpompaa, jos sinulla on jo käyttöoikeudet ( etuoikeuden eskalointi ).

Puskurin ylivuotohyökkäykset ovat tärkeä asia tietoturvassa ja verkkoturvallisuudessa . Niitä voidaan yrittää paitsi minkä tahansa tyyppisessä verkossa myös paikallisesti järjestelmässä. Yleensä ne voidaan ratkaista vain virheenkorjauksilla ( korjaustiedostoilla ), jotka valmistaja tarjoaa lyhyellä varoitusajalla .

Ohjelmoinnin laiminlyönnin lisäksi puskurin ylivuotoja mahdollistavat ensisijaisesti Von Neumann -arkkitehtuuriin perustuvat tietokonejärjestelmät, joiden mukaan data ja ohjelma ovat samassa muistissa. Laitteiden läheisyyden vuoksi ne ovat vain koottujen tai koottujen ohjelmointikielien ongelma. Tulkin virheiden lisäksi tulkitut kielet eivät yleensä ole alttiita, koska tietojen muistialueet ovat aina tulkin täydellisessä hallinnassa.

Kun Suojattu tila , joka on otettu käyttöön 80286 , ohjelma, data ja pino muistia voidaan fyysisesti erottaa toisistaan , jonka segmentoimalla lineaarinen muisti . Pääsysuojaus tapahtuu prosessorin muistinhallintayksikön kautta . Käyttöjärjestelmän on vain varmistettava, että muistia ei ole käytettävissä enemmän kuin lineaarinen osoiteavaruus. OS / 2 oli ainoa laajasti käytetty käyttöjärjestelmä, joka käytti muistin segmentointia.

Ohjelmointikielet

Tärkein syy puskurin ylivuotoja on käyttää ohjelmointikieltä , jotka eivät tarjoa mahdollisuutta automaattisesti seuranta rajat muistin alueilla , jotta estetään muistiin alueille ylittymisen. Tämä sisältää erityisesti C- kielen , jossa painotetaan pääasiassa suorituskykyä (ja alun perin kääntäjän yksinkertaisuutta) ja luopuu valvonnasta, sekä C-kehityksen C ++ . Tässä ohjelmoija on joskus pakko tuottaa vastaava koodi käsin, usein tahallaan tai huolimattomasti tekemällä sitä ilman. Tarkastus toteutetaan usein väärin, koska näitä ohjelman osia ei yleensä testata tai testata riittämättömästi ohjelmatestien aikana. Lisäksi monimutkainen kielivalikoima (C ++: n tapauksessa) ja vakiokirjasto tarjoavat suuren määrän virhealttiita rakenteita, joille tuskin on vaihtoehtoa monissa tapauksissa.

Usein käytetty ohjelmointikieli C ++ tarjoaa vain rajalliset mahdollisuudet kenttärajojen automaattiseen tarkistamiseen. C-ohjelmointikielen jatkokehityksenä se ottaa suurimman osan C-ominaisuuksista, mutta puskurin ylivuotojen riski nykyaikaisia ​​kieliresursseja (mukaan lukien automaattinen muistinhallinta) käytettäessä voidaan suurelta osin välttää. Tavanomaisuuden, olemassa olevan C-koodin kanssa yhteensopivuuden vuoksi, järjestelmäkutsut C-sopimuksessa ja suorituskyvyn vuoksi näitä vaihtoehtoja ei aina käytetä. Toisin kuin Pascalin tai Adan kaltaiset kielet , ajonaikaiset tarkistukset eivät ole osa kieltä, mutta ne voidaan jälkiasentaa joissakin käyttötapauksissa (esim. Älyosoittimilla ).

Koska useimmat ohjelmointikielet määrittelevät myös standardikirjastot, kielen valinta tarkoittaa yleensä myös vastaavien vakiokirjastojen käyttöä. C: n ja C ++: n tapauksessa vakiokirjasto sisältää useita vaarallisia toimintoja, joista jotkut eivät salli turvallista käyttöä ollenkaan, ja joissain ei ole vaihtoehtoja.

Ohjelmointikielitasolla puskurin ylivuotojen riskiä voidaan vähentää tai poistaa käyttämällä ohjelmointikieliä, jotka ovat käsitteellisesti turvallisempia kuin C ++ tai C. Paljon pienempi riski on esimerkiksi Pascal-perheen Modula , Object Pascal tai Ada ohjelmointikielissä .

Puskurin ylivuoto, esimerkiksi Java- ohjelmointikielellä, on melkein mahdotonta, koska suoritusta valvotaan tavukoodissa . Mutta Java-ohjelmassa on myös puskurin ylivuotoja, joiden syy on ajonaikaisessa järjestelmässä ja joka vaikuttaa useisiin JRE- versioihin. Toisaalta Java-ajonaikainen ympäristö heittää yhden, java.lang.StackOverflowErrorjos metodikutsupino täynnä virheellisen loputtoman rekursio johtuu. Tämä on sovellusohjelmoijan, ei ajonaikaisen järjestelmän, looginen ohjelmointivirhe.

Suorittimet ja ohjelmointityyli

Muut C: n ja C ++: n erityispiirteet ja yleisimmin käytetyt prosessorit tekevät puskurin ylivuotoista todennäköisiä. Näiden kielten ohjelmat koostuvat osittain alaohjelmista . Näillä on paikallisia muuttujia.

Nykyaikaisissa prosessoreissa on tavallista laittaa aliohjelman ja sen paikallisten muuttujien paluuosoite pinolle kutsutulle alueelle . Kun aliohjelma kutsutaan, ensin paluuosoite ja sitten paikalliset muuttujat sijoitetaan pinoon. Nykyaikaisilla prosessoreilla, kuten Intel Pentium , pinoa hallitaan sisäänrakennetuilla prosessorikomennoilla ja se kasvaa alaspäin . Jos paikallisissa muuttujissa käytetään kenttiä tai merkkijonoja, ne kuvataan yleensä edellä . Jos kentän rajaa ei ole tarkistettu, pinon paluuosoitteeseen pääsee ylittämällä pellon ja tarvittaessa muokkaamalla sitä tarkoituksella.

Seuraava C-osan ohjelmaosa, jota käytetään usein samankaltaisessa muodossa, osoittaa tällaisen puskurin ylivuotoa:

void input_line()
{
    char line[1000];
    if (gets(line))     // gets erhält Zeiger auf das Array, keine Längeninformation
        puts(line);     // puts schreibt den Inhalt von line nach stdout
}

Prosessoreissa, jotka kuvaavat pinon alaspäin, se näyttää tältä ennen kuin kutsu saa (C: n vakiokirjaston toiminto) (jos jätetään huomioimatta mahdollisesti olemassa oleva perusosoitin):

Palautusosoite
1000. merkki
... ...
3. merkki
2. merkki
1. merkki ← Pino-osoitin
Pino kasvaa alaspäin, muuttuja korvataan ylöspäin

get lukee rivin syötteestä ja kirjoittaa merkit riviltä [0] pinoon. Se ei tarkista linjan pituutta. C: n semantiikan mukaan saa vain muistiosoitteen osoittimena, mutta ei tietoa käytettävissä olevasta pituudesta. Jos syötät nyt 1004 merkkiä, viimeiset 4 tavua korvaavat palautusosoitteen (olettaen, että osoite on 4 tavua), joka voidaan ohjata pinon sisällä olevaan ohjelmaosioon. Tarvittaessa voit kirjoittaa sopivan ohjelman 1000 ensimmäiseen merkkiin .

00@45eA/%A@4 ... ... ... ... ... ... ... ... ... ... ... ... ... ... 0A&%
Syöttö, kirjoitetaan pinoon hakemuksella (1004 merkkiä)
muokattu palautusosoite
rivi, 1000. merkki
...
rivi, 5. merkki kolmas tavu koodissa
rivi, 4. merkki toinen tavu koodissa
rivi, 3. merkki Paluuosoitteen määränpää, ohjelmakoodin aloitus
rivi, 2. merkki
rivi, 1. merkki ← Pino-osoitin
Paluuosoitteen ja ohjelmakoodin korvaaminen pinossa

Jos ohjelmalla on korkeammat oikeudet kuin käyttäjällä, hän voi käyttää puskurin ylivuotoa saadakseen nämä oikeudet erityisellä syötöllä.

Vastatoimenpiteet

Ohjelman luominen

Erittäin kestävä vastatoimenpide on tyyppiturvallisten ohjelmointikielien ja työkalujen, kuten Java tai C # , käyttö, joissa kääntäjä tarkistaa konekielelle kääntäjän määritettyjen muistialueiden noudattamisen , mutta sitä seurataan vastaavalla ohjelmalla koodi viimeistään ajon aikana . Tässä on olennaista, että osoitinmuuttujia voidaan muuttaa vain tiukkojen, rajoittavien sääntöjen mukaisesti, ja tässä yhteydessä on myös hyödyllistä, jos vain ajonaikainen järjestelmä suorittaa automaattisen roskakorin.

Kun luot ohjelmia, sinun on siis tarkistettava kaikki kentän rajat. Vanhentuneiden, tyyppiturvallisten ohjelmointikielien tapauksessa tämä on ohjelmoijan vastuulla. Mieluiten kannattaa kuitenkin harkita ohjelmointikielien käyttöä, jotka seuraavat automaattisesti kentän rajoja, mutta tämä ei ole aina mahdollista. C ++: a käytettäessä C-tyylisten kenttien käyttöä tulisi välttää mahdollisimman paljon.

void input_line()
{
    char line[1000];
    if (fgets(line, sizeof(line), stdin))   // fgets überprüft die Länge
        puts(line);  // puts schreibt den Inhalt von line nach stdout
}
Vastatoimenpide: fgets tarkistaa syötteen pituuden

Tarkistetaan ohjelmakoodi

Erityiset tarkistustyökalut mahdollistavat koodin analysoinnin ja mahdollisten heikkouksien löytämisen. Kentän rajojen tarkistuskoodi voi kuitenkin olla buginen, jota ei usein testata.

Kääntäjän tuki

Erittäin laaja valikoima olemassa olevia ohjelmia on saatavana C- ja C ++ -järjestelmissä. Nykyaikaiset kääntäjät , kuten GNU C-kääntäjän uudet versiot, mahdollistavat koodin luontitoiminnon aktivoimisen käännöksen aikana.

Suunnittelunsa vuoksi kielet, kuten C, eivät aina salli kentän rajojen tarkistamista (esimerkki: saa ). Kääntäjien on mentävä muilla tavoilla: He lisäävät tilaa satunnaisluvulle (kutsutaan myös "kanarialle") paluuosoitteen ja paikallisten muuttujien väliin. Tämä numero määritetään, kun ohjelma käynnistetään, jolloin se ottaa eri arvot joka kerta. Jokaisen aliohjelmakutsun yhteydessä satunnaisluku kirjoitetaan sille varatulle alueelle. Kääntäjä luo tarvittavan koodin automaattisesti. Ennen kuin poistut ohjelmasta paluuosoitteen kautta, kääntäjä lisää koodin, joka tarkistaa satunnaisluvun suunnitellulle arvolle. Jos sitä muutettiin, paluuosoitetta ei myöskään voida luottaa. Ohjelma keskeytetään vastaavalla viestillä.

Palautusosoite
Satunnaislukueste
rivi, 1000. merkki
...
rivi, 3. merkki
rivi, 2. merkki
rivi, 1. merkki ← Pino-osoitin
Vastatoimenpide: satunnaislukueste

Lisäksi jotkut kääntäjät voidaan myös saada aikaan kopio palautusosoitteesta paikallisten kenttien alapuolella, kun aliohjelma kutsutaan . Tätä kopiota käytetään palautettaessa, mikä tekee puskurin ylivuotojen hyödyntämisen paljon vaikeammaksi:

Palautusosoite
rivi, 1000. merkki
...
rivi, 3. merkki
rivi, 2. merkki
rivi, 1. merkki
Kopio palautusosoitteesta ← Pino-osoitin
Vastatoimenpide: Kopio palautusosoitteesta

Kääntäjä ja kääntäjälaajennukset

Esimerkiksi GNU-kääntäjäkokoelmalle on olemassa kaksi yleistä laajennusta, jotka toteuttavat yllä kuvattuja toimenpiteitä:

Kasan ylivuoto

Kasaan ylivuoto on puskurin ylivuoto, joka esiintyy kasaan . Kasan muisti varataan, kun ohjelmat pyytävät dynaamista muistia, esimerkiksi malloc (): n tai uuden operaattorin kautta C ++: ssa . Jos tiedot kirjoitetaan kasan puskuriin tarkistamatta pituutta ja jos datan määrä on suurempi kuin puskurin koko, data kirjoitetaan puskurin pään yli ja tapahtuu muistin ylivuoto.

By kasaan ylivuodot koodin voidaan saada korvaamalla osoittimia toimintoja suoritetaan tietokoneen varsinkin kun keko on suoritettavissa. Esimerkiksi FreeBSD: llä on kasasuojaus, mutta tämä ei ole mahdollista täällä. Niitä voi esiintyä vain sellaisilla ohjelmointikielillä , joilla ei ole pituustarkistusta puskuria käytettäessä. C , C ++ tai assembler ovat haavoittuvia, Java tai Perl eivät.

Esimerkiksi 23. kesäkuuta 2015 Adobe ilmoitti, että tällainen puskurin ylivuoto voi aiheuttaa haitallisen koodin suorittamisen järjestelmissä ja siten hallita järjestelmää, johon Flash Player on asennettu.

esimerkki

#define BUFSIZE 128

char * copy_string(const char *s)
{
    char * buf = malloc(BUFSIZE); // Annahme: Längere Strings kommen niemals vor

    if (buf)
        strcpy(buf, s); // Heap-Überlauf, falls strlen(s) > 127

    return buf;
}

Koska strcpy () ei tarkista lähteen ja kohteen kokoja, vaan odottaa lähteeksi nollapäätetyn ('\ 0') muistialueen, seuraava versio on myös vaarallinen (se ei kuitenkaan ylitä "bufia") , mutta mahdollisesti "s": lle osoitetun muistialueen yläpuolella).

char * buf;

buf = malloc(1 + strlen(s)); // Plus 1 wegen des terminierenden NUL-Zeichens
if (buf)
    strcpy(buf, s);

Strncpy-komento puolestaan ​​kopioi enintään n merkkiä lähteestä määränpäähän ja toimii siten, jos s on null-päättynyt tai suurempi kuin BUFSIZE.

char *buf;

if ((buf = malloc(BUFSIZE)) != NULL) { // Überprüfung des Zeigers.
    strncpy(buf, s, BUFSIZE - 1);
    buf[BUFSIZE - 1] = '\0';  // Nachteil: Die Zeichenkette muss manuell terminiert werden.
}
return buf;

Jotkut käyttöjärjestelmät, esim. B. OpenBSD , tarjoa funktio strlcpy , joka puolestaan ​​varmistaa, että kohdemerkkijono päättyy nollaan, ja yksinkertaistaa katkaistun kohdejonon tunnistamista.

Katso myös

kirjallisuus

nettilinkit

Yksittäiset todisteet

  1. Haavoittuvuus Sun Java Runtime Environment - LinuxCommunity -ohjelmassa 17. tammikuuta 2007
  2. Sun Java JRE jopa 1.5.x GIF Image Handler -puskurin ylivuoto - vuldb.com , 22. tammikuuta 2007 (viimeisin muutos 7. heinäkuuta 2015)
  3. Mikä on pino? . 2. kesäkuuta 2012.
  4. Dennis Schirrmacherin: Adobe: Emergency päivityksen Flash Player. Julkaisussa: Heise Security. Heise online , 24. kesäkuuta 2015, luettu 29. kesäkuuta 2015 .
  5. Adobe Flash Playerin tietoturvapäivitykset - CVE-numero: CVE-2015-3113. Julkaisussa: Adobe Security Bulletin. Adobe Inc. , 23. kesäkuuta 2015, luettu 29. kesäkuuta 2015 .