
Preuve de concept pour CVE-2023-41992, une vulnérabilité du noyau macOS, démontrant des techniques d'exploitation et fournissant une analyse du correctif.
Ceci est une preuve de concept pour CVE-2023-41992. Et avant tout, cela n'a rien à voir avec jailbreak ! Et il est encore en développement.
Merci à tous ceux qui m'ont aidé jusqu'à présent. Pour des raisons de confidentialité, je ne peux pas vous lister ici. Envoyez-moi un message privé si vous le souhaitez !
Pour autant que je sache, le correctif se trouve dans ipc_right_destroy. Quelqu'un l'a également signalé sur X (ou Twitter).
diff --git a/osfmk/ipc/ipc_right.c b/osfmk/ipc/ipc_right.c
index a81ac21..32a9a3e 100644
--- a/osfmk/ipc/ipc_right.c
+++ b/osfmk/ipc/ipc_right.c
@@ -912,7 +912,6 @@ ipc_right_destroy(
mach_port_type_t type;
bits = entry->ie_bits;
- entry->ie_bits &= ~IE_BITS_TYPE_MASK;
type = IE_BITS_TYPE(bits);
assert(is_active(space));
Utiliser ipc_right_destroy pour obtenir une entrée ipc de type aucun laissée dans l'espace ipc déclencherait une exception. Voir [0] et [1] ci-dessous.
kern_return_t
ipc_right_destroy(
ipc_space_t space,
mach_port_name_t name,
ipc_entry_t entry,
boolean_t check_guard,
uint64_t guard)
{
...
if (type == MACH_PORT_TYPE_SEND) {
if (ip_is_pinned(port)) {
assert(ip_active(port));
is_write_unlock(space);
mach_port_guard_exception_pinned(space, // <---- [0]
name, port, MPG_FLAGS_MOD_REFS_PINNED_DESTROY);
return KERN_INVALID_CAPABILITY;
}
ipc_hash_delete(space, ip_to_object(port), name, entry);
}
...
if ((type & MACH_PORT_TYPE_RECEIVE) &&
(check_guard) && (port->ip_guarded) &&
(guard != port->ip_context)) {
/* Guard Violation */
uint64_t portguard = port->ip_context;
ip_mq_unlock(port);
is_write_unlock(space);
/* Raise mach port guard exception */
mach_port_guard_exception(name, // <---- [1]
0, portguard, kGUARD_EXC_DESTROY);
return KERN_INVALID_RIGHT;
}
[0] ne tuera pas la tâche dans le bac à sable des applications tierces. J'ai choisi mach_thread_self() auparavant parce que c'est le seul droit d'envoi épinglé que j'ai pu trouver.
Mais sans éviter ReportCrash ou SIGKILL, le bug ne sera pas utile dans le bac à sable WebContent. J'ai donc creusé un peu plus.
void
mach_port_guard_ast(thread_t t,
mach_exception_data_type_t code, mach_exception_data_type_t subcode)
{
...
if (reason <= MAX_FATAL_kGUARD_EXC_CODE) {
/*
* Fatal Mach port guards - always delivered synchronously.
* Check if anyone has registered for Synchronous EXC_GUARD, if yes then,
* deliver it synchronously and then kill the process, else kill the process
* and deliver the exception via EXC_CORPSE_NOTIFY.
*/
if (task_exception_notify(EXC_GUARD, code, subcode) == KERN_SUCCESS) {
task_bsdtask_kill(task);
} else {
exit_with_guard_exception(get_bsdtask_info(task), code, subcode);
}
...
mach_port_guard_ast dans le noyau gère les exceptions de garde de port mach. Pour une exception fatale, il cherche d'abord le port d'exception. Si la notification d'exception renvoie KERN_SUCCESS, effectuez un SIGKILL. Cela semble prometteur, chaque tâche qui a déclenché une exception fatale de garde de port mach sera tuée. Cependant...
Les gardes de port Mach fatales - toujours délivrées de manière synchrone.
Je peux simplement définir un port d'exception de thread pour le thread qui déclenche le bug, et ne pas traiter la notification d'exception. Le noyau attendra simplement une réponse ici, pas de SIGKILL.
Panique dans ipc_right_copyout() avec une entrée NULL.