macOS MACF
Temel Bilgiler
MACF, Zorunlu Erişim Kontrol Çerçevesi anlamına gelir ve bilgisayarınızı korumaya yardımcı olmak için işletim sistemine entegre edilmiş bir güvenlik sistemidir. Belirli sistem bölümlerine (dosyalar, uygulamalar ve sistem kaynakları gibi) kimin veya neyin erişebileceği hakkında katı kurallar belirleyerek çalışır. Bu kuralları otomatik olarak uygulayarak, MACF yalnızca yetkili kullanıcıların ve süreçlerin belirli eylemleri gerçekleştirmesine izin verir, yetkisiz erişim veya kötü niyetli faaliyetler riskini azaltır.
MACF'nin gerçekten herhangi bir karar vermediğini, yalnızca eylemleri yakaladığını ve kararları çağırdığı politika modüllerine (kernel uzantıları) bıraktığını unutmayın; bunlar arasında AppleMobileFileIntegrity.kext
, Quarantine.kext
, Sandbox.kext
, TMSafetyNet.kext
ve mcxalr.kext
bulunmaktadır.
Akış
Süreç bir syscall/mach tuzağı gerçekleştirir
İlgili işlev kernel içinde çağrılır
İşlev MACF'yi çağırır
MACF, o işlevi politikalarına bağlamak için talep eden politika modüllerini kontrol eder
MACF, ilgili politikaları çağırır
Politikalar, eylemi izin verip vermeyeceklerini belirtir
Apple, MAC Framework KPI'sini kullanabilen tek kişidir.
Etiketler
MACF, ardından politikaların bazı erişim izni verip vermeyeceğini kontrol edeceği etiketler kullanır. Etiketlerin yapı tanımının kodu burada bulunabilir; bu, struct ucred
içinde burada cr_label
kısmında kullanılır. Etiket, MACF politikalarının işaretçi ayırmak için kullanabileceği bayraklar ve bir dizi slot içerir. Örneğin, Sandbox konteyner profilini işaret edecektir.
MACF Politikaları
Bir MACF Politikası, belirli kernel işlemlerinde uygulanacak kural ve koşulları tanımlar.
Bir kernel uzantısı, mac_policy_conf
yapısını yapılandırabilir ve ardından mac_policy_register
çağrısını yaparak kaydedebilir. Buradan:
Kernel uzantılarını bu politikaları yapılandırırken mac_policy_register
çağrılarına bakarak kolayca tanımlamak mümkündür. Ayrıca, uzantının ayrıştırmasını kontrol ederek kullanılan mac_policy_conf
yapısını bulmak da mümkündür.
MACF politikalarının dinamik olarak kaydedilebileceğini ve kaydının iptal edilebileceğini unutmayın.
mac_policy_conf
'nin ana alanlarından biri mpc_ops
'dir. Bu alan, politikanın ilgilendiği işlemleri belirtir. Bunların yüzlercesi olduğunu unutmayın, bu nedenle hepsini sıfırlamak ve ardından politikanın ilgilendiği yalnızca belirli olanları seçmek mümkündür. Buradan:
Hemen hemen tüm hook'lar, bu işlemlerden biri engellendiğinde MACF tarafından geri çağrılacaktır. Ancak, mpo_policy_*
hook'ları bir istisnadır çünkü mpo_hook_policy_init()
kayıt sırasında çağrılan bir geri çağrıdır (yani mac_policy_register()
sonrasında) ve mpo_hook_policy_initbsd()
BSD alt sistemi düzgün bir şekilde başlatıldığında geç kayıt sırasında çağrılır.
Ayrıca, mpo_policy_syscall
hook'u, özel bir ioctl tarzı çağrı arayüzü sunmak için herhangi bir kext tarafından kaydedilebilir. Ardından, bir kullanıcı istemcisi, politika adı ile bir tamsayı kodunu ve isteğe bağlı argümanları belirterek mac_syscall
(#381) çağrısı yapabilecektir.
Örneğin, Sandbox.kext
bunu çok kullanır.
Kext'in __DATA.__const*
kontrol edilerek, politikanın kaydedilmesinde kullanılan mac_policy_ops
yapısını tanımlamak mümkündür. Bunu bulmak mümkündür çünkü işaretçisi mpo_policy_conf
içinde bir ofsettedir ve ayrıca o alanda bulunacak NULL işaretçi sayısı nedeniyle.
Ayrıca, her kaydedilen politika ile güncellenen _mac_policy_list
yapısını bellekten dökerek bir politikayı yapılandırmış kext'lerin listesini almak da mümkündür.
MACF Başlatma
MACF çok kısa bir süre içinde başlatılır. XNU'nun bootstrap_thread
'inde ayarlanır: ipc_bootstrap
'tan sonra mac_policy_init()
çağrısı yapılır, bu da mac_policy_list
'i başlatır ve kısa bir süre sonra mac_policy_initmach()
çağrılır. Bu işlev, ALF.kext
, AppleMobileFileIntegrity.kext
, Quarantine.kext
, Sandbox.kext
ve TMSafetyNet.kext
gibi Info.plist'lerinde AppleSecurityExtension
anahtarına sahip tüm Apple kext'lerini alır ve yükler.
MACF Çağrıları
Kodda #if CONFIG_MAC
koşullu blokları gibi MACF'ye yapılan çağrılar bulmak yaygındır. Ayrıca, bu blokların içinde belirli eylemleri gerçekleştirmek için izinleri kontrol etmek amacıyla MACF'yi çağıran mac_proc_check*
çağrılarına rastlamak mümkündür. Ayrıca, MACF çağrılarının formatı: mac_<object>_<opType>_opName
şeklindedir.
Nesne aşağıdakilerden biridir: bpfdesc
, cred
, file
, proc
, vnode
, mount
, devfs
, ifnet
, inpcb
, mbuf
, ipq
, pipe
, sysv[msg/msq/shm/sem]
, posix[shm/sem]
, socket
, kext
.
opType
genellikle eylemi izin vermek veya reddetmek için kullanılacak olan kontrol'dür. Ancak, kext'in verilen eyleme tepki vermesine izin verecek olan notify
'yi de bulmak mümkündür.
Bir örneği https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_mman.c#L621 adresinde bulabilirsiniz:
Ardından, mac_file_check_mmap
kodunu https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/security/mac_file.c#L174 adresinde bulmak mümkündür.
MAC_CHECK
makrosunu çağıran, kodu https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/security/mac_internal.h#L261 adresinde bulunabilir.
Hangi, tüm kayıtlı mac politikalarını çağırarak işlevlerini çalıştıracak ve çıktıyı hata değişkeninde depolayacak, bu değişken yalnızca başarı kodları ile mac_error_select
tarafından geçersiz kılınabilir, bu nedenle herhangi bir kontrol başarısız olursa, tüm kontrol başarısız olacak ve işlem izin verilmeyecektir.
Ancak, tüm MACF çağrılarının yalnızca eylemleri reddetmek için kullanılmadığını unutmayın. Örneğin, mac_priv_grant
makrosunu çağırır MAC_GRANT, bu, herhangi bir politikanın 0 ile yanıt vermesi durumunda talep edilen ayrıcalığı verecektir:
priv_check & priv_grant
Bu çağrılar, bsd/sys/priv.h dosyasında tanımlanan (onlarca) ayrıcalığı kontrol etmek ve sağlamak için tasarlanmıştır.
Bazı çekirdek kodları, sürecin KAuth kimlik bilgileri ile priv_check_cred()
çağrısını bsd/kern/kern_priv.c dosyasından yapar ve ayrıcalık kodlarından birini kullanarak mac_priv_check
çağrısını yapar; bu, herhangi bir politikanın ayrıcalığı vermeyi reddedip etmediğini kontrol eder ve ardından mac_priv_grant
çağrısını yaparak herhangi bir politikanın ayrıcalığı
verip vermediğini kontrol eder.
proc_check_syscall_unix
Bu kanca, tüm sistem çağrılarını yakalamaya olanak tanır. bsd/dev/[i386|arm]/systemcalls.c
dosyasında, bu kodu içeren tanımlı fonksiyonu unix_syscall
görebilirsiniz:
Hangi çağıran süreçte bitmask kontrol edilecektir, eğer mevcut syscall mac_proc_check_syscall_unix
çağırması gerekiyorsa. Bunun nedeni, syscalls'ın bu kadar sık çağrılmasıdır, bu yüzden mac_proc_check_syscall_unix
'i her seferinde çağırmaktan kaçınmak ilginçtir.
proc_set_syscall_filter_mask()
fonksiyonunun, bir süreçteki bitmask syscalls'ı ayarlamak için Sandbox tarafından çağrıldığını unutmayın; bu, sandboxed süreçlerde maskeleri ayarlamak içindir.
Açık MACF syscalls
MACF ile etkileşimde bulunmak, security/mac.h dosyasında tanımlanan bazı syscalls aracılığıyla mümkündür:
Referanslar
Last updated