Introduktion
NX-skydd verkar bra; det stoppar virus döda i deras spår och eliminerar de irriterande buffertspill vi har hört så mycket om de senaste 15 åren. Tja, kanske inte. Det verkar faktiskt som att NX tillhandahåller flera lager av falsk säkerhet, särskilt eftersom den bara stannar någrabufferten svämmar över och om det stoppar några virus eller inte har ännu inte kunnat ses.
Även om AMD och Intel båda gillar att snurra sin nyaste NX/XD “Virus Protection” som en ny funktion på x86-tekniken, beter sig NX i verkligheten mer som en nödpatch för en lätt exploaterbar arkitektur. För att verkligen utforska hur NX gynnar oss, och var det ger en falsk känsla av säkerhet, måste vi förstå ett av scenarierna som det påstås förhindra.
Den enklaste förklaringen till ett buffertspill är när ett program exekverar minne som det inte hade för avsikt att göra. Vanligtvis görs detta när ett program skriver något i minnet som det inte har allokerats för; ibland skriver man över delar av samma program som redan finns i minnet.
Låt oss till exempel ta en titt på följande programkod:
int main(int argc, char **argv) { char line[512]; line[0] = 0; gets(line); ... return 0; }
Utan tvekan skrattar även de som bara har gått rudimentära programmeringskurser med monstrositeten ovan. Men den här koden är faktiskt nästan ordagrant kopierad från originalet UNIX fingeradprogram ca 1988. I UNIX (eller något annat operativsystem) laddas hela innehållet i programmet in i minnet som maskinkod. Ett enkelt, men inte nödvändigtvis korrekt, sätt att tänka på ovanstående kod är en array med flera hundra byte i minnet; 512 byte tilldelade för arrayen av tecken, linjepå rad 3 i koden.
När programmet börjar bläddra igenom koden i sin array (som egentligen kallas en stack), når det funktionen får(). får()en hemsk, gammal funktion, läser input och placerar den i linjearray. Men linje har bara tillräckligt med minne tilldelat för 512 tecken! Det skulle bara ta en illvillig användare några sekunder att inse att skriva mer än 512 tecken till fingerad programmet skulle resultera i förmågan att skriva data efter slutet av linje array. Och sedan linjefinns i en stack i minnet, skriver förbi slutet av linje börjar faktiskt skriva över kritiska delar av programmet! Om en användare skulle skriva 512 tecken till fingerad följt av maskinkod, kan användaren i princip kontrollera vilket attribut som helst för hela maskinen. Exemplet med fingeradovan blev den första riktiga internetmaskexploatet, en buffer-överflöde. Maskar som Nimda och Code Red fungerar exakt likadant som originalet fingeradmask, så tyvärr 16 år senare oförsiktig programmering ochexploateringsbar hårdvara är fortfarande skyldig.