Chrome zero-day: "This exploit is in the wild", οπότε ελέγξτε την έκδοσή σας τώρα

Chrome zero-day: "This exploit is in the wild", οπότε ελέγξτε την έκδοσή σας τώρα

Κόμβος πηγής: 2704382

Κυκλοφόρησε η τελευταία ενημέρωση Chrome της Google και αυτή τη φορά η εταιρεία δεν έχει μασήσει τα λόγια του περίπου μία από τις δύο ενημερώσεις κώδικα ασφαλείας που περιλαμβάνει:

Η Google γνωρίζει ότι μια εκμετάλλευση για CVE-2023-3079 υπάρχει στην άγρια ​​φύση.

Δεν υπάρχει λόγος διαχωρισμού δύο βαθμών, όπως έχουμε δει συχνά από την Google στο παρελθόν, για να πούμε ότι η εταιρεία «γνωρίζει αναφορές» για μια εκμετάλλευση.

Αυτή τη φορά, είναι "τα γνωρίζουμε όλα μόνοι μας", που μεταφράζεται ακόμη πιο ωμά σε "ξέρουμε ότι οι απατεώνες το κάνουν κατάχρηση καθώς μιλάμε", δεδομένου ότι η αναφορά σφαλμάτων προήλθε απευθείας από την ομάδα έρευνας απειλών της Google.

Ως συνήθως, αυτό υποδηλώνει ότι η Google ερευνούσε μια ενεργή επίθεση (είτε εναντίον της ίδιας της Google είτε εναντίον κάποιου εξωτερικού οργανισμού, δεν γνωρίζουμε) στην οποία το Chrome είχε παραβιαστεί από μια προηγουμένως άγνωστη τρύπα ασφαλείας.

Το σφάλμα περιγράφεται απλά ως εξής: Τύπος Σύγχυση στο V8. (Κατανοητά, η Google δεν λέει περισσότερα από αυτό σε αυτό το στάδιο.)

Όπως έχουμε εξηγήσει προηγουμένως, α σύγχυση τύπου σφάλμα παρουσιάζεται όταν παρέχετε σε ένα πρόγραμμα ένα κομμάτι δεδομένων που υποτίθεται ότι αναλύει, επικυρώνει, επεξεργάζεται και ενεργεί με έναν τρόπο…

…αλλά αργότερα καταφέρνετε να ξεγελάσετε το πρόγραμμα ώστε να ερμηνεύσει τα δεδομένα με διαφορετικό, μη εξουσιοδοτημένο, μη επικυρωμένο και δυνητικά επικίνδυνο τρόπο.

Επεξηγούνται οι κίνδυνοι σύγχυσης τύπου

Φανταστείτε ότι γράφετε ένα πρόγραμμα σε C. (Δεν έχει σημασία αν γνωρίζετε C ή όχι, μπορείτε απλώς να ακολουθήσετε ούτως ή άλλως.)

Στο C, συνήθως δηλώνετε τις μεταβλητές μεμονωμένα, δεσμεύοντας έτσι όχι μόνο τη μνήμη όπου μπορούν να αποθηκευτούν, αλλά και σηματοδοτώντας στο πρόγραμμα πώς αυτές οι μεταβλητές υποτίθεται ότι θα χρησιμοποιηθούν.

Για παράδειγμα:

 long long int JulianDayNumber? υπογεγραμμένο char* Όνομα πελάτη;

Η πρώτη δήλωση μεταβλητής δεσμεύει 64 bit για την αποθήκευση μιας απλής παλιάς ακέραιας τιμής που αντιπροσωπεύει τον αστρονομικό αριθμό ημέρας. (Σε περίπτωση που αναρωτιέστε, σήμερα το απόγευμα είναι JDN 23157 – Οι Ιουλιανές Ημέρες ξεκινούν το μεσημέρι, όχι τα μεσάνυχτα, επειδή οι αστρονόμοι εργάζονται συχνά τη νύχτα, με τα μεσάνυχτα να είναι το μέσο της εργάσιμης ημέρας τους.)

Το δεύτερο κρατά 64 bit για την αποθήκευση μιας διεύθυνσης μνήμης όπου μπορεί να βρεθεί η συμβολοσειρά κειμένου του ονόματος ενός πελάτη.

Όπως μπορείτε να φανταστείτε, καλύτερα να μην ανακατεύετε αυτές τις δύο τιμές, γιατί ένας αριθμός που έχει νόημα και είναι ασφαλής για χρήση ως αριθμός ημέρας, όπως το 23157, θα ήταν σχεδόν σίγουρα μη ασφαλής για χρήση ως διεύθυνση μνήμης.

Όπως μπορείτε να δείτε από αυτήν την ένδειξη μνήμης ενός προγράμματος των Windows που εκτελείται, η χαμηλότερη διεύθυνση μνήμης που έχει εκχωρηθεί για χρήση ξεκινά από το 0x00370000, που είναι 3,604,480 δεκαδικά, πολύ μεγαλύτερο από οποιονδήποτε λογικό αριθμό ημέρας.

Οι πραγματικές διευθύνσεις μνήμης που χρησιμοποιούνται από τα Windows ποικίλλουν τυχαία με την πάροδο του χρόνου, για να κάνουν τους απατεώνες πιο δύσκολο να μαντέψουν τη διάταξη της μνήμης σας, οπότε αν εκτελούσατε το ίδιο πρόγραμμα, θα λαμβάνατε τιμές, αλλά θα είναι παρόλα αυτά παρόμοιες:

Και (αν και είναι στο κάτω μέρος της παραπάνω εικόνας) οι διευθύνσεις μνήμης της ενότητας δεδομένων χρήστη χρόνου εκτέλεσης όταν αυτό το πρόγραμμα εκτελούσε 0x01130000 προς την 0x01134FFF, που αντιπροσωπεύει το απίθανο εύρος ημερομηνιών από 22 Ιουλίου 44631 έως 16 Αυγούστου 44687.

Πράγματι, εάν προσπαθήσετε να αναμίξετε αυτές τις δύο μεταβλητές, ο μεταγλωττιστής θα πρέπει να προσπαθήσει να σας προειδοποιήσει, για παράδειγμα ως εξής:

 JulianDayNumber = Όνομα πελάτη; CustomerName = JulianDayNumber; προειδοποίηση: η ανάθεση κάνει ακέραιο από δείκτη χωρίς cast warning: ανάθεση κάνει δείκτη από ακέραιο χωρίς cast

Τώρα, εάν έχετε προγραμματίσει ποτέ σε C, θα ξέρετε ότι για ευκολία, μπορείτε να δηλώσετε μεταβλητές με πολλές διαφορετικές ερμηνείες χρησιμοποιώντας το union λέξη-κλειδί, όπως αυτή:

 union { long long int JulianDayNumer; υπογεγραμμένο char* Όνομα πελάτη; } δεδομένα;

Τώρα μπορείτε να αναφέρετε ακριβώς την ίδια μεταβλητή στη μνήμη με δύο διαφορετικούς τρόπους.

Εάν γράφετε data.JulianDayNumber, ερμηνεύετε με μαγικό τρόπο τα αποθηκευμένα δεδομένα ως ακέραιο, αλλά εγγράφως data.CustomerName λέει στον μεταγλωττιστή ότι αναφέρετε μια διεύθυνση μνήμης, παρόλο που έχετε πρόσβαση στα ίδια αποθηκευμένα δεδομένα.

Αυτό που κάνετε, λίγο πολύ, είναι να παραδεχτείτε στον μεταγλωττιστή ότι μερικές φορές θα αντιμετωπίζετε τα δεδομένα που έχετε ως ημερομηνία και άλλες φορές ως διεύθυνση μνήμης, και ότι αναλαμβάνετε την ευθύνη να θυμάστε ποια ερμηνεία ισχύει σε ποια στιγμή στον κώδικα.

Ίσως αποφασίσετε να έχετε μια δεύτερη μεταβλητή, γνωστή ως a tag (συνήθως ένας ακέραιος αριθμός) για να συμβαδίσει με το δικό σας union για να παρακολουθείτε με τι είδους δεδομένα εργάζεστε αυτήν τη στιγμή, για παράδειγμα:

 struct { int tag; union { long long int JulianDayNumer; υπογεγραμμένος χαρακτήρας* Όνομα πελάτη; } δεδομένα; } αξία;

Μπορείς να το αποφασίσεις πότε value.tag έχει οριστεί σε 0, τα δεδομένα δεν έχουν αρχικοποιηθεί ακόμα για χρήση, 1 σημαίνει ότι αποθηκεύετε μια ημερομηνία, 2 σημαίνει ότι είναι μια διεύθυνση μνήμης και οτιδήποτε άλλο υποδηλώνει σφάλμα.

Λοιπόν, καλύτερα να μην αφήσεις κανέναν άλλο να ασχοληθεί με αυτό value.tag ρύθμιση ή το πρόγραμμά σας θα μπορούσε να καταλήξει να έχει δραματική κακή συμπεριφορά.

Ένα πιο ανησυχητικό παράδειγμα μπορεί να είναι κάπως έτσι:

 struct { int tag; // 1 = κατακερματισμός, 2 = ένωση δεικτών συνάρτησης { unsigned char hash[16]; // είτε αποθηκεύστε μια τυχαία δομή κατακερματισμού { void* openfunc; // ή δύο προσεκτικά επικυρωμένες void* closefunc; // δείκτες κώδικα για εκτέλεση αργότερα } επικύρωση; } } αξία;

Τώρα, υπερφορτώνουμε το ίδιο μπλοκ μνήμης, ώστε μερικές φορές να μπορούμε να το χρησιμοποιήσουμε για να αποθηκεύσουμε έναν κατακερματισμό 16 byte και μερικές φορές για να αποθηκεύσουμε δύο δείκτες 8 byte σε λειτουργίες που θα καλέσει το πρόγραμμά μας αργότερα.

Σαφώς, πότε value.tag == 1, θα χαρούμε να αφήσουμε το λογισμικό μας να αποθηκεύσει οποιαδήποτε συμβολοσειρά 16 byte στη μνήμη που έχει εκχωρηθεί για την ένωση, επειδή οι κατακερματισμοί είναι ψευδοτυχαίοι, επομένως οποιαδήποτε συλλογή byte είναι εξίσου πιθανή.

Αλλά όταν value.tag == 2, ο κώδικάς μας θα πρέπει να είναι εξαιρετικά προσεκτικός ώστε να μην επιτρέπει στο χρήστη να παρέχει μη επικυρωμένες, μη αξιόπιστες, άγνωστες διευθύνσεις συναρτήσεων για εκτέλεση αργότερα.

Τώρα φανταστείτε ότι θα μπορούσατε να υποβάλετε μια τιμή σε αυτόν τον κωδικό ενώ η ετικέτα είχε οριστεί σε 1, έτσι ώστε να μην ελεγχθεί και να επικυρωθεί…

…αλλά αργότερα, λίγο πριν το πρόγραμμα χρησιμοποιήσει πραγματικά την αποθηκευμένη τιμή, μπορέσατε να ξεγελάσετε τον κώδικα για να αλλάξετε την ετικέτα σε 2.

Στη συνέχεια, ο κώδικας θα δεχόταν τις μη επικυρωμένες διευθύνσεις συναρτήσεών σας ως "γνωστές και ήδη επαληθευμένες ασφαλείς" (παρόλο που δεν ήταν) και θα αποστέλλει με εμπιστοσύνη την εκτέλεση του προγράμματος σε μια παράνομη τοποθεσία στη μνήμη που είχατε επιλέξει κρυφά εκ των προτέρων.

Και αυτό συμβαίνει σε ένα σφάλμα σύγχυσης τύπων, αν και χρησιμοποιώντας ένα επινοημένο και απλοποιημένο παράδειγμα,

Μνήμη που θα ήταν ασφαλής να καταναλωθεί, εάν ο χειρισμός γινόταν με έναν τρόπο, παραδίδεται κακόβουλα στο πρόγραμμα για επεξεργασία με έναν εναλλακτικό, μη ασφαλή τρόπο.

Τι να κάνω;

Βεβαιωθείτε ότι διαθέτετε την πιο πρόσφατη έκδοση του Chrome ή του Chromium.

Θέλετε Chrome 114.0.5735.106 ή αργότερα σε Mac και Linux και 114.0.5735.110 ή αργότερα στα Windows.

Το Microsoft Edge, το οποίο βασίζεται στο Chromium, επηρεάζεται επίσης από αυτό το σφάλμα.

Η Microsoft έχει μέχρι στιγμής [2023-06-06T16:25:00Z] Σημειώνεται ότι

Η Microsoft έχει επίγνωση των πρόσφατων εκμεταλλεύσεων που υπάρχουν στη φύση. Εργαζόμαστε ενεργά για την κυκλοφορία μιας ενημέρωσης κώδικα ασφαλείας.

Το Edge βρίσκεται αυτήν τη στιγμή στην έκδοση 114.0.1823.37, οπότε οτιδήποτε είναι αριθμημένο αργότερα από αυτό θα πρέπει να περιλαμβάνει τις ενημερώσεις κώδικα CVE-2023-3079 της Microsoft.

Για να ελέγξετε την έκδοσή σας και να επιβάλετε μια ενημέρωση εάν υπάρχει κάποια που δεν έχετε λάβει ακόμη:

  • Google Chrome. Μενού με τρεις κουκκίδες (⋮) > Βοήθεια > Σχετικά με το Chrome.
  • Microsoft Edge. Ρυθμίσεις και πολλά άλλα (…) > Βοήθεια και σχόλια > Σχετικά με τον Microsoft Edge.

Παρακαλώ.


Σφραγίδα ώρας:

Περισσότερα από Γυμνή ασφάλεια