hacktricks/binary-exploitation/stack-overflow/uninitialized-variables.md

5.7 KiB

Neinicijalizovane promenljive

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Osnovne informacije

Osnovna ideja ovde je razumeti šta se dešava sa neinicijalizovanim promenljivima jer će imati vrednost koja je već bila u dodeljenoj memoriji njima. Primer:

  • Funkcija 1: initializeVariable: Deklarisali smo promenljivu x i dodelili joj vrednost, recimo 0x1234. Ova akcija je slična rezervisanju mesta u memoriji i postavljanju određene vrednosti u nju.
  • Funkcija 2: useUninitializedVariable: Ovde deklarišemo drugu promenljivu y ali joj ne dodeljujemo nikakvu vrednost. U programskom jeziku C, neinicijalizovane promenljive se ne postavljaju automatski na nulu. Umesto toga, zadržavaju vrednost koja je poslednja bila sačuvana na njihovoj memorijskoj lokaciji.

Kada pokrenemo ove dve funkcije sekvencijalno:

  1. U initializeVariable, x je dodeljena vrednost (0x1234), koja zauzima određenu memorijsku adresu.
  2. U useUninitializedVariable, y je deklarisana ali joj nije dodeljena vrednost, pa zauzima memorijsko mesto odmah posle x. Zbog nedostatka inicijalizacije y, završava "nasleđujući" vrednost sa iste memorijske lokacije koju koristi x, jer je to poslednja vrednost koja je bila tamo.

Ovo ponašanje ilustruje ključni koncept u programiranju na niskom nivou: Upravljanje memorijom je ključno, a neinicijalizovane promenljive mogu dovesti do nepredvidivog ponašanja ili sigurnosnih ranjivosti, jer mogu nenamerno držati osetljive podatke ostavljene u memoriji.

Neinicijalizovane promenljive na steku mogu predstavljati nekoliko sigurnosnih rizika kao što su:

  • Curenje podataka: Osetljive informacije poput lozinki, ključeva za šifrovanje ili ličnih detalja mogu biti izložene ako se čuvaju u neinicijalizovanim promenljivima, omogućavajući napadačima da potencijalno pročitaju ove podatke.
  • Otkrivanje informacija: Sadržaj neinicijalizovanih promenljivih može otkriti detalje o memorijskoj strukturi programa ili internim operacijama, pomažući napadačima u razvoju ciljanih eksploatacija.
  • Padovi i nestabilnost: Operacije koje uključuju neinicijalizovane promenljive mogu rezultirati nedefinisanim ponašanjem, što dovodi do rušenja programa ili nepredvidivih ishoda.
  • Izvršavanje proizvoljnog koda: U određenim scenarijima, napadači bi mogli iskoristiti ove ranjivosti da promene tok izvršavanja programa, omogućavajući im da izvrše proizvoljan kod, što može uključivati pretnje izvršavanjem udaljenog koda.

Primer

#include <stdio.h>

// Function to initialize and print a variable
void initializeAndPrint() {
int initializedVar = 100; // Initialize the variable
printf("Initialized Variable:\n");
printf("Address: %p, Value: %d\n\n", (void*)&initializedVar, initializedVar);
}

// Function to demonstrate the behavior of an uninitialized variable
void demonstrateUninitializedVar() {
int uninitializedVar; // Declare but do not initialize
printf("Uninitialized Variable:\n");
printf("Address: %p, Value: %d\n\n", (void*)&uninitializedVar, uninitializedVar);
}

int main() {
printf("Demonstrating Initialized vs. Uninitialized Variables in C\n\n");

// First, call the function that initializes its variable
initializeAndPrint();

// Then, call the function that has an uninitialized variable
demonstrateUninitializedVar();

return 0;
}

Kako ovo funkcioniše:

  • Funkcija initializeAndPrint: Ova funkcija deklariše celobrojnu promenljivu initializedVar, dodeljuje joj vrednost 100, a zatim štampa kako memorijsku adresu tako i vrednost promenljive. Ovaj korak je jednostavan i pokazuje kako se ponaša inicijalizovana promenljiva.
  • Funkcija demonstrateUninitializedVar: U ovoj funkciji deklarišemo celobrojnu promenljivu uninitializedVar bez inicijalizacije. Kada pokušamo da štampamo njenu vrednost, izlaz može pokazati nasumičan broj. Taj broj predstavlja bilo koje podatke koji su prethodno bili na toj memorijskoj lokaciji. Zavisno od okruženja i kompajlera, stvarni izlaz može varirati, a ponekad, radi bezbednosti, neki kompajleri automatski mogu inicijalizovati promenljive na nulu, iako se na to ne bi trebalo oslanjati.
  • Funkcija main: Funkcija main poziva obe prethodne funkcije jednu za drugom, demonstrirajući kontrast između inicijalizovane i neinicijalizovane promenljive.

Primer za ARM64

Ovo se u potpunosti ne menja u ARM64 jer se lokalne promenljive takođe upravljaju na steku, možete proveriti ovaj primer gde je to prikazano.