Uninitialized Variables

Impara e pratica il Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica il Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Supporta HackTricks

Informazioni di Base

L'idea principale qui è comprendere cosa succede con le variabili non inizializzate poiché avranno il valore che era già nella memoria a loro assegnata. Esempio:

  • Funzione 1: initializeVariable: Dichiaramo una variabile x e le assegniamo un valore, diciamo 0x1234. Questa azione è simile a riservare un posto in memoria e mettere un valore specifico in esso.

  • Funzione 2: useUninitializedVariable: Qui, dichiariamo un'altra variabile y ma non le assegniamo alcun valore. In C, le variabili non inizializzate non vengono automaticamente impostate a zero. Invece, mantengono qualunque valore fosse stato memorizzato per ultimo nella loro posizione di memoria.

Quando eseguiamo queste due funzioni sequentially:

  1. In initializeVariable, x viene assegnato un valore (0x1234), che occupa un indirizzo di memoria specifico.

  2. In useUninitializedVariable, y è dichiarato ma non assegnato un valore, quindi occupa il posto di memoria subito dopo x. A causa della mancata inizializzazione di y, finisce per "ereditarne" il valore dalla stessa posizione di memoria utilizzata da x, perché quello è l'ultimo valore che c'era.

Questo comportamento illustra un concetto chiave nella programmazione a basso livello: La gestione della memoria è cruciale, e le variabili non inizializzate possono portare a comportamenti imprevedibili o vulnerabilità di sicurezza, poiché potrebbero contenere involontariamente dati sensibili lasciati in memoria.

Le variabili di stack non inizializzate potrebbero presentare diversi rischi per la sicurezza come:

  • Data Leakage: Informazioni sensibili come password, chiavi di crittografia o dettagli personali possono essere esposte se memorizzate in variabili non inizializzate, consentendo agli attaccanti di potenzialmente leggere questi dati.

  • Information Disclosure: I contenuti delle variabili non inizializzate potrebbero rivelare dettagli sulla disposizione della memoria del programma o sulle operazioni interne, aiutando gli attaccanti a sviluppare exploit mirati.

  • Crashes and Instability: Operazioni che coinvolgono variabili non inizializzate possono portare a comportamenti indefiniti, causando crash del programma o risultati imprevedibili.

  • Arbitrary Code Execution: In determinate situazioni, gli attaccanti potrebbero sfruttare queste vulnerabilità per alterare il flusso di esecuzione del programma, consentendo loro di eseguire codice arbitrario, che potrebbe includere minacce di esecuzione di codice remoto.

Esempio

#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;
}

Come Funziona:

  • Funzione initializeAndPrint: Questa funzione dichiara una variabile intera initializedVar, le assegna il valore 100 e poi stampa sia l'indirizzo di memoria che il valore della variabile. Questo passaggio è semplice e mostra come si comporta una variabile inizializzata.

  • Funzione demonstrateUninitializedVar: In questa funzione, dichiariamo una variabile intera uninitializedVar senza inizializzarla. Quando tentiamo di stampare il suo valore, l'output potrebbe mostrare un numero casuale. Questo numero rappresenta i dati che erano precedentemente in quella posizione di memoria. A seconda dell'ambiente e del compilatore, l'output effettivo può variare e, a volte, per sicurezza, alcuni compilatori potrebbero inizializzare automaticamente le variabili a zero, anche se non ci si dovrebbe fare affidamento.

  • Funzione main: La funzione main chiama entrambe le funzioni sopra in sequenza, dimostrando il contrasto tra una variabile inizializzata e una non inizializzata.

Esempio ARM64

Questo non cambia affatto in ARM64 poiché le variabili locali sono gestite anche nello stack, puoi controllare questo esempio dove questo è mostrato.

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Supporta HackTricks

Last updated