Uninitialized Variables
Last updated
Last updated
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Główna idea tutaj polega na zrozumieniu, co się dzieje z niezainicjowanymi zmiennymi, ponieważ będą one miały wartość, która już znajdowała się w przydzielonej pamięci. Przykład:
Funkcja 1: initializeVariable
: Deklarujemy zmienną x
i przypisujemy jej wartość, powiedzmy 0x1234
. Ta akcja jest podobna do rezerwacji miejsca w pamięci i umieszczenia w nim konkretnej wartości.
Funkcja 2: useUninitializedVariable
: Tutaj deklarujemy inną zmienną y
, ale nie przypisujemy jej żadnej wartości. W C, niezainicjowane zmienne nie są automatycznie ustawiane na zero. Zamiast tego, zachowują wartość, która była ostatnio przechowywana w ich lokalizacji pamięci.
Kiedy uruchamiamy te dwie funkcje sekwencyjnie:
W initializeVariable
, x
otrzymuje wartość (0x1234
), która zajmuje określony adres pamięci.
W useUninitializedVariable
, y
jest deklarowane, ale nie przypisano mu wartości, więc zajmuje miejsce w pamięci tuż po x
. Z powodu braku inicjalizacji y
, kończy się na "dziedziczeniu" wartości z tej samej lokalizacji pamięci używanej przez x
, ponieważ to była ostatnia wartość, która tam była.
To zachowanie ilustruje kluczową koncepcję w programowaniu niskopoziomowym: Zarządzanie pamięcią jest kluczowe, a niezainicjowane zmienne mogą prowadzić do nieprzewidywalnego zachowania lub luk w zabezpieczeniach, ponieważ mogą niezamierzenie przechowywać wrażliwe dane pozostawione w pamięci.
Niezainicjowane zmienne stosu mogą stwarzać kilka zagrożeń bezpieczeństwa, takich jak:
Wycieki Danych: Wrażliwe informacje, takie jak hasła, klucze szyfrowania lub dane osobowe, mogą być ujawnione, jeśli są przechowywane w niezainicjowanych zmiennych, co pozwala atakującym na potencjalne odczytanie tych danych.
Ujawnienie Informacji: Zawartość niezainicjowanych zmiennych może ujawniać szczegóły dotyczące układu pamięci programu lub wewnętrznych operacji, co pomaga atakującym w opracowywaniu ukierunkowanych exploitów.
Awaria i Niestabilność: Operacje związane z niezainicjowanymi zmiennymi mogą prowadzić do nieokreślonego zachowania, co skutkuje awariami programu lub nieprzewidywalnymi wynikami.
Wykonanie Dowolnego Kodu: W niektórych scenariuszach, atakujący mogą wykorzystać te luki, aby zmienić przepływ wykonania programu, co umożliwia im wykonanie dowolnego kodu, co może obejmować zagrożenia związane z zdalnym wykonaniem kodu.
Funkcja initializeAndPrint
: Ta funkcja deklaruje zmienną całkowitą initializedVar
, przypisuje jej wartość 100
, a następnie drukuje zarówno adres pamięci, jak i wartość zmiennej. Ten krok jest prosty i pokazuje, jak zachowuje się zainicjowana zmienna.
Funkcja demonstrateUninitializedVar
: W tej funkcji deklarujemy zmienną całkowitą uninitializedVar
bez jej inicjalizacji. Kiedy próbujemy wydrukować jej wartość, wynik może pokazać losową liczbę. Ta liczba reprezentuje dane, które wcześniej znajdowały się w tej lokalizacji pamięci. W zależności od środowiska i kompilatora, rzeczywisty wynik może się różnić, a czasami, dla bezpieczeństwa, niektóre kompilatory mogą automatycznie inicjalizować zmienne do zera, chociaż na tym nie należy polegać.
Funkcja main
: Funkcja main
wywołuje obie powyższe funkcje w kolejności, demonstrując kontrast między zainicjowaną a niezainicjowaną zmienną.
To w ogóle się nie zmienia w ARM64, ponieważ zmienne lokalne są również zarządzane na stosie, możesz sprawdzić ten przykład, gdzie to jest pokazane.
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)