9.1 KiB
Uninitialized Variables
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Basic Information
Основна ідея полягає в тому, щоб зрозуміти, що відбувається з нініціалізованими змінними, оскільки вони матимуть значення, яке вже було в пам'яті, призначеній їм. Приклад:
- Функція 1:
initializeVariable
: Ми оголошуємо зміннуx
і присвоюємо їй значення, скажімо,0x1234
. Ця дія подібна до резервування місця в пам'яті та вставлення в нього конкретного значення. - Функція 2:
useUninitializedVariable
: Тут ми оголошуємо іншу зміннуy
, але не присвоюємо їй жодного значення. У C нініціалізовані змінні не автоматично встановлюються в нуль. Натомість вони зберігають те, яке значення було останнім збережено в їхньому місці пам'яті.
Коли ми запускаємо ці дві функції послідовно:
- У
initializeVariable
зміннійx
присвоюється значення (0x1234
), яке займає конкретну адресу пам'яті. - У
useUninitializedVariable
зміннаy
оголошується, але їй не присвоюється значення, тому вона займає місце в пам'яті безпосередньо післяx
. Через те, щоy
не ініціалізована, вона в кінцевому підсумку "успадковує" значення з того ж місця пам'яті, яке використовувалосяx
, оскільки це останнє значення, яке там було.
Ця поведінка ілюструє ключове поняття в низькорівневому програмуванні: Управління пам'яттю є критично важливим, і нініціалізовані змінні можуть призвести до непередбачуваної поведінки або вразливостей безпеки, оскільки вони можуть ненавмисно містити чутливі дані, залишені в пам'яті.
Нініціалізовані стекові змінні можуть становити кілька ризиків безпеки, таких як:
- Витік даних: Чутлива інформація, така як паролі, ключі шифрування або особисті дані, може бути розкрита, якщо зберігається в нініціалізованих змінних, що дозволяє зловмисникам потенційно читати ці дані.
- Розкриття інформації: Вміст нініціалізованих змінних може розкрити деталі про структуру пам'яті програми або внутрішні операції, що допомагає зловмисникам розробляти цілеспрямовані експлойти.
- Збої та нестабільність: Операції, що стосуються нініціалізованих змінних, можуть призвести до невизначеної поведінки, що викликає збої програми або непередбачувані результати.
- Виконання довільного коду: У певних сценаріях зловмисники можуть експлуатувати ці вразливості, щоб змінити потік виконання програми, що дозволяє їм виконувати довільний код, що може включати загрози віддаленого виконання коду.
Example
#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;
}
Як це працює:
initializeAndPrint
Функція: Ця функція оголошує цілу зміннуinitializedVar
, присвоює їй значення100
, а потім виводить як адресу пам'яті, так і значення змінної. Цей крок є простим і демонструє, як поводиться ініціалізована змінна.demonstrateUninitializedVar
Функція: У цій функції ми оголошуємо цілу зміннуuninitializedVar
без її ініціалізації. Коли ми намагаємося вивести її значення, вихід може показати випадкове число. Це число представляє будь-які дані, які раніше знаходилися за цією адресою пам'яті. Залежно від середовища та компілятора, фактичний вихід може варіюватися, і іноді, для безпеки, деякі компілятори можуть автоматично ініціалізувати змінні до нуля, хоча на це не слід покладатися.main
Функція: Функціяmain
викликає обидві вищезгадані функції послідовно, демонструючи контраст між ініціалізованою змінною та неініціалізованою.
ARM64 Приклад
Це зовсім не змінюється в ARM64, оскільки локальні змінні також управляються в стеку, ви можете перевірити цей приклад, де це показано.
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримати HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.