
Proof-of-concept per CVE-2023-41992, una vulnerabilità del kernel macOS, che dimostra tecniche di sfruttamento e fornisce un'analisi della patch.
Questa è una proof-of-concept per CVE-2023-41992. E prima di tutto, non ha nulla a che fare con il jailbreak! Ed è ancora in fase di sviluppo.
Ringrazio tutti coloro che mi hanno aiutato finora. Per motivi di privacy, potrei non elencarvi qui. Scrivetemi in DM se volete!
Per quanto ne so, la patch è in ipc_right_destroy. Qualcuno l'ha anche segnalato su X (o 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));
Usare ipc_right_destroy per ottenere una entry ipc di tipo none rimasta nello spazio ipc innesca un'eccezione. Controlla [0] e [1] qui sotto.
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] non ucciderà il task nella sandbox di app di terze parti. Prima ho scelto mach_thread_self() perché è l'unico send right pinnato che sono riuscito a trovare.
Ma senza evitare ReportCrash o SIGKILL, il bug non sarà utile nella sandbox di WebContent. Quindi ho scavato un po' più a fondo.
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 nel kernel gestisce le eccezioni di guardia dei mach port. Per un'eccezione fatale, cerca prima l'exception port. Se la notifica di eccezione restituisce KERN_SUCCESS, esegue un SIGKILL. Sembra promettente: ogni task che ha innescato un'eccezione fatale di guardia dei mach port verrà ucciso. Tuttavia...
Guardie Mach port fatali - sempre consegnate in modo sincrono.
Posso semplicemente impostare una thread exception port per il thread che innesca il bug e non elaborare la notifica di eccezione. Il kernel aspetterà la risposta qui, niente SIGKILL.
Panic in ipc_right_copyout() con una entry NULL.