# Finding 1: Authentication Bypass on macOS/BSD (CRITICAL)

**CWE-287 (Improper Authentication)**
**CVSS 3.1: 8.8** (AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H)
**Affected:** ALL macOS, FreeBSD, OpenBSD, NetBSD builds of spice-vdagent

## Root Cause

Two functions interact to completely disable authentication on non-Linux
platforms:

**1. `src/vdagentd/dummy-session-info.c:26`**

`session_info_create()` unconditionally returns NULL on macOS because
neither ConsoleKit nor systemd-logind exists. This file is compiled on all
macOS/BSD builds.

**2. `src/vdagentd/vdagentd.c:996`**

`agent_connect()` wraps the ENTIRE UID/PID verification block inside:

```c
if (session_info) {
PidUid pid_uid = vdagent_connection_get_peer_pid_uid(...);
// check_uid_of_pid()
// session matching
// UID equality checks
// ALL SKIPPED when session_info == NULL
}
```

When `session_info` is NULL (always on macOS/BSD), zero authentication is
performed. Any process that connects to the UDSCS socket is silently
accepted as the daemon's trusted agent.

Additionally, `check_uid_of_pid()` at `vdagentd.c:978` reads
`/proc/%u/status`, which does not exist on macOS/Darwin.

## Impact

Any unprivileged local user (e.g., uid=502) can:

1. Connect to the world-writable UDS socket (`/var/run/spice-vdagent-sock`)
2. Become `active_session_conn` with zero credential checks
3. Receive ALL host→guest messages (clipboard data, file transfers, monitor
config)
4. Inject clipboard data to the SPICE host (credential theft vector)
5. Intercept ALL file transfers from the host
6. Prevent the legitimate agent from becoming active

The attack is completely silent — no authentication failure is logged
because no authentication is attempted.

**Linux note:** On Linux with systemd-logind, the daemon logs "UID
mismatch" but STILL PROCESSES all commands from unauthorized connections.
1,646 "UID mismatch" entries observed — every command was executed.

## Proof of Concept

```
$ id
uid=502(attacker) gid=20(staff)

$ ./spice_lpe_exploit
[Stage 1] Verifying spice-vdagentd is running as root...
root 286 /usr/local/bin/spice-vdagentd
[+] CONFIRMED: daemon runs as root

[Stage 3] Exploiting auth bypass (CWE-287)...
[+] CONNECTED! Daemon version: 0.22.1
[+] AUTH BYPASS CONFIRMED — no credential check performed!
[+] We are now the daemon's TRUSTED AGENT (active_session_conn)

[Stage 4] Demonstrating attacker capabilities...
[4a] Sending clipboard grab (requesting host clipboard)...
[4b] Requesting clipboard data from host...

[VIRTIO] Intercepted 40 bytes from SPICE host:
Chunk: port=2 size=32
Msg: proto=1 type=6 size=12 ← ANNOUNCE_CAPABILITIES stolen from host

[Stage 6] Injecting fake clipboard to SPICE host...
[+] Injected 57 bytes to host clipboard: "PWNED_BY_DORKERDEVIL"
```

## Escalation Path

```
Unprivileged user (uid=502)
→ Auth bypass (silent, no logs)
→ Become trusted agent in root daemon
→ Claim clipboard ownership via CLIPBOARD_GRAB
→ All SPICE host clipboard data forwarded to attacker
→ Monitor for passwords/credentials
→ Inject crafted commands into host clipboard
→ When admin pastes in Terminal → attacker command executes
```

## Suggested Fix

Use `getpeereid()` on macOS/BSD to verify peer UID regardless of
`session_info` availability:

```c
// In agent_connect(), BEFORE the session_info check:
PidUid pid_uid = vdagent_connection_get_peer_pid_uid(conn);
if (pid_uid.uid != getuid() && pid_uid.uid != 0) {
syslog(LOG_WARNING, "Rejecting connection from uid %d", pid_uid.uid);
return;
}
```

## Attachments

- `spice_lpe_exploit.c` — Auth bypass + virtio MitM + clipboard injection
PoC

## Author

Ashish Kunwar (@D0rkerDevil) — [email protected]

Attachment: spice_lpe_exploit.c
Description: Binary data

Reply via email to