Ευπάθεια ρίζας στον πυρήνα του Linux και άρνηση υπηρεσίας στο systemd

Ερευνητές ασφαλείας από την Qualys αποκάλυψαν λεπτομέρειες για δύο τρωτά σημεία που επηρεάζουν τον πυρήνα του Linux και τον διαχειριστή συστήματος systemd. Μια ευπάθεια στον πυρήνα (CVE-2021-33909) επιτρέπει σε έναν τοπικό χρήστη να επιτύχει την εκτέλεση κώδικα με δικαιώματα ρίζας μέσω χειρισμού καταλόγων με υψηλή ένθεση.

Ο κίνδυνος της ευπάθειας επιδεινώνεται από το γεγονός ότι οι ερευνητές μπόρεσαν να προετοιμάσουν εργασιακά exploit που λειτουργούν στο Ubuntu 20.04/20.10/21.04, στο Debian 11 και στο Fedora 34 στην προεπιλεγμένη διαμόρφωση. Σημειώνεται ότι άλλες διανομές δεν έχουν δοκιμαστεί, αλλά θεωρητικά είναι επίσης επιρρεπείς στο πρόβλημα και μπορούν να επιτεθούν. Ο πλήρης κώδικας των εκμεταλλεύσεων υπόσχεται να δημοσιευτεί αφού το πρόβλημα εξαλειφθεί παντού, αλλά προς το παρόν είναι διαθέσιμο μόνο ένα πρωτότυπο περιορισμένης λειτουργικότητας, προκαλώντας τη συντριβή του συστήματος. Το πρόβλημα είναι παρόν από τον Ιούλιο του 2014 και επηρεάζει τις εκδόσεις του πυρήνα ξεκινώντας από την 3.16. Η επιδιόρθωση ευπάθειας συντονίστηκε με την κοινότητα και έγινε αποδεκτή στον πυρήνα στις 19 Ιουλίου. Οι κύριες διανομές έχουν ήδη δημιουργήσει ενημερώσεις στα πακέτα πυρήνα τους (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

Η ευπάθεια προκαλείται από την αποτυχία ελέγχου του αποτελέσματος μιας μετατροπής size_t σε int πριν από την εκτέλεση λειτουργιών στον κώδικα seq_file, ο οποίος δημιουργεί αρχεία από μια ακολουθία εγγραφών. Η αποτυχία ελέγχου μπορεί να οδηγήσει σε εγγραφές εκτός ορίων στο buffer κατά τη δημιουργία, την τοποθέτηση και τη διαγραφή μιας πολύ ένθετης δομής καταλόγου (μέγεθος διαδρομής μεγαλύτερο από 1 GB). Ως αποτέλεσμα, ένας εισβολέας μπορεί να επιτύχει μια συμβολοσειρά 10 byte "//deleted" γραμμένη με μετατόπιση "-2 GB - 10 bytes" που δείχνει την περιοχή αμέσως πριν από την εκχωρημένη προσωρινή μνήμη.

Το προετοιμασμένο exploit απαιτεί 5 GB μνήμης και 1 εκατομμύριο δωρεάν inodes για να λειτουργήσει. Το exploit λειτουργεί καλώντας το mkdir() για να δημιουργήσει μια ιεραρχία περίπου ενός εκατομμυρίου υποκαταλόγων για να επιτευχθεί ένα μέγεθος διαδρομής αρχείου που υπερβαίνει το 1 GB. Αυτός ο κατάλογος προσαρτάται μέσω bind-mount σε έναν ξεχωριστό χώρο ονομάτων χρήστη, μετά τον οποίο εκτελείται η συνάρτηση rmdir() για την κατάργησή του. Παράλληλα, δημιουργείται ένα νήμα που φορτώνει ένα μικρό πρόγραμμα eBPF, το οποίο μπλοκάρεται στο στάδιο μετά τον έλεγχο του ψευδοκώδικα eBPF, αλλά πριν από τη μεταγλώττιση του JIT.

Στον μη προνομιούχο χώρο ονομάτων χρήστη, ανοίγει το αρχείο /proc/self/mountinfo και διαβάζεται το long pathname του καταλόγου που είναι προσαρτημένο σε bind, με αποτέλεσμα η συμβολοσειρά "//deleted" να γράφεται στην περιοχή πριν από την έναρξη του buffer. Η θέση για την εγγραφή της γραμμής επιλέγεται έτσι ώστε να αντικαθιστά την εντολή στο ήδη δοκιμασμένο αλλά μη μεταγλωττισμένο πρόγραμμα eBPF.

Στη συνέχεια, σε επίπεδο προγράμματος eBPF, η μη ελεγχόμενη εγγραφή εκτός buffer μετατρέπεται σε ελεγχόμενη ικανότητα ανάγνωσης και εγγραφής σε άλλες δομές πυρήνα μέσω χειρισμού των δομών btf και map_push_elem. Ως αποτέλεσμα, το exploit καθορίζει τη θέση του buffer modprobe_path[] στη μνήμη του πυρήνα και αντικαθιστά τη διαδρομή "/sbin/modprobe" σε αυτήν, η οποία σας επιτρέπει να ξεκινήσετε την εκκίνηση οποιουδήποτε εκτελέσιμου αρχείου με δικαιώματα root σε περίπτωση κλήση request_module(), η οποία εκτελείται, για παράδειγμα, κατά τη δημιουργία υποδοχής netlink.

Οι ερευνητές παρέχουν αρκετές λύσεις που είναι αποτελεσματικές μόνο για μια συγκεκριμένη εκμετάλλευση, αλλά δεν εξαλείφουν το ίδιο το πρόβλημα. Συνιστάται να ορίσετε το "/proc/sys/kernel/unprivileged_userns_clone" στο 0 για να απενεργοποιήσετε τους καταλόγους προσάρτησης σε ξεχωριστό χώρο ονομάτων αναγνωριστικού χρήστη και το "/proc/sys/kernel/unprivileged_bpf_disabled" στο 1 για να απενεργοποιήσετε τη φόρτωση προγραμμάτων eBPF στον πυρήνα.

Είναι αξιοσημείωτο ότι κατά την ανάλυση μιας εναλλακτικής επίθεσης που περιλαμβάνει τη χρήση του μηχανισμού FUSE αντί του bind-mound για την προσάρτηση ενός μεγάλου καταλόγου, οι ερευνητές συνάντησαν μια άλλη ευπάθεια (CVE-2021-33910) που επηρεάζει τον διαχειριστή συστήματος συστήματος. Αποδείχθηκε ότι όταν προσπαθείτε να προσαρτήσετε έναν κατάλογο με μέγεθος διαδρομής που υπερβαίνει τα 8 MB μέσω FUSE, η διαδικασία προετοιμασίας ελέγχου (PID1) εξαντλείται από τη μνήμη στοίβας και διακόπτεται, γεγονός που θέτει το σύστημα σε κατάσταση «πανικού».

Το πρόβλημα είναι ότι το systemd παρακολουθεί και αναλύει τα περιεχόμενα του /proc/self/mountinfo και επεξεργάζεται κάθε σημείο προσάρτησης στη συνάρτηση unit_name_path_escape(), η οποία εκτελεί μια λειτουργία strdupa() που τοποθετεί τα δεδομένα στη στοίβα αντί στη δυναμικά εκχωρημένη μνήμη . Δεδομένου ότι το μέγιστο μέγεθος στοίβας περιορίζεται μέσω RLIMIT_STACK, η επεξεργασία μιας πολύ μεγάλης διαδρομής στο σημείο προσάρτησης προκαλεί τη διακοπή λειτουργίας της διαδικασίας PID1 και τη διακοπή του συστήματος. Για μια επίθεση, μπορείτε να χρησιμοποιήσετε την απλούστερη μονάδα FUSE σε συνδυασμό με τη χρήση ενός εξαιρετικά ένθετου καταλόγου ως σημείου προσάρτησης, το μέγεθος διαδρομής του οποίου υπερβαίνει τα 8 MB.

Το πρόβλημα εμφανίζεται από το systemd 220 (Απρίλιος 2015), έχει ήδη επιδιορθωθεί στο κύριο αποθετήριο systemd και επιδιορθώθηκε σε διανομές (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Συγκεκριμένα, στην έκδοση systemd 248 το exploit δεν λειτουργεί λόγω ενός σφάλματος στον κώδικα systemd που προκαλεί την αποτυχία της επεξεργασίας του /proc/self/mountinfo. Είναι επίσης ενδιαφέρον ότι το 2018, προέκυψε μια παρόμοια κατάσταση και όταν προσπάθησαν να γράψουν ένα exploit για την ευπάθεια CVE-2018-14634 στον πυρήνα του Linux, οι ερευνητές της Qualys αντιμετώπισαν τρία κρίσιμα τρωτά σημεία στο systemd.

Πηγή: opennet.ru

Προσθέστε ένα σχόλιο