Μη Αρχικοποιημένες Μεταβλητές
Reading time: 5 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Βασικές Πληροφορίες
Η βασική ιδέα εδώ είναι να κατανοήσουμε τι συμβαίνει με τις μη αρχικοποιημένες μεταβλητές καθώς θα έχουν την τιμή που ήταν ήδη στη μνήμη που τους έχει ανατεθεί. Παράδειγμα:
- Συνάρτηση 1:
initializeVariable
: Δηλώνουμε μια μεταβλητήx
και της αναθέτουμε μια τιμή, ας πούμε0x1234
. Αυτή η ενέργεια είναι παρόμοια με την κράτηση μιας θέσης στη μνήμη και την τοποθέτηση μιας συγκεκριμένης τιμής σε αυτήν. - Συνάρτηση 2:
useUninitializedVariable
: Εδώ, δηλώνουμε μια άλλη μεταβλητήy
αλλά δεν της αναθέτουμε καμία τιμή. Στην C, οι μη αρχικοποιημένες μεταβλητές δεν ρυθμίζονται αυτόματα σε μηδέν. Αντίθετα, διατηρούν όποια τιμή ήταν τελευταία αποθηκευμένη στη θέση μνήμης τους.
Όταν εκτελούμε αυτές τις δύο συναρτήσεις διαδοχικά:
- Στην
initializeVariable
, ηx
ανατίθεται μια τιμή (0x1234
), η οποία καταλαμβάνει μια συγκεκριμένη διεύθυνση μνήμης. - Στην
useUninitializedVariable
, ηy
δηλώνεται αλλά δεν της ανατίθεται τιμή, οπότε καταλαμβάνει τη θέση μνήμης αμέσως μετά τηνx
. Λόγω της μη αρχικοποίησης τηςy
, καταλήγει να "κληρονομεί" την τιμή από την ίδια θέση μνήμης που χρησιμοποιήθηκε από τηνx
, επειδή αυτή είναι η τελευταία τιμή που υπήρχε εκεί.
Αυτή η συμπεριφορά απεικονίζει μια βασική έννοια στον προγραμματισμό χαμηλού επιπέδου: Η διαχείριση μνήμης είναι κρίσιμη, και οι μη αρχικοποιημένες μεταβλητές μπορούν να οδηγήσουν σε απρόβλεπτη συμπεριφορά ή ευπάθειες ασφαλείας, καθώς μπορεί να κρατούν κατά λάθος ευαίσθητα δεδομένα που έχουν απομείνει στη μνήμη.
Οι μη αρχικοποιημένες μεταβλητές στο στοίβα θα μπορούσαν να θέσουν αρκετούς κινδύνους ασφαλείας όπως:
- Διαρροή Δεδομένων: Ευαίσθητες πληροφορίες όπως κωδικοί πρόσβασης, κλειδιά κρυπτογράφησης ή προσωπικά στοιχεία μπορεί να εκτεθούν αν αποθηκευτούν σε μη αρχικοποιημένες μεταβλητές, επιτρέποντας στους επιτιθέμενους να διαβάσουν αυτά τα δεδομένα.
- Αποκάλυψη Πληροφοριών: Το περιεχόμενο των μη αρχικοποιημένων μεταβλητών μπορεί να αποκαλύψει λεπτομέρειες σχετικά με τη διάταξη μνήμης του προγράμματος ή τις εσωτερικές λειτουργίες, βοηθώντας τους επιτιθέμενους να αναπτύξουν στοχευμένες εκμεταλλεύσεις.
- Κρατήσεις και Αστάθεια: Οι λειτουργίες που περιλαμβάνουν μη αρχικοποιημένες μεταβλητές μπορεί να οδηγήσουν σε μη καθορισμένη συμπεριφορά, προκαλώντας κρατήσεις προγράμματος ή απρόβλεπτα αποτελέσματα.
- Εκτέλεση Αυθαίρετου Κώδικα: Σε ορισμένα σενάρια, οι επιτιθέμενοι θα μπορούσαν να εκμεταλλευτούν αυτές τις ευπάθειες για να αλλάξουν τη ροή εκτέλεσης του προγράμματος, επιτρέποντάς τους να εκτελέσουν αυθαίρετο κώδικα, ο οποίος μπορεί να περιλαμβάνει απειλές εκτέλεσης απομακρυσμένου κώδικα.
Παράδειγμα
#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 καθώς οι τοπικές μεταβλητές διαχειρίζονται επίσης στο στοίβα, μπορείτε να ελέγξετε αυτό το παράδειγμα όπου αυτό δείχνεται.
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.