Μη Αρχικοποιημένες Μεταβλητές

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

Βασικές Πληροφορίες

Η βασική ιδέα εδώ είναι να κατανοήσουμε τι συμβαίνει με τις μη αρχικοποιημένες μεταβλητές καθώς θα έχουν την τιμή που ήταν ήδη στη μνήμη που τους έχει ανατεθεί. Παράδειγμα:

  • Συνάρτηση 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 καθώς οι τοπικές μεταβλητές διαχειρίζονται επίσης στο στοίβα, μπορείτε να ελέγξετε αυτό το παράδειγμα όπου αυτό δείχνεται.

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