macOS MACF - Mandatory Access Control Framework
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
MACF σημαίνει Πλαίσιο Υποχρεωτικού Ελέγχου Πρόσβασης, το οποίο είναι ένα σύστημα ασφαλείας ενσωματωμένο στο λειτουργικό σύστημα για να βοηθήσει στην προστασία του υπολογιστή σας. Λειτουργεί θέτοντας αυστηρούς κανόνες σχετικά με το ποιος ή τι μπορεί να έχει πρόσβαση σε ορισμένα μέρη του συστήματος, όπως αρχεία, εφαρμογές και πόρους συστήματος. Εφαρμόζοντας αυτούς τους κανόνες αυτόματα, το MACF διασφαλίζει ότι μόνο οι εξουσιοδοτημένοι χρήστες και διαδικασίες μπορούν να εκτελούν συγκεκριμένες ενέργειες, μειώνοντας τον κίνδυνο μη εξουσιοδοτημένης πρόσβασης ή κακόβουλων δραστηριοτήτων.
Σημειώστε ότι το MACF δεν παίρνει πραγματικά αποφάσεις καθώς απλώς παρεμβαίνει σε ενέργειες, αφήνει τις αποφάσεις στα modules πολιτικής (επέκταση πυρήνα) που καλεί όπως AppleMobileFileIntegrity.kext
, Quarantine.kext
, Sandbox.kext
, TMSafetyNet.kext
και mcxalr.kext
.
Η διαδικασία εκτελεί μια syscall/mach trap
Η σχετική λειτουργία καλείται μέσα στον πυρήνα
Η λειτουργία καλεί το MACF
Το MACF ελέγχει τα modules πολιτικής που ζήτησαν να συνδεθούν με αυτή τη λειτουργία στην πολιτική τους
Το MACF καλεί τις σχετικές πολιτικές
Οι πολιτικές υποδεικνύουν αν επιτρέπουν ή απορρίπτουν την ενέργεια
Η Apple είναι η μόνη που μπορεί να χρησιμοποιήσει το KPI του MAC Framework.
Το MACF χρησιμοποιεί ετικέτες που στη συνέχεια οι πολιτικές ελέγχουν αν θα χορηγήσουν κάποια πρόσβαση ή όχι. Ο κώδικας της δήλωσης δομής των ετικετών μπορεί να βρεθεί εδώ, ο οποίος χρησιμοποιείται στη συνέχεια μέσα στη struct ucred
εδώ στο μέρος cr_label
. Η ετικέτα περιέχει σημαίες και έναν αριθμό slots που μπορούν να χρησιμοποιηθούν από πολιτικές MACF για να εκχωρήσουν δείκτες. Για παράδειγμα, το Sandbox θα δείχνει στο προφίλ του κοντέινερ.
Μια πολιτική MACF καθορίζει κανόνες και συνθήκες που θα εφαρμοστούν σε ορισμένες λειτουργίες του πυρήνα.
Μια επέκταση πυρήνα θα μπορούσε να διαμορφώσει μια δομή mac_policy_conf
και στη συνέχεια να την καταχωρίσει καλώντας mac_policy_register
. Από εδώ:
Είναι εύκολο να εντοπιστούν οι επεκτάσεις πυρήνα που ρυθμίζουν αυτές τις πολιτικές ελέγχοντας τις κλήσεις προς το mac_policy_register
. Επιπλέον, ελέγχοντας την αποσυναρμολόγηση της επέκτασης είναι επίσης δυνατό να βρεθεί η χρησιμοποιούμενη δομή mac_policy_conf
.
Σημειώστε ότι οι πολιτικές MACF μπορούν να καταχωρηθούν και να αποσυρθούν επίσης δυναμικά.
Ένα από τα κύρια πεδία της mac_policy_conf
είναι το mpc_ops
. Αυτό το πεδίο καθορίζει ποιες λειτουργίες ενδιαφέρει η πολιτική. Σημειώστε ότι υπάρχουν εκατοντάδες από αυτές, οπότε είναι δυνατό να μηδενιστούν όλες και στη συνέχεια να επιλεγούν μόνο αυτές που ενδιαφέρει η πολιτική. Από εδώ:
Σχεδόν όλοι οι hooks θα καλούνται από το MACF όταν μία από αυτές τις λειτουργίες παρεμποδίζεται. Ωστόσο, οι mpo_policy_*
hooks είναι μια εξαίρεση επειδή το mpo_hook_policy_init()
είναι μια callback που καλείται κατά την εγγραφή (οπότε μετά το mac_policy_register()
) και το mpo_hook_policy_initbsd()
καλείται κατά την καθυστερημένη εγγραφή μόλις το BSD υποσύστημα έχει αρχικοποιηθεί σωστά.
Επιπλέον, ο mpo_policy_syscall
hook μπορεί να εγγραφεί από οποιοδήποτε kext για να εκθέσει μια ιδιωτική ioctl στυλ κλήση interface. Στη συνέχεια, ένας πελάτης χρήστη θα μπορεί να καλέσει το mac_syscall
(#381) καθορίζοντας ως παραμέτρους το όνομα πολιτικής με έναν ακέραιο κωδικό και προαιρετικά ορίσματα.
Για παράδειγμα, το Sandbox.kext
το χρησιμοποιεί πολύ.
Ελέγχοντας το __DATA.__const*
του kext είναι δυνατό να προσδιοριστεί η δομή mac_policy_ops
που χρησιμοποιείται κατά την εγγραφή της πολιτικής. Είναι δυνατό να την βρείτε επειδή ο δείκτης της είναι σε μια απόσταση μέσα στο mpo_policy_conf
και επίσης λόγω του αριθμού των NULL δεικτών που θα είναι σε αυτήν την περιοχή.
Επιπλέον, είναι επίσης δυνατό να αποκτήσετε τη λίστα των kexts που έχουν ρυθμίσει μια πολιτική εκ dumping από τη μνήμη της δομής _mac_policy_list
που ενημερώνεται με κάθε πολιτική που εγγράφεται.
Το MACF αρχικοποιείται πολύ νωρίς. Ρυθμίζεται στο bootstrap_thread
του XNU: μετά το ipc_bootstrap
γίνεται μια κλήση στο mac_policy_init()
που αρχικοποιεί τη mac_policy_list
και λίγα λεπτά αργότερα καλείται το mac_policy_initmach()
. Μεταξύ άλλων, αυτή η συνάρτηση θα αποκτήσει όλα τα Apple kexts με το κλειδί AppleSecurityExtension
στο Info.plist τους όπως το ALF.kext
, AppleMobileFileIntegrity.kext
, Quarantine.kext
, Sandbox.kext
και TMSafetyNet.kext
και τα φορτώνει.
Είναι κοινό να βρείτε callouts στο MACF που ορίζονται σε κώδικα όπως: #if CONFIG_MAC
μπλοκ συνθηκών. Επιπλέον, μέσα σε αυτά τα μπλοκ είναι δυνατό να βρείτε κλήσεις σε mac_proc_check*
που καλεί το MACF για έλεγχο δικαιωμάτων για την εκτέλεση ορισμένων ενεργειών. Επιπλέον, η μορφή των callouts του MACF είναι: mac_<object>_<opType>_opName
.
Το αντικείμενο είναι ένα από τα εξής: bpfdesc
, cred
, file
, proc
, vnode
, mount
, devfs
, ifnet
, inpcb
, mbuf
, ipq
, pipe
, sysv[msg/msq/shm/sem]
, posix[shm/sem]
, socket
, kext
.
Ο opType
είναι συνήθως check που θα χρησιμοποιηθεί για να επιτρέψει ή να αρνηθεί την ενέργεια. Ωστόσο, είναι επίσης δυνατό να βρείτε notify
, που θα επιτρέψει στο kext να αντιδράσει στην δεδομένη ενέργεια.
Μπορείτε να βρείτε ένα παράδειγμα στο https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_mman.c#L621:
Στη συνέχεια, είναι δυνατό να βρείτε τον κώδικα του mac_file_check_mmap
στο https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/security/mac_file.c#L174
Ποιο καλεί το μακροεντολή MAC_CHECK
, του οποίου ο κώδικας μπορεί να βρεθεί στο https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/security/mac_internal.h#L261
Ποια θα περάσει από όλες τις καταχωρημένες πολιτικές mac καλώντας τις συναρτήσεις τους και αποθηκεύοντας την έξοδο μέσα στη μεταβλητή σφάλματος, η οποία θα μπορεί να παρακαμφθεί μόνο από το mac_error_select
με κωδικούς επιτυχίας, έτσι ώστε αν οποιαδήποτε έλεγχος αποτύχει, ο συνολικός έλεγχος θα αποτύχει και η ενέργεια δεν θα επιτρέπεται.
Ωστόσο, θυμηθείτε ότι δεν καλούνται όλες οι κλήσεις MACF μόνο για να αρνηθούν ενέργειες. Για παράδειγμα, το mac_priv_grant
καλεί το μακροεντολή MAC_GRANT, η οποία θα παραχωρήσει το ζητούμενο προνόμιο αν οποιαδήποτε πολιτική απαντήσει με 0:
Αυτές οι κλήσεις προορίζονται να ελέγξουν και να παρέχουν (δεκάδες) privileges που ορίζονται στο bsd/sys/priv.h.
Ορισμένος κώδικας πυρήνα θα καλεί το priv_check_cred()
από bsd/kern/kern_priv.c με τα KAuth διαπιστευτήρια της διαδικασίας και έναν από τους κωδικούς privileges που θα καλέσει το mac_priv_check
για να δει αν κάποια πολιτική denies την παροχή του privilege και στη συνέχεια καλεί το mac_priv_grant
για να δει αν κάποια πολιτική παραχωρεί το privilege
.
Αυτή η γάντζος επιτρέπει την παρεμβολή σε όλες τις κλήσεις συστήματος. Στο bsd/dev/[i386|arm]/systemcalls.c
είναι δυνατή η προβολή της δηλωμένης συνάρτησης unix_syscall
, η οποία περιέχει αυτόν τον κώδικα:
Ποιο θα ελέγξει στη διαδικασία κλήσης bitmask αν η τρέχουσα syscall θα πρέπει να καλέσει mac_proc_check_syscall_unix
. Αυτό συμβαίνει επειδή οι syscalls καλούνται τόσο συχνά που είναι ενδιαφέρον να αποφευχθεί η κλήση του mac_proc_check_syscall_unix
κάθε φορά.
Σημειώστε ότι η συνάρτηση proc_set_syscall_filter_mask()
, η οποία ρυθμίζει το bitmask syscalls σε μια διαδικασία, καλείται από το Sandbox για να ρυθμίσει μάσκες σε διαδικασίες που είναι σε sandbox.
Είναι δυνατόν να αλληλεπιδράσετε με το MACF μέσω ορισμένων syscalls που ορίζονται στο security/mac.h:
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Εκπαίδευση AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Εκπαίδευση GCP Red Team Expert (GRTE)