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 steht für Mandatory Access Control Framework, ein Sicherheitssystem, das in das Betriebssystem integriert ist, um Ihren Computer zu schützen. Es funktioniert, indem es strenge Regeln festlegt, wer oder was auf bestimmte Teile des Systems zugreifen kann, wie Dateien, Anwendungen und Systemressourcen. Durch die automatische Durchsetzung dieser Regeln stellt MACF sicher, dass nur autorisierte Benutzer und Prozesse bestimmte Aktionen ausführen können, wodurch das Risiko unbefugten Zugriffs oder böswilliger Aktivitäten verringert wird.
Beachten Sie, dass MACF keine Entscheidungen trifft, da es lediglich Aktionen abfängt; die Entscheidungen überlässt es den Richtlinienmodulen (Kernel-Erweiterungen), die es aufruft, wie AppleMobileFileIntegrity.kext
, Quarantine.kext
, Sandbox.kext
, TMSafetyNet.kext
und mcxalr.kext
.
Prozess führt einen syscall/mach trap aus
Die relevante Funktion wird im Kernel aufgerufen
Funktion ruft MACF auf
MACF überprüft die Richtlinienmodule, die angefordert haben, diese Funktion in ihrer Richtlinie zu hooken
MACF ruft die relevanten Richtlinien auf
Richtlinien geben an, ob sie die Aktion erlauben oder ablehnen
Apple ist der einzige, der das MAC Framework KPI verwenden kann.
MACF verwendet Labels, die dann von den Richtlinien überprüft werden, um zu entscheiden, ob sie den Zugriff gewähren sollen oder nicht. Der Code der Label-Strukturdeklaration kann hier gefunden werden, der dann innerhalb der struct ucred
hier im cr_label
-Teil verwendet wird. Das Label enthält Flags und eine Anzahl von Slots, die von MACF-Richtlinien zur Zuweisung von Zeigern verwendet werden können. Zum Beispiel wird Sandbox auf das Containerprofil verweisen.
Eine MACF-Richtlinie definiert Regeln und Bedingungen, die auf bestimmte Kerneloperationen angewendet werden.
Eine Kernel-Erweiterung könnte eine mac_policy_conf
-Struktur konfigurieren und sie dann registrieren, indem sie mac_policy_register
aufruft. Von hier:
Es ist einfach, die Kernel-Erweiterungen, die diese Richtlinien konfigurieren, zu identifizieren, indem man die Aufrufe von mac_policy_register
überprüft. Darüber hinaus ist es auch möglich, beim Disassemblieren der Erweiterung die verwendete mac_policy_conf
-Struktur zu finden.
Beachten Sie, dass MACF-Richtlinien auch dynamisch registriert und deregistriert werden können.
Eines der Hauptfelder der mac_policy_conf
ist das mpc_ops
. Dieses Feld gibt an, an welchen Operationen die Richtlinie interessiert ist. Beachten Sie, dass es Hunderte davon gibt, sodass es möglich ist, alle auf Null zu setzen und dann nur die auszuwählen, an denen die Richtlinie interessiert ist. Von hier:
Fast alle Hooks werden von MACF zurückgerufen, wenn eine dieser Operationen abgefangen wird. Die mpo_policy_*
Hooks sind jedoch eine Ausnahme, da mpo_hook_policy_init()
ein Callback ist, das bei der Registrierung aufgerufen wird (also nach mac_policy_register()
) und mpo_hook_policy_initbsd()
während der späten Registrierung aufgerufen wird, sobald das BSD-Subsystem ordnungsgemäß initialisiert wurde.
Darüber hinaus kann der mpo_policy_syscall
Hook von jedem Kext registriert werden, um einen privaten ioctl-ähnlichen Schnittstellen-Aufruf bereitzustellen. Dann kann ein Benutzer-Client mac_syscall
(#381) aufrufen und als Parameter den Policy-Namen mit einem ganzzahligen Code und optionalen Argumenten angeben.
Zum Beispiel verwendet Sandbox.kext
dies häufig.
Durch Überprüfung des __DATA.__const*
des Kexts ist es möglich, die mac_policy_ops
-Struktur zu identifizieren, die bei der Registrierung der Policy verwendet wird. Es ist möglich, sie zu finden, da ihr Zeiger an einem Offset innerhalb von mpo_policy_conf
liegt und auch aufgrund der Anzahl der NULL-Zeiger, die sich in diesem Bereich befinden werden.
Darüber hinaus ist es auch möglich, die Liste der Kexts zu erhalten, die eine Policy konfiguriert haben, indem man die Struktur _mac_policy_list
aus dem Speicher dumpet, die mit jeder registrierten Policy aktualisiert wird.
MACF wird sehr früh initialisiert. Es wird im bootstrap_thread
von XNU eingerichtet: nach ipc_bootstrap
erfolgt ein Aufruf von mac_policy_init()
, der die mac_policy_list
initialisiert, und kurz darauf wird mac_policy_initmach()
aufgerufen. Unter anderem wird diese Funktion alle Apple-Kexts mit dem Schlüssel AppleSecurityExtension
in ihrer Info.plist wie ALF.kext
, AppleMobileFileIntegrity.kext
, Quarantine.kext
, Sandbox.kext
und TMSafetyNet.kext
abrufen und laden.
Es ist üblich, Callouts zu MACF in Code zu finden, wie: #if CONFIG_MAC
bedingte Blöcke. Darüber hinaus ist es innerhalb dieser Blöcke möglich, Aufrufe von mac_proc_check*
zu finden, die MACF aufrufen, um Berechtigungen zu überprüfen, um bestimmte Aktionen durchzuführen. Darüber hinaus hat das Format der MACF-Callouts die Form: mac_<object>_<opType>_opName
.
Das Objekt ist eines der folgenden: bpfdesc
, cred
, file
, proc
, vnode
, mount
, devfs
, ifnet
, inpcb
, mbuf
, ipq
, pipe
, sysv[msg/msq/shm/sem]
, posix[shm/sem]
, socket
, kext
.
Der opType
ist normalerweise check, der verwendet wird, um die Aktion zu erlauben oder abzulehnen. Es ist jedoch auch möglich, notify
zu finden, was dem Kext erlaubt, auf die gegebene Aktion zu reagieren.
Ein Beispiel finden Sie unter https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_mman.c#L621:
Dann ist es möglich, den Code von mac_file_check_mmap
unter https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/security/mac_file.c#L174 zu finden.
Welches das MAC_CHECK
-Makro aufruft, dessen Code in https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/security/mac_internal.h#L261 gefunden werden kann.
Welche alle registrierten mac Richtlinien aufruft, ihre Funktionen aufruft und die Ausgabe in der Fehler-Variable speichert, die nur von mac_error_select
durch Erfolgscodes überschreibbar ist, sodass, wenn eine Überprüfung fehlschlägt, die gesamte Überprüfung fehlschlägt und die Aktion nicht erlaubt wird.
Denken Sie jedoch daran, dass nicht alle MACF-Callouts nur verwendet werden, um Aktionen zu verweigern. Zum Beispiel ruft mac_priv_grant
das Makro MAC_GRANT auf, das das angeforderte Privileg gewährt, wenn eine Richtlinie mit einer 0 antwortet:
Diese Aufrufe dienen dazu, (Dutzende von) Berechtigungen zu überprüfen und bereitzustellen, die in bsd/sys/priv.h definiert sind.
Einige Kernel-Codes würden priv_check_cred()
aus bsd/kern/kern_priv.c mit den KAuth-Anmeldeinformationen des Prozesses und einem der Berechtigungs-Codes aufrufen, der mac_priv_check
aufruft, um zu sehen, ob eine Richtlinie die Gewährung der Berechtigung verweigert und dann wird mac_priv_grant
aufgerufen, um zu sehen, ob eine Richtlinie die Berechtigung
gewährt.
Dieser Hook ermöglicht es, alle Systemaufrufe abzufangen. In bsd/dev/[i386|arm]/systemcalls.c
ist es möglich, die deklarierte Funktion unix_syscall
zu sehen, die diesen Code enthält:
Welche im aufrufenden Prozess Bitmaske überprüft, ob der aktuelle Syscall mac_proc_check_syscall_unix
aufrufen sollte. Dies liegt daran, dass Syscalls so häufig aufgerufen werden, dass es interessant ist, zu vermeiden, mac_proc_check_syscall_unix
jedes Mal aufzurufen.
Beachten Sie, dass die Funktion proc_set_syscall_filter_mask()
, die die Bitmaske für Syscalls in einem Prozess festlegt, von Sandbox aufgerufen wird, um Masken für sandboxed Prozesse festzulegen.
Es ist möglich, über einige in security/mac.h definierte Syscalls mit MACF zu interagieren:
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)