I den här självstudien kommer vi att prata om buffertöverflöde (Buffer-överflöde), ett fel som har funnits under en längre tid, uppstår när data som kopieras i ett minnesområde (som har reserverats tidigare) inte kontrolleras korrekt, kan det vara att programmet fungerar korrekt om användaren infogar data med en tillräcklig storlek, men om vi reserverar minne för 15 tecken och användaren sätter in 20, kommer det att påverka ett annat minnesområde, som kan reserveras eller inte.
Detta kan få vårt program att hänga, men det kan också vara mycket värre, en användare med onda avsikter kan dra nytta av detta fel och påverka programmets funktion eller köra godtycklig kod på en dator (normalt öppnar den koden en tolkning av kommandon ). Även om programmet körs med förhöjda privilegier har vi en allvarlig säkerhetsbrist. En annan attack som kan ändra driften av en applikation eller injicera kod är XSS.
NoteraDe avrättningar som du kommer att se under denna handledning har utförts i 32-bitars Ubuntu 16.04-operativsystemet.
Låt oss se a Enkelt exempel på C -kod som är sårbar för denna attack, när programmet startas måste vi skicka en parameter, applikationen räkna med att få en sträng som inte är längre än 15 tecken, om det är den förväntade strängen kommer det att bli en lyckad åtkomst, om inte kommer det att "nekas". Koden är enligt nedan:
#include #include #define password "Test" void test (char * str) {char buffer [15]; int n = 0; strcpy (buffert, str); if (strcmp (buffert, lösenord) == 0) {n = 1; } om (n) {printf ("Framgång \ n"); utgång (0); } annat {printf ("Åtkomst nekad \ n"); }} int main (int argc, char * argv []) {if (argc <2) {printf ("Appen kräver en parameter \ n"); utgång (-1); } test (argv [1]); }Programmet är uppkallat efter överflöd. c, och för att sammanställa följande har använts:
gcc overflow.c -o overflow -fno -stack -protectorDen sista delen: -fno-stack-protector Den används så att kompilatorn inte sätter skydd och vi kan visa exemplet. Om användaren anger rätt data, som är en sträng med högst 15 tecken, fungerar programmet bra, om vi anger ett felaktigt "lösenord" kommer det att visa oss Tillträde beviljas ej, och om vi sätter "Testa”Kommer att sätta oss Framgång. Låt oss se en inspelning som kör programmet 2 gånger, en gång med fel åtkomst och en annan med rätt sträng:
Vi ser att allt fungerar korrekt. Men vad händer om vi sätter in en övre sträng, låt oss se vad som händer:
Vi har lanserat programmet med 20 bokstäver A, och visar oss Framgång. I den här applikationen har vi ingenting, vi lämnar helt enkelt programmet, men vi har nått ett begränsat område utan att veta lösenordet. Om vi ersätter följande funktion:
strcpy (buffert, str);Med följande:
strncpy (buffert, str, 15);Y vi kör koden med 20 bokstäver A, har vi följande utdata:
Du kan också se att vi använder oss av strcmp, istället borde vi använda strncmp, så vi kontrollerar också storleken. Vi har kontrollerat att endast högst 15 tecken kan kopieras, så det påverkar inte vårt program om de infogar fler. Om efter att meddelandet visats Framgång vi kör ett systemkommando (i det här fallet vem är jag), får vi informationen:
Ovanstående är vi inte root, men om vi kör det med sudo får vi följande:
Det enda vi har lagt till är en rad i koden som vi såg ovan, under kodraden:
printf ("Framgång \ n");Vi har lagt:
system ("whoami");För att förstå lite vad som har hänt, kommer jag att ändra programmet för att visa de 2 variabler som vi har (buffert Y n) oavsett om det är korrekt eller inte, och nedanför är utmatningen, det första vi sätter in en sträng som kommer att behandlas som korrekt (“Testa”), Då en felaktig som inte överskrider längden och slutligen 20 bokstäver A:
Vi ser att i den första utförandet är det värt 1 Variabeln n, eftersom kedjan som passerat är den rätta, i den andra är den värd 0, eftersom det är fel, men i det sista är det värt 1094795585, vilket gör att du hoppar över villkoret som vi sätter om (n), det kommer att vara sant så länge n skiljer sig från 0. Det är inte ett bra skick, även om det inte skulle behöva misslyckas om resten av koden var korrekt. Om vi lägger 16 bokstäver A som parameter ser vi att variabelns värde n det är 65:
Om vi tittar på ASCII -koden, numret 65 motsvarar bokstaven TILL, vi har sett att minnet av variabeln n av misstag har berörts av oss, den extra bokstaven som vi har skickat som parameter har gått till variabeln n. Vi skulle ha minnet enligt följande:
Om vi går längre än tecken kan det vara så att det skickar ett meddelande om överträdelse av segmentet (om vi eliminerar avsluta (0) vad har vi i om (n)), kan vi se det i följande bild:
Denna varning beror på ett försök att komma åt ett minnesområde som ligger utanför gränserna för det som operativsystemet tilldelat applikationen. Om vi sammanställde exemplet enligt följande:
gcc overflow.c -o overflow -stack -protectorEller bara ta bort -fno-stack-protector Från den sammanställning som vi såg första gången, och vi kör koden med överflöd, får vi följande resultat:
Ett extra skydd som gcc ger oss.
NoteraOm vi ville köra en kod (skalkod) vi skulle behöva skriva över returadressen med den för vår skalkod, det är något mer komplext än exemplet som ses i självstudien och kräver därför mer arbete.
Om någon lyckas dra nytta av denna sårbarhet kan det orsaka mycket skada. Undvik att ha den här typen av fel och att en skadlig användare kan dra nytta av detta är mycket enkelt, programmera korrekt, du måste känna till programmeringsspråket som används, veta vilka funktioner du ska använda och vad du inte ska använda, testa programmet Tja, inte bara med korrekta data, det måste också fungera korrekt när vi hanterar oförutsedda data.
Andra attacker som du kan granska och vara medvetna om så att de inte påverkar dig eller minimerar deras risker är: DoS och Brute Force. Och glöm inte att kontrollera CVE -sidan med avseende på sårbarheter.
Gillade du och hjälpte denna handledning?Du kan belöna författaren genom att trycka på den här knappen för att ge honom en positiv poäng