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

67 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Невизначені Змінні
{{#include ../../banners/hacktricks-training.md}}
## Основна Інформація
Основна ідея полягає в тому, щоб зрозуміти, що відбувається з **невизначеними змінними, оскільки вони матимуть значення, яке вже було в пам'яті, призначеній їм.** Приклад:
- **Функція 1: `initializeVariable`**: Ми оголошуємо змінну `x` і присвоюємо їй значення, скажімо, `0x1234`. Ця дія подібна до резервування місця в пам'яті та вставлення в нього конкретного значення.
- **Функція 2: `useUninitializedVariable`**: Тут ми оголошуємо іншу змінну `y`, але не присвоюємо їй жодного значення. У C невизначені змінні не автоматично встановлюються в нуль. Натомість вони зберігають те, яке значення було останнім, збереженим за їх адресою в пам'яті.
Коли ми запускаємо ці дві функції **послідовно**:
1. У `initializeVariable` змінній `x` присвоюється значення (`0x1234`), яке займає конкретну адресу в пам'яті.
2. У `useUninitializedVariable` змінна `y` оголошується, але їй не присвоюється значення, тому вона займає місце в пам'яті відразу після `x`. Через те, що `y` не ініціалізована, вона в кінцевому підсумку "успадковує" значення з тієї ж адреси пам'яті, що й `x`, оскільки це останнє значення, яке там було.
Ця поведінка ілюструє ключове поняття в низькорівневому програмуванні: **Управління пам'яттю є критично важливим**, і невизначені змінні можуть призвести до непередбачуваної поведінки або вразливостей безпеки, оскільки вони можуть ненавмисно містити чутливі дані, залишені в пам'яті.
Невизначені стекові змінні можуть становити кілька ризиків безпеки, таких як:
- **Витік Даних**: Чутлива інформація, така як паролі, ключі шифрування або особисті дані, може бути розкрита, якщо зберігається в невизначених змінних, що дозволяє зловмисникам потенційно читати ці дані.
- **Розкриття Інформації**: Вміст невизначених змінних може розкрити деталі про структуру пам'яті програми або внутрішні операції, що допомагає зловмисникам розробляти цілеспрямовані експлойти.
- **Збої та Нестабільність**: Операції, що стосуються невизначених змінних, можуть призвести до невизначеної поведінки, що викликає збої програми або непередбачувані результати.
- **Виконання Довільного Коду**: У певних сценаріях зловмисники можуть експлуатувати ці вразливості, щоб змінити потік виконання програми, що дозволяє їм виконувати довільний код, що може включати загрози віддаленого виконання коду.
### Приклад
```c
#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, оскільки локальні змінні також управляються в стеку, ви можете [**перевірити цей приклад**](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/), де це показано.
{{#include ../../banners/hacktricks-training.md}}