## https://sploitus.com/exploit?id=8B371FF0-E7C9-5832-8302-485AF18C97C7
This is a proof-of-concept for CVE-2023-41992. And first of all, this has nothing to do with __jailbreak__ !
0. I've recently been auditing xnu code and old vulnerabilities, and 41992 looks interesting.
1. It's time to contribute something to the community. (If the iOS community still exists...)
2. Hope someone can actually exploit this vulnerability. (Or someone who knows how to exploit this can give me some hint ๐)
The kernel will crash as soon as the app is killed by hand. My test device is iPhone12 iOS16.2.
# patch
As far as I know, the patch is in `ipc_right_destroy`. @Fame_G_Monster also pointed this out on x ([link](https://x.com/Fame_G_Monster/status/1705109684045467815)).
```diff
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));
```
I am not sure if this is true.
# code path
It's ok to wipe out type when destroy a ipc right, but things change when the ipc right is not destroied ! There are some "early-return" paths in `ipc_right_destroy`. In this case, type in `ie_bits` will be erased.
```C
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, name, port, MPG_FLAGS_MOD_REFS_PINNED_DESTROY);
return KERN_INVALID_CAPABILITY;
}
ipc_hash_delete(space, ip_to_object(port), name, entry);
}
```
This give us an ipc entry __without__ type ! But this is not easy. The port needs to be pinned, and the task has to surive from `mach_port_guard_exception_pinned`. I don't want to go too deep here, and I choose third-party app context with `mach_thread_self()` as target in the end.
> How is this bug used in the exploit chain? Triggering this path would crash WebContent (WebContent is first-party code, it just can't surive from `mach_port_guard_exception_pinned`. Yes, I tested this on iOS with Safari RCE). This is a vulnerability that is being exploited in the wild. It has to be something in the exploit chain.
When `mach_thread_self()` is called, kernel goes to `thread_self_trap`. After all, `ipc_right_copyout` is called in kernel.
- `thread_self_trap`
- `ipc_port_copyout_send`
- `ipc_port_copyout_send_internal`
- `ipc_object_copyout`
- `ipc_right_copyout`
For the `ipc_right_copyout`, `msgt_name` should be `MACH_MSG_TYPE_PORT_SEND`. In the switch-case for `MACH_MSG_TYPE_PORT_SEND`, the entry type is checked. For an entry without type, a line of code can lead to overflow.
```C
entry->ie_bits = (bits | MACH_PORT_TYPE_SEND) + 1; /* increment urefs */
```
`urefs` in `ie_bits` is not checked for none-type entry (at least in release kernel... ). If the `urefs` here reaches 0xffff and no type in ie_bits, this is `(0xffff | 0x10000) + 1` (some other bit fields in ie_bits are ignored here.). This will make the entry have a `MACH_PORT_RIGHT_RECEIVE` type.