Neinicijalizovane promenljive

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Osnovne informacije

Suština je ovde da se razume šta se dešava sa neinicijalizovanim promenljivama, jer one imaju vrednost koja je već bila na dodeljenoj memorijskoj lokaciji. Primer:

  • Funkcija 1: initializeVariable: Deklarišemo promenljivu x i dodelimo joj vrednost, recimo 0x1234. Ova akcija je kao rezervisanje mesta u memoriji i upisivanje određene vrednosti.
  • Funkcija 2: useUninitializedVariable: Ovde deklarišemo drugu promenljivu y, ali joj ne dodeljujemo vrednost. U C-u, neinicijalizovane promenljive se automatski ne postavljaju na nulu. Umesto toga, zadržavaju vrednost koja je poslednja bila smeštena na toj memorijskoj lokaciji.

Kada pokrenemo ove dve funkcije sekvencijalno:

  1. U initializeVariable, x dobija vrednost (0x1234), koja zauzima određenu memorijsku adresu.
  2. U useUninitializedVariable, y je deklarisana ali joj nije dodeljena vrednost, tako da zauzima memorijsko mesto odmah posle x. Zbog neinicijalizovanja y, ona na kraju “nasleđuje” vrednost iz iste memorijske lokacije koju je koristio x, jer je to poslednja vrednost koja je tamo bila.

Ovo ponašanje ilustruje ključni koncept u niskonivnom programiranju: upravljanje memorijom je ključno, i neinicijalizovane promenljive mogu dovesti do nepredvidivog ponašanja ili sigurnosnih ranjivosti, jer mogu nenamerno sadržati osetljive podatke preostale u memoriji.

Neinicijalizovane stack promenljive mogu predstavljati nekoliko sigurnosnih rizika, kao što su:

  • Data Leakage: Osetljive informacije kao što su lozinke, ključevi za enkripciju ili lični podaci mogu biti izloženi ako su smešteni u neinicijalizovanim promenljivama, što napadačima može omogućiti da potencijalno pročitaju te podatke.
  • Otkrivanje informacija: Sadržaj neinicijalizovanih promenljivih može otkriti detalje o rasporedu memorije programa ili internim operacijama, pomažući napadačima u razvoju ciljnih exploits.
  • Padovi i nestabilnost: Operacije koje uključuju neinicijalizovane promenljive mogu rezultirati nedefinisanim ponašanjem, što dovodi do pada programa ili nepredvidivih rezultata.
  • Arbitrary Code Execution: U određenim scenarijima, napadači bi mogli iskoristiti ove ranjivosti da promene tok izvršavanja programa, omogućavajući im da izvrše arbitrary code, što može uključivati remote code execution pretnje.

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:

  • initializeAndPrint Function: Ova funkcija deklariše celo-brojnu promenljivu initializedVar, dodeljuje joj vrednost 100 i zatim ispisuje i memorijsku adresu i vrednost promenljive. Ovaj korak je jednostavan i pokazuje kako se ponaša inicijalizovana promenljiva.
  • demonstrateUninitializedVar Function: U ovoj funkciji deklarišemo celo-brojnu promenljivu uninitializedVar bez inicijalizacije. Kada pokušamo da ispišemo njenu vrednost, izlaz može prikazati nasumičan broj. Taj broj predstavlja podatke koji su prethodno bili na toj lokaciji u memoriji. U zavisnosti od okruženja i kompajlera, stvarni izlaz može varirati, i ponekad, iz bezbednosnih razloga, neki kompajleri mogu automatski inicijalizovati promenljive na nulu, mada se na to ne treba oslanjati.
  • main Function: Funkcija main poziva obe prethodne funkcije redom, demonstrirajući kontrast između inicijalizovane promenljive i neinicijalizovane.

Praktični obrasci eksploatacije (2024–2025)

The classic “read-before-write” bug remains relevant because modern mitigations (ASLR, canaries) often rely on secrecy. Typical attack surfaces:

  • Partially initialized structs copied to userland: Kernel or drivers frequently memset only a length field and then copy_to_user(&u, &local_struct, sizeof(local_struct)). Padding and unused fields leak stack canary halves, saved frame pointers or kernel pointers. If the struct contains a function pointer, leaving it uninitialized may also allow controlled overwrite when later reused.
  • Uninitialized stack buffers reused as indexes/lengths: An uninitialized size_t len; used to bound read(fd, buf, len) may give attackers out-of-bounds reads/writes or allow bypassing size checks when the stack slot still contains a large value from a prior call.
  • Compiler-added padding: Čak i kada su pojedinačni članovi inicijalizovani, implicitni padding bajtovi između njih nisu. Kopiranje celog struct-a u userland može leak padding koji često sadrži prethodni sadržaj stacka (canaries, pointers).
  • ROP/Canary disclosure: Ako funkcija kopira lokalni struct na stdout radi debugovanja, uninitialized padding može otkriti stack canary, omogućavajući naknadnu stack overflow eksploataciju bez brute-force.

Minimal PoC pattern to detect such issues during review:

struct msg {
char data[0x20];
uint32_t len;
};

ssize_t handler(int fd) {
struct msg m;              // never fully initialized
m.len = read(fd, m.data, sizeof(m.data));
// later debug helper
write(1, &m, sizeof(m));   // leaks padding + stale stack
return m.len;
}

Mitigacije & opcije kompajlera (imajte na umu prilikom zaobilaženja)

  • Clang/GCC auto-init: Recent toolchains expose -ftrivial-auto-var-init=zero or -ftrivial-auto-var-init=pattern, filling every automatic (stack) variable at function entry with zeros or a poison pattern (0xAA / 0xFE). Ovo zatvara većinu uninitialized-stack info leaks i otežava eksploataciju pretvarajući tajne u poznate vrednosti.
  • Linux kernel hardening: Kerneli kompajlirani sa CONFIG_INIT_STACK_ALL ili novijim CONFIG_INIT_STACK_ALL_PATTERN nuliraju/pattern-inicijalizuju svaki stack slot na ulazu funkcije, brišući canaries/pointers koji bi inače leak-ovali. Potražite distro-e koji isporučuju Clang-built kernel-e sa ovim opcijama uključenim (uobičajeno u 6.8+ hardening konfiguracijama).
  • Opt-out attributes: Clang now allows __attribute__((uninitialized)) on specific locals/structs to keep performance-critical areas uninitialized even when global auto-init is enabled. Pažljivo pregledajte takve anotacije—često označavaju namerno attack surface za side channels.

Sa stanovišta napadača, poznavanje da li je binarni fajl izgrađen sa ovim flag-ovima određuje da li su stack-leak primitives izvodljive ili morate pivot-ovati na heap/data-section disclosures.

Finding uninitialized-stack bugs quickly

  • Compiler diagnostics: Kompajlirajte sa -Wall -Wextra -Wuninitialized (GCC/Clang). Za C++ kod, clang-tidy -checks=cppcoreguidelines-init-variables će auto-fix-ovati mnoge slučajeve u zero-init i korisno je za pronalaženje propuštenih lokalnih promenljivih tokom audita.
  • Dynamic tools: -fsanitize=memory (MSan) in Clang or Valgrind’s --track-origins=yes pouzdano flag-uju čitanja neinicijalizovanih stack bajtova tokom fuzz-ovanja. Instrumentujte test harness-e ovim alatima da izvučete suptilne padding leaks.
  • Grepping patterns: U review-ima tražite copy_to_user / write pozive koji šalju cele strukture, ili memcpy/send stack podataka gde je samo deo strukture postavljen. Obratite posebnu pažnju na error path-ove gde je inicijalizacija preskočena.

ARM64 Example

Ovo se uopšte ne menja na ARM64 jer se lokalne promenljive takođe smeštaju na stack; možete check this example gde je ovo prikazano.

References

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks