
This advisory comes out of our open source partnership program, which we introduced in Smarter, Not Bigger: How We Built BackBox AI, and How We Partner with Open Source. The target is NetBird, the open source overlay network and VPN client. BackBox AI analyzed the NetBird client daemon running on Linux and identified a local privilege escalation affecting versions up to and including 0.75.0.
The issue is not caused by a single programming mistake, but by a chain of individually moderate weaknesses that, when combined, allow any unprivileged local user to obtain a root shell. The attack does not require memory corruption, kernel vulnerabilities, or race conditions. Instead, it abuses trust assumptions within the daemon's local gRPC interface and configuration workflow. It was reported to the maintainers through responsible disclosure.
Advisory Summary
| Field | Detail |
|---|---|
| Project | NetBird client daemon (Linux, runs as root under systemd) |
| Affected | Versions up to and including 0.75.0 |
| Component | Local gRPC interface exposed over the daemon's Unix domain socket |
| Class | Local privilege escalation (chained weaknesses) |
| CWE | CWE-732 (Incorrect Permission Assignment), CWE-306 (Missing Authentication), CWE-862 (Missing Authorization) |
| CVSS 3.1 | 7.8 (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| Severity | High |
| Advisory ID | BBL-2026-07101 (internal tracking) |
| Status | Reported via responsible disclosure |
Understanding the Architecture
Security boundaries are often imagined around network-facing services, authentication gateways, and exposed APIs. Local inter-process communication (IPC) mechanisms deserve the same level of scrutiny: a privileged service exposing an overly permissive local interface can become just as dangerous as an Internet-facing application.
NetBird provides secure peer-to-peer connectivity through a client daemon that typically runs as root under systemd. The daemon exposes a Unix domain socket that allows local components to communicate with it through a gRPC API.
This design is common among modern endpoint agents. A privileged background service performs operations requiring elevated permissions, while user-facing applications interact with it through a local IPC channel.
The security of this architecture depends entirely on one assumption:
Only trusted local users should be able to invoke privileged operations through the IPC interface.
Unfortunately, this assumption does not hold in the affected implementation.
The First Weakness: An Unprotected Local API
The daemon creates its Unix socket with world-readable and world-writable permissions (0666), making it accessible to every local user on the system. At the same time, the gRPC server does not perform any authentication or authorization before processing incoming requests.
From a security perspective, this effectively removes the trust boundary between privileged and unprivileged users.
Instead of acting as an administrative interface restricted to trusted clients, the daemon exposes management functionality to anyone capable of opening the socket.
Among the available RPC methods are operations such as:
- retrieving the current configuration,
- modifying configuration parameters,
- changing operational state,
- reconnecting to the management infrastructure,
- adjusting daemon behavior.
None of these operations require proof that the caller is authorized to perform administrative actions.
Configuration as an Attack Surface
Administrative APIs are often considered less dangerous than direct code execution because they expose "intended functionality."
In reality, configuration endpoints frequently represent one of the most attractive attack surfaces inside privileged software.
In this case, the exposed SetConfig functionality allows a local user to modify critical runtime parameters, including the management server address and several independent SSH-related flags: serverSSHAllowed, enableSSHRoot, and disableSSHAuth. Since these requests are accepted without authentication, an attacker can instruct the daemon to communicate with infrastructure under their control and simultaneously pre-configure the SSH subsystem in a maximally permissive state.
The daemon faithfully applies the new configuration and reconnects, trusting that the supplied management endpoint is legitimate.
At this stage, no exploitation has occurred in the traditional sense. The software is simply performing exactly what it was instructed to do.
Turning Trust into Control
Once the management endpoint has been redirected, the daemon establishes a connection with an attacker-controlled server. In practice, the attack requires standing up two fake local gRPC services: a management server (default port 33073) and a signal server (default port 33074). Both are necessary, because the daemon connects to the management server for Login and Sync operations, then registers with the signal server as part of its normal startup sequence.
Because the client's existing WireGuard private key is preserved when the management URL changes, the fake management server can continue communicating with the daemon without triggering key regeneration or additional trust validation.
This behavior significantly lowers the complexity of the attack chain.
Rather than creating an entirely new identity, the daemon seamlessly continues operating with its existing credentials, now under the control of a different management and signal infrastructure.
From the daemon's perspective, the workflow appears legitimate.
An Unexpected Authentication Gap
The final stage of the attack relies on two subtle but independent implementation details.
The first is the disableSSHAuth configuration flag. When SSH authentication is disabled through this setting, the daemon starts its embedded SSH service without installing a password authentication handler. In this state, authentication is effectively absent, allowing incoming connections to be accepted without credentials.
The second is the enableSSHRoot flag, which is a separate and distinct control from disableSSHAuth. Enabling root login requires explicitly setting this field to true in the SetConfig request. The two flags must both be set to achieve a root session, because disabling authentication alone is insufficient if root login has not been independently enabled.
A third detail worth noting is that the daemon's embedded SSH server listens on a non-standard port (22022 by default) and rejects connections sourced from its own WireGuard IP (127.0.0.2). A working exploit must therefore bind the SSH client to a different local address (e.g., 127.0.0.3) to bypass this check.
Individually, each of these behaviors may have been intended to support specific deployment scenarios.
Combined with unrestricted configuration access, however, they become the final components of a complete privilege escalation chain.
Reproduction
The full chain turns an unprivileged local shell into a root session using only the daemon's own functionality. The proof of concept stands up two local services that impersonate NetBird's control plane, reconfigures the daemon through its unauthenticated socket, and then logs in over the embedded SSH server.
- Stand up a fake management server (default port
33073) and a fake signal server (default port33074) on the loopback interface. The daemon uses the first for Login and Sync, and registers with the second during startup. - Call
SetConfigon the daemon's Unix socket (no authentication required) to redirect the management URL and pre-configure the SSH subsystem in its most permissive state:ManagementURLpoints to the attacker-controlled endpoint,serverSSHAllowed = true,enableSSHRoot = true,disableSSHAuth = true.
- The daemon reconnects to the attacker-controlled management server. Because the existing WireGuard private key is preserved across the URL change, no key regeneration or additional trust validation is triggered.
- Connect to the embedded SSH server as root. It listens on port
22022and rejects connections from the daemon's own WireGuard IP (127.0.0.2), so the client must be bound to a different local address:
ssh -b 127.0.0.3 -p 22022 root@127.0.0.2
With authentication disabled and root login enabled, the session is accepted without credentials, and the attacker obtains a root shell without injecting a single byte of shellcode.
Why Chained Vulnerabilities Matter
This research highlights an important lesson in modern application security: security weaknesses rarely exist in isolation.
Each issue identified during the assessment appears relatively straightforward when considered independently:
- overly permissive Unix socket permissions (
0666); - missing authentication on the local gRPC interface;
- unrestricted access to privileged configuration methods;
- independent SSH flags (
disableSSHAuth,enableSSHRoot) configurable without authorization; - authentication behavior fully dependent on runtime configuration;
- persistent cryptographic identity across management server changes;
- signal server registration completing without independent trust verification.
Individually, each weakness might be categorized as a hardening issue or a design oversight.
Together, they remove every security boundary protecting a privileged service.
The resulting attack chain allows an unprivileged local user to obtain full administrative access without exploiting memory safety bugs or bypassing operating system protections.
How BackBox AI Found It
No single component in this chain is a memory-safety bug, and none is exploitable on its own. The finding is the composition. BackBox AI mapped the daemon's local attack surface, noticed that the Unix socket was world-writable (0666) and that the gRPC server serviced requests without authenticating the caller, and then reasoned about what an attacker could actually do with unrestricted SetConfig access. Following that thread, it connected the management-URL redirect, the preserved WireGuard identity, and the two independent SSH flags into a single path from an unprivileged shell to root. Recognizing that individually benign behaviors combine into a complete privilege escalation is exactly the kind of contextual reasoning the platform is built to do.
Disclosure and Status
The finding was reported to the NetBird maintainers through responsible disclosure. At the time of writing, no CVE has yet been associated with it, which is why we track the advisory internally as BBL-2026-07101; that identifier is a placeholder and will be replaced if and when a CVE is issued.
Conclusion
Privilege escalation vulnerabilities are often associated with sophisticated exploitation techniques, kernel internals, or complex memory corruption.
This case demonstrates that equally severe outcomes can emerge from design decisions affecting trust boundaries between local processes.
A privileged daemon should treat every IPC request as untrusted until proven otherwise. File permissions, peer authentication, authorization, and secure defaults are not independent security controls; they form layers of the same defense.
When those layers are removed one by one, ordinary management functionality can become a reliable path from an unprivileged shell to complete system compromise.
As endpoint agents and VPN clients continue to adopt increasingly rich local APIs, reviewing IPC interfaces should become a standard component of every security assessment. The attack surface may be local, but the impact is absolute.
If you maintain an open source project and think an extra set of eyes would help, apply to partner with us.