macOS MACF

Reading time: 16 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Informations de base

MACF signifie Mandatory Access Control Framework, qui est un systÚme de sécurité intégré au systÚme d'exploitation pour aider à protéger votre ordinateur. Il fonctionne en définissant des rÚgles strictes sur qui ou quoi peut accéder à certaines parties du systÚme, comme les fichiers, les applications et les ressources systÚme. En appliquant automatiquement ces rÚgles, MACF garantit que seuls les utilisateurs et processus autorisés peuvent effectuer des actions spécifiques, réduisant ainsi le risque d'accÚs non autorisé ou d'activités malveillantes.

Notez que MACF ne prend pas réellement de décisions puisqu'il se contente d'intercepter les actions ; il laisse les décisions aux modules de politique (extensions du noyau) qu'il appelle, comme AppleMobileFileIntegrity.kext, Quarantine.kext, Sandbox.kext, TMSafetyNet.kext et mcxalr.kext.

  • Une policy peut ĂȘtre en mode enforcement (retourne 0 ou non-zĂ©ro sur une opĂ©ration)
  • Une policy peut ĂȘtre en mode monitoring (retourne 0, n'objecte pas mais profite du hook pour faire quelque chose)
  • Une MACF static policy est installĂ©e au boot et NE SERA JAMAIS retirĂ©e
  • Une MACF dynamic policy est installĂ©e par une KEXT (kextload) et peut hypothĂ©tiquement ĂȘtre kextunloaded
  • Sur iOS seules les policies statiques sont autorisĂ©es et sur macOS statiques + dynamiques.
  • https://newosxbook.com/xxr/index.php

Flux

  1. Un processus effectue un syscall/mach trap
  2. La fonction pertinente est appelée à l'intérieur du noyau
  3. La fonction appelle MACF
  4. MACF vérifie les modules de policy qui ont demandé à hooker cette fonction dans leur policy
  5. MACF appelle les policies concernées
  6. Les policies indiquent si elles autorisent ou refusent l'action

caution

Apple est la seule entité pouvant utiliser le MAC Framework KPI.

Généralement, les fonctions vérifiant les permissions avec MACF appellent la macro MAC_CHECK. Par exemple, dans le cas d'un syscall pour créer un socket, celui-ci appellera la fonction mac_socket_check_create qui appelle MAC_CHECK(socket_check_create, cred, domain, type, protocol);. De plus, la macro MAC_CHECK est définie dans security/mac_internal.h comme :

c
Resolver tambien MAC_POLICY_ITERATE, MAC_CHECK_CALL, MAC_CHECK_RSLT


#define MAC_CHECK(check, args...) do {                                   \
error = 0;                                                           \
MAC_POLICY_ITERATE({                                                 \
if (mpc->mpc_ops->mpo_ ## check != NULL) {                   \
MAC_CHECK_CALL(check, mpc);                          \
int __step_err = mpc->mpc_ops->mpo_ ## check (args); \
MAC_CHECK_RSLT(check, mpc);                          \
error = mac_error_select(__step_err, error);         \
}                                                            \
});                                                                  \
} while (0)

Notez que, en transformant check en socket_check_create et args... par (cred, domain, type, protocol), vous obtenez :

c
// Note the "##" just get the param name and append it to the prefix
#define MAC_CHECK(socket_check_create, args...) do {                                   \
error = 0;                                                           \
MAC_POLICY_ITERATE({                                                 \
if (mpc->mpc_ops->mpo_socket_check_create != NULL) {                   \
MAC_CHECK_CALL(socket_check_create, mpc);                          \
int __step_err = mpc->mpc_ops->mpo_socket_check_create (args); \
MAC_CHECK_RSLT(socket_check_create, mpc);                          \
error = mac_error_select(__step_err, error);         \
}                                                            \
});                                                                  \
} while (0)

L'expansion des macros utilitaires montre le flux de contrĂŽle concret :

c
do {                                                // MAC_CHECK
error = 0;
do {                                            // MAC_POLICY_ITERATE
struct mac_policy_conf *mpc;
u_int i;
for (i = 0; i < mac_policy_list.staticmax; i++) {
mpc = mac_policy_list.entries[i].mpc;
if (mpc == NULL) {
continue;
}
if (mpc->mpc_ops->mpo_socket_check_create != NULL) {
DTRACE_MACF3(mac__call__socket_check_create,
void *, mpc, int, error, int, MAC_ITERATE_CHECK); // MAC_CHECK_CALL
int __step_err = mpc->mpc_ops->mpo_socket_check_create(args);
DTRACE_MACF2(mac__rslt__socket_check_create,
void *, mpc, int, __step_err);                    // MAC_CHECK_RSLT
error = mac_error_select(__step_err, error);
}
}
if (mac_policy_list_conditional_busy() != 0) {
for (; i <= mac_policy_list.maxindex; i++) {
mpc = mac_policy_list.entries[i].mpc;
if (mpc == NULL) {
continue;
}
if (mpc->mpc_ops->mpo_socket_check_create != NULL) {
DTRACE_MACF3(mac__call__socket_check_create,
void *, mpc, int, error, int, MAC_ITERATE_CHECK);
int __step_err = mpc->mpc_ops->mpo_socket_check_create(args);
DTRACE_MACF2(mac__rslt__socket_check_create,
void *, mpc, int, __step_err);
error = mac_error_select(__step_err, error);
}
}
mac_policy_list_unbusy();
}
} while (0);
} while (0);

Autrement dit, MAC_CHECK(socket_check_create, ...) parcourt d'abord les politiques statiques, verrouille conditionnellement et itÚre sur les politiques dynamiques, émet les probes DTrace autour de chaque hook, et rassemble le code de retour de chaque hook en un seul résultat error via mac_error_select().

Étiquettes

MACF utilise des labels que les politiques vĂ©rifiant si elles doivent accorder un accĂšs ou non utiliseront. Le code de la dĂ©claration de la struct labels peut ĂȘtre trouvĂ© ici, qui est ensuite utilisĂ© Ă  l’intĂ©rieur de la struct ucred dans ici dans la partie cr_label. Le label contient des flags et un nombre de slots qui peuvent ĂȘtre utilisĂ©s par les politiques MACF pour allouer des pointeurs. Par exemple Sandbox pointera vers le profil du conteneur

Politiques MACF

Une politique MACF définit des rÚgles et conditions à appliquer lors de certaines opérations du noyau.

Une extension du noyau peut configurer une mac_policy_conf struct puis l'enregistrer en appelant mac_policy_register. Extrait de ici:

c
#define mpc_t	struct mac_policy_conf *

/**
@brief Mac policy configuration

This structure specifies the configuration information for a
MAC policy module.  A policy module developer must supply
a short unique policy name, a more descriptive full name, a list of label
namespaces and count, a pointer to the registered enty point operations,
any load time flags, and optionally, a pointer to a label slot identifier.

The Framework will update the runtime flags (mpc_runtime_flags) to
indicate that the module has been registered.

If the label slot identifier (mpc_field_off) is NULL, the Framework
will not provide label storage for the policy.  Otherwise, the
Framework will store the label location (slot) in this field.

The mpc_list field is used by the Framework and should not be
modified by policies.
*/
/* XXX - reorder these for better aligment on 64bit platforms */
struct mac_policy_conf {
const char		*mpc_name;		/** policy name */
const char		*mpc_fullname;		/** full name */
const char		**mpc_labelnames;	/** managed label namespaces */
unsigned int		 mpc_labelname_count;	/** number of managed label namespaces */
struct mac_policy_ops	*mpc_ops;		/** operation vector */
int			 mpc_loadtime_flags;	/** load time flags */
int			*mpc_field_off;		/** label slot */
int			 mpc_runtime_flags;	/** run time flags */
mpc_t			 mpc_list;		/** List reference */
void			*mpc_data;		/** module data */
};

Il est facile d'identifier les kernel extensions configurant ces politiques en vérifiant les appels à mac_policy_register. De plus, en vérifiant le désassemblage de l'extension, il est également possible de trouver la structure mac_policy_conf utilisée.

Notez que les politiques MACF peuvent ĂȘtre enregistrĂ©es et dĂ©senregistrĂ©es Ă©galement dynamiquement.

Un des champs principaux de la mac_policy_conf est mpc_ops. Ce champ spécifie quelles opérations intéressent la politique. Notez qu'il y en a des centaines, il est donc possible de tout mettre à zéro puis de ne sélectionner que celles qui intéressent la politique. Depuis here:

c
struct mac_policy_ops {
mpo_audit_check_postselect_t		*mpo_audit_check_postselect;
mpo_audit_check_preselect_t		*mpo_audit_check_preselect;
mpo_bpfdesc_label_associate_t		*mpo_bpfdesc_label_associate;
mpo_bpfdesc_label_destroy_t		*mpo_bpfdesc_label_destroy;
mpo_bpfdesc_label_init_t		*mpo_bpfdesc_label_init;
mpo_bpfdesc_check_receive_t		*mpo_bpfdesc_check_receive;
mpo_cred_check_label_update_execve_t	*mpo_cred_check_label_update_execve;
mpo_cred_check_label_update_t		*mpo_cred_check_label_update;
[...]

Presque tous les hooks seront rappelés par MACF lorsqu'une de ces opérations est interceptée. Cependant, les hooks mpo_policy_* font exception car mpo_hook_policy_init() est un callback appelé lors de l'enregistrement (donc aprÚs mac_policy_register()) et mpo_hook_policy_initbsd() est appelé pendant un enregistrement tardif une fois que le sous-systÚme BSD s'est correctement initialisé.

De plus, le hook mpo_policy_syscall peut ĂȘtre enregistrĂ© par n'importe quel kext pour exposer un appel privĂ© de type ioctl en interface. Ensuite, un user client pourra appeler mac_syscall (#381) en spĂ©cifiant comme paramĂštres le policy name avec un entier code et des arguments optionnels.
Par exemple, le Sandbox.kext utilise beaucoup cela.

En vérifiant le kext's __DATA.__const*, il est possible d'identifier la structure mac_policy_ops utilisée lors de l'enregistrement de la policy. On peut la trouver car son pointeur est à un offset à l'intérieur de mpo_policy_conf et aussi à cause du nombre de pointeurs NULL présents dans cette zone.

De plus, il est aussi possible d'obtenir la liste des kexts qui ont configuré une policy en dumpant depuis la mémoire la struct _mac_policy_list qui est mise à jour à chaque policy enregistrée.

Vous pouvez aussi utiliser l'outil xnoop pour dumper toutes les policies enregistrées dans le systÚme:

bash
xnoop offline .

Xn👀p> macp
mac_policy_list(@0xfffffff0447159b8): 3 Mac Policies@0xfffffff0447153f0
0: 0xfffffff044886f18:
mpc_name: AppleImage4
mpc_fullName: AppleImage4 hooks
mpc_ops: mac_policy_ops@0xfffffff044886f68
1: 0xfffffff0448d7d40:
mpc_name: AMFI
mpc_fullName: Apple Mobile File Integrity
mpc_ops: mac_policy_ops@0xfffffff0448d72c8
2: 0xfffffff044b0b950:
mpc_name: Sandbox
mpc_fullName: Seatbelt sandbox policy
mpc_ops: mac_policy_ops@0xfffffff044b0b9b0
Xn👀p> dump mac_policy_opns@0xfffffff0448d72c8
Type 'struct mac_policy_opns' is unrecognized - dumping as raw 64 bytes
Dumping 64 bytes from 0xfffffff0448d72c8

Ensuite, dump all the checks de check policy avec :

bash
Xn👀p> dump mac_policy_ops@0xfffffff044b0b9b0
Dumping 2696 bytes from 0xfffffff044b0b9b0 (as struct mac_policy_ops)

mpo_cred_check_label_update_execve(@0x30): 0xfffffff046d7fb54(PACed)
mpo_cred_check_label_update(@0x38): 0xfffffff046d7348c(PACed)
mpo_cred_label_associate(@0x58): 0xfffffff046d733f0(PACed)
mpo_cred_label_destroy(@0x68): 0xfffffff046d733e4(PACed)
mpo_cred_label_update_execve(@0x90): 0xfffffff046d7fb60(PACed)
mpo_cred_label_update(@0x98): 0xfffffff046d73370(PACed)
mpo_file_check_fcntl(@0xe8): 0xfffffff046d73164(PACed)
mpo_file_check_lock(@0x110): 0xfffffff046d7309c(PACed)
mpo_file_check_mmap(@0x120): 0xfffffff046d72fc4(PACed)
mpo_file_check_set(@0x130): 0xfffffff046d72f2c(PACed)
mpo_reserved08(@0x168): 0xfffffff046d72e3c(PACed)
mpo_reserved09(@0x170): 0xfffffff046d72e34(PACed)
mpo_necp_check_open(@0x1f0): 0xfffffff046d72d9c(PACed)
mpo_necp_check_client_action(@0x1f8): 0xfffffff046d72cf8(PACed)
mpo_vnode_notify_setextattr(@0x218): 0xfffffff046d72ca4(PACed)
mpo_vnode_notify_setflags(@0x220): 0xfffffff046d72c84(PACed)
mpo_proc_check_get_task_special_port(@0x250): 0xfffffff046d72b98(PACed)
mpo_proc_check_set_task_special_port(@0x258): 0xfffffff046d72ab4(PACed)
mpo_vnode_notify_unlink(@0x268): 0xfffffff046d72958(PACed)
mpo_vnode_check_copyfile(@0x290): 0xfffffff046d726c0(PACed)
mpo_mount_check_quotactl(@0x298): 0xfffffff046d725c4(PACed)
...

MACF initialization in XNU

Early bootstrap and mac_policy_init()

  • MACF est initialisĂ© trĂšs tĂŽt. Dans bootstrap_thread (dans le code de dĂ©marrage XNU), aprĂšs ipc_bootstrap, XNU appelle mac_policy_init() (dans mac_base.c).
  • mac_policy_init() initialise la mac_policy_list globale (un tableau ou une liste d'emplacements de policy) et met en place l'infrastructure pour le MAC (Mandatory Access Control) au sein d'XNU.
  • Plus tard, mac_policy_initmach() est invoquĂ©, ce qui gĂšre le cĂŽtĂ© noyau de l'enregistrement des policies pour les policies intĂ©grĂ©es ou empaquetĂ©es.

mac_policy_initmach() and loading “security extensions”

  • mac_policy_initmach() examine les kernel extensions (kexts) qui sont prĂ©chargĂ©s (ou dans une liste de “policy injection”) et inspecte leur Info.plist pour la clĂ© AppleSecurityExtension.

  • Les kexts qui dĂ©clarent <key>AppleSecurityExtension</key> (ou true) dans leur Info.plist sont considĂ©rĂ©s comme des « security extensions » — c.-Ă -d. ceux qui implĂ©mentent une MAC policy ou s'accrochent Ă  l'infrastructure MACF.

  • Des exemples de kexts Apple avec cette clĂ© incluent ALF.kext, AppleMobileFileIntegrity.kext (AMFI), Sandbox.kext, Quarantine.kext, TMSafetyNet.kext, CoreTrust.kext, AppleSystemPolicy.kext, parmi d'autres (comme vous l'avez dĂ©jĂ  listĂ©).

  • Le noyau s'assure que ces kexts sont chargĂ©s tĂŽt, puis appelle leurs routines d'enregistrement (via mac_policy_register) pendant le boot, les insĂ©rant dans la mac_policy_list.

  • Chaque module de policy (kext) fournit une structure mac_policy_conf, avec des hooks (mpc_ops) pour diverses opĂ©rations MAC (vnode checks, exec checks, mises Ă  jour de labels, etc.).

  • Les flags de load time peuvent inclure MPC_LOADTIME_FLAG_NOTLATE signifiant « doit ĂȘtre chargĂ© tĂŽt » (ainsi les tentatives d'enregistrement tardives sont rejetĂ©es).

  • Une fois enregistrĂ©, chaque module obtient un handle et occupe un emplacement dans la mac_policy_list.

  • Lorsqu'un hook MAC est invoquĂ© plus tard (par exemple, accĂšs vnode, exec, etc.), MACF itĂšre sur toutes les policies enregistrĂ©es pour prendre des dĂ©cisions collectives.

  • En particulier, AMFI (Apple Mobile File Integrity) est une telle security extension. Son Info.plist inclut AppleSecurityExtension le marquant comme une policy de sĂ©curitĂ©.

  • Dans le cadre du boot du noyau, la logique de chargement du noyau s'assure que la “security policy” (AMFI, etc.) est dĂ©jĂ  active avant que de nombreux sous-systĂšmes n'en dĂ©pendent. Par exemple, le noyau « se prĂ©pare pour les tĂąches Ă  venir en chargeant 
 la security policy, y compris AppleMobileFileIntegrity (AMFI), Sandbox, Quarantine policy. »

bash
cd /System/Library/Extensions
find . -name Info.plist | xargs grep AppleSecurityExtension 2>/dev/null

./AppleImage4.kext/Contents/Info.plist:	<key>AppleSecurityExtension</key>
./ALF.kext/Contents/Info.plist:	<key>AppleSecurityExtension</key>
./CoreTrust.kext/Contents/Info.plist:	<key>AppleSecurityExtension</key>
./AppleMobileFileIntegrity.kext/Contents/Info.plist:	<key>AppleSecurityExtension</key>
./Quarantine.kext/Contents/Info.plist:	<key>AppleSecurityExtension</key>
./Sandbox.kext/Contents/Info.plist:	<key>AppleSecurityExtension</key>
./AppleSystemPolicy.kext/Contents/Info.plist:	<key>AppleSecurityExtension</key>

KPI dependency & com.apple.kpi.dsep in MAC policy kexts

Lors de l'écriture d'un kext qui utilise le framework MAC (c.-à-d. appel à mac_policy_register() etc.), vous devez déclarer des dépendances aux KPI (Kernel Programming Interfaces) afin que le linker de kext (kxld) puisse résoudre ces symboles. Donc, pour déclarer qu'un kext dépend de MACF, vous devez l'indiquer dans l'Info.plist avec com.apple.kpi.dsep (find . Info.plist | grep AppleSecurityExtension), ensuite le kext fera référence à des symboles comme mac_policy_register, mac_policy_unregister, et des pointeurs de fonctions hook MAC. Pour résoudre ceux-ci, vous devez lister com.apple.kpi.dsep comme dépendance.

Example Info.plist snippet (inside your .kext):

xml
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.dsep</key>
<string>18.0</string>
<key>com.apple.kpi.libkern</key>
<string>18.0</string>
<key>com.apple.kpi.bsd</key>
<string>18.0</string>
<key>com.apple.kpi.mach</key>
<string>18.0</string>

 (other kpi dependencies as needed)
</dict>

Appels Ă  MACF

Il est courant de trouver des appels à MACF définis dans le code, par exemple dans des blocs conditionnels #if CONFIG_MAC. De plus, à l'intérieur de ces blocs, on peut trouver des appels à mac_proc_check* qui invoquent MACF pour vérifier les permissions nécessaires pour effectuer certaines actions. Le format des appels MACF est : mac_<object>_<opType>_opName.

L'objet est l'un des suivants : bpfdesc, cred, file, proc, vnode, mount, devfs, ifnet, inpcb, mbuf, ipq, pipe, sysv[msg/msq/shm/sem], posix[shm/sem], socket, kext.
Le opType est généralement check, qui est utilisé pour autoriser ou refuser l'action. Cependant, on peut aussi trouver notify, qui permet au kext de réagir à l'action en question.

You can find an example in https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_mman.c#L621:

int
mmap(proc_t p, struct mmap_args *uap, user_addr_t *retval)
{
[...]
#if CONFIG_MACF
			error = mac_file_check_mmap(vfs_context_ucred(ctx),
			    fp->fp_glob, prot, flags, file_pos + pageoff,
&maxprot);
if (error) {
(void)vnode_put(vp);
goto bad;
}
#endif /* MAC */
[...]

Ensuite, il est possible de trouver le code de mac_file_check_mmap dans https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/security/mac_file.c#L174

c
mac_file_check_mmap(struct ucred *cred, struct fileglob *fg, int prot,
int flags, uint64_t offset, int *maxprot)
{
int error;
int maxp;

maxp = *maxprot;
MAC_CHECK(file_check_mmap, cred, fg, NULL, prot, flags, offset, &maxp);
if ((maxp | *maxprot) != *maxprot) {
panic("file_check_mmap increased max protections");
}
*maxprot = maxp;
return error;
}

Qui appelle la macro MAC_CHECK, dont le code peut ĂȘtre trouvĂ© Ă  l'adresse https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/security/mac_internal.h#L261

c
/*
* MAC_CHECK performs the designated check by walking the policy
* module list and checking with each as to how it feels about the
* request.  Note that it returns its value via 'error' in the scope
* of the caller.
*/
#define MAC_CHECK(check, args...) do {                              \
error = 0;                                                      \
MAC_POLICY_ITERATE({                                            \
if (mpc->mpc_ops->mpo_ ## check != NULL) {              \
DTRACE_MACF3(mac__call__ ## check, void *, mpc, int, error, int, MAC_ITERATE_CHECK); \
int __step_err = mpc->mpc_ops->mpo_ ## check (args); \
DTRACE_MACF2(mac__rslt__ ## check, void *, mpc, int, __step_err); \
error = mac_error_select(__step_err, error);         \
}                                                           \
});                                                             \
} while (0)

Ce qui parcourra toutes les politiques mac enregistrĂ©es en appelant leurs fonctions et en stockant la sortie dans la variable error, qui ne pourra ĂȘtre remplacĂ©e que par mac_error_select via des codes de succĂšs ; ainsi, si un contrĂŽle Ă©choue, le contrĂŽle global Ă©chouera et l'action ne sera pas autorisĂ©e.

tip

Cependant, souvenez-vous que tous les callouts MACF ne sont pas utilisés uniquement pour refuser des actions. Par exemple, mac_priv_grant appelle la macro MAC_GRANT, qui accordera le privilÚge demandé si une politique répond par 0 :

/*
* MAC_GRANT performs the designated check by walking the policy
* module list and checking with each as to how it feels about the
* request.  Unlike MAC_CHECK, it grants if any policies return '0',
* and otherwise returns EPERM.  Note that it returns its value via
* 'error' in the scope of the caller.
*/
#define MAC_GRANT(check, args...) do {                              \
   error = EPERM;                                                  \
   MAC_POLICY_ITERATE({                                            \
	if (mpc->mpc_ops->mpo_ ## check != NULL) {                  \
	        DTRACE_MACF3(mac__call__ ## check, void *, mpc, int, error, int, MAC_ITERATE_GRANT); \
	        int __step_res = mpc->mpc_ops->mpo_ ## check (args); \
	        if (__step_res == 0) {                              \
	                error = 0;                                  \
	        }                                                   \
	        DTRACE_MACF2(mac__rslt__ ## check, void *, mpc, int, __step_res); \
	    }                                                           \
   });                                                             \
} while (0)

priv_check & priv_grant

Ces appels sont destinés à vérifier et fournir (des dizaines de) privilÚges définis dans bsd/sys/priv.h.
Certain code du noyau appellerait priv_check_cred() depuis bsd/kern/kern_priv.c avec les credentials KAuth du processus et un des codes de privilĂšges, qui appellera mac_priv_check pour voir si une politique refuse d'accorder le privilĂšge, puis il appelle mac_priv_grant pour voir si une politique accorde le privilege.

proc_check_syscall_unix

Ce hook permet d'intercepter tous les appels systÚme. Dans bsd/dev/[i386|arm]/systemcalls.c, on peut voir la fonction déclarée unix_syscall, qui contient ce code :

c
#if CONFIG_MACF
if (__improbable(proc_syscall_filter_mask(proc) != NULL && !bitstr_test(proc_syscall_filter_mask(proc), syscode))) {
error = mac_proc_check_syscall_unix(proc, syscode);
if (error) {
goto skip_syscall;
}
}
#endif /* CONFIG_MACF */

Which will check in the calling process bitmask if the current syscall should call mac_proc_check_syscall_unix. This is because syscalls are called so frequently that it's interesting to avoid calling mac_proc_check_syscall_unix every time.

Note that the function proc_set_syscall_filter_mask(), which set the bitmask syscalls in a process is called by Sandbox to set masks on sandboxed processes.

Syscalls MACF exposés

It's possible to interact with MACF through some syscalls defined in security/mac.h:

c
/*
* Extended non-POSIX.1e interfaces that offer additional services
* available from the userland and kernel MAC frameworks.
*/
#ifdef __APPLE_API_PRIVATE
__BEGIN_DECLS
int      __mac_execve(char *fname, char **argv, char **envv, mac_t _label);
int      __mac_get_fd(int _fd, mac_t _label);
int      __mac_get_file(const char *_path, mac_t _label);
int      __mac_get_link(const char *_path, mac_t _label);
int      __mac_get_pid(pid_t _pid, mac_t _label);
int      __mac_get_proc(mac_t _label);
int      __mac_set_fd(int _fildes, const mac_t _label);
int      __mac_set_file(const char *_path, mac_t _label);
int      __mac_set_link(const char *_path, mac_t _label);
int      __mac_mount(const char *type, const char *path, int flags, void *data,
struct mac *label);
int      __mac_get_mount(const char *path, struct mac *label);
int      __mac_set_proc(const mac_t _label);
int      __mac_syscall(const char *_policyname, int _call, void *_arg);
__END_DECLS
#endif /*__APPLE_API_PRIVATE*/

Références

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks