mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
67 lines
7.9 KiB
Markdown
67 lines
7.9 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`, και στη συνέχεια εκτυπώνει τόσο τη διεύθυνση μνήμης όσο και την τιμή της μεταβλητής. Αυτό το βήμα είναι απλό και δείχνει πώς συμπ behaves μια αρχικοποιημένη μεταβλητή.
|
||
- **`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}}
|