mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
67 lines
6.8 KiB
Markdown
67 lines
6.8 KiB
Markdown
# Невизначені Змінні
|
||
|
||
{{#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}}
|