T1569.003 Google Chronicle · YARA-L

Detect Systemctl in Google Chronicle

Adversaries may abuse systemctl to execute commands or programs as systemd services on Linux systems. Systemctl is the primary interface for systemd, the Linux init system and service manager. By crafting malicious service unit files and using systemctl start, enable, and daemon-reload, adversaries can execute arbitrary code immediately and establish persistent execution across reboots. Real-world abuse patterns include TeamTNT deploying cryptocurrency mining services, threat actors writing reverse shell service units pointing to payloads in /dev/shm or /tmp, and web shell compromise chains where an attacker-controlled web process creates a privileged service for lateral movement or persistence. Common subcommands used in attacks include: systemctl start, systemctl enable, systemctl daemon-reload, and systemctl link.

MITRE ATT&CK

Tactic
Execution
Technique
T1569 System Services
Sub-technique
T1569.003 Systemctl
Canonical reference
https://attack.mitre.org/techniques/T1569/003/

YARA-L Detection Query

Google Chronicle (YARA-L)
yaral
rule t1569_003_systemctl_abuse {
  meta:
    author = "Argus Detection Engineering"
    description = "Detects T1569.003 - malicious systemctl abuse for persistence or code execution. Covers web process spawning systemctl, suspicious service unit file creation, and unprivileged service enablement."
    mitre_attack_tactic = "Execution, Persistence"
    mitre_attack_technique = "T1569.003"
    severity = "HIGH"
    confidence = "HIGH"
    created = "2026-04-21"
    platform = "Linux"

  events:
    // Branch 1: Web/app server spawning systemctl
    $e1.metadata.event_type = "PROCESS_LAUNCH"
    $e1.target.process.file.full_path = /\/bin\/systemctl|\/usr\/bin\/systemctl$|^systemctl$/
    (
      $e1.target.process.command_line = /\bstart\b/ or
      $e1.target.process.command_line = /\benable\b/ or
      $e1.target.process.command_line = /daemon-reload/ or
      $e1.target.process.command_line = /\blink\b/
    )
    (
      $e1.principal.process.file.full_path = /apache2|nginx|httpd|php-fpm|php|node|nodejs|java|python3?|ruby|perl|gunicorn|uwsgi|lighttpd|caddy|haproxy/ or
      $e1.principal.process.parent_process.file.full_path = /apache2|nginx|httpd|php-fpm|php|node|nodejs|java|python3?|ruby|perl|gunicorn|uwsgi/
    )
    $e1.principal.hostname = $hostname
    $detection_branch1 = "WebApp_Process_Spawned_Systemctl"

  match:
    $hostname over 5m

  condition:
    $e1
}

rule t1569_003_service_unit_file_drop {
  meta:
    author = "Argus Detection Engineering"
    description = "Detects suspicious .service unit files written to systemd directories by non-package-manager or web-process parents — a key indicator of TeamTNT-style cryptomining or reverse shell persistence."
    mitre_attack_tactic = "Persistence"
    mitre_attack_technique = "T1569.003"
    severity = "CRITICAL"
    confidence = "HIGH"
    created = "2026-04-21"
    platform = "Linux"

  events:
    $e2.metadata.event_type = "FILE_CREATION"
    $e2.target.file.full_path = /^\/etc\/systemd\/system\/.*\.service$|^\/lib\/systemd\/system\/.*\.service$|^\/usr\/lib\/systemd\/system\/.*\.service$|^\/run\/systemd\/system\/.*\.service$/
    not $e2.principal.process.file.full_path = /dpkg|apt-get|apt|rpm|yum|dnf|snap|packagekitd|zypper|pacman|pip3?|conda|flatpak/
    (
      $e2.principal.process.file.full_path = /apache2|nginx|httpd|php|node|java|python3?|ruby|perl|curl|wget|bash|sh$/ or
      $e2.principal.process.command_line = /\/tmp\/|\/dev\/shm\/|\/var\/tmp\/|wget |curl | nc |bash -i|sh -i|python -c|perl -e|base64 -d|xmrig|minerd|cpuminer|mkfifo|\/dev\/tcp\//
    )
    $e2.principal.hostname = $hostname2

  match:
    $hostname2 over 1m

  condition:
    $e2
}

rule t1569_003_unprivileged_service_enable {
  meta:
    author = "Argus Detection Engineering"
    description = "Detects non-root, non-system accounts invoking systemctl enable, link, or daemon-reload outside of package manager or interactive login session context — indicates privilege escalation attempt or persistence by low-privilege compromised account."
    mitre_attack_tactic = "Persistence, Privilege Escalation"
    mitre_attack_technique = "T1569.003"
    severity = "HIGH"
    confidence = "MEDIUM"
    created = "2026-04-21"
    platform = "Linux"

  events:
    $e3.metadata.event_type = "PROCESS_LAUNCH"
    $e3.target.process.file.full_path = /\/bin\/systemctl|\/usr\/bin\/systemctl$|^systemctl$/
    (
      $e3.target.process.command_line = /\benable\b/ or
      $e3.target.process.command_line = /\blink\b/ or
      $e3.target.process.command_line = /daemon-reload/
    )
    not $e3.principal.user.userid = "root"
    not $e3.principal.user.userid = /^_|^systemd|^daemon/
    not $e3.principal.process.file.full_path = /dpkg|apt|rpm|yum|dnf|snap|zypper|pacman|pip3?|conda|flatpak/
    not $e3.principal.process.parent_process.file.full_path = /\/usr\/sbin\/sshd|^\/bin\/login$|^\/bin\/su$|^\/usr\/bin\/sudo$|tmux|screen/
    $e3.principal.hostname = $hostname3

  match:
    $hostname3 over 10m

  condition:
    $e3
}
high severity high confidence

Three Chronicle YARA-L 2.0 rules for T1569.003 systemctl abuse detection. Rule 1 detects web/application server processes (Apache, Nginx, PHP, Node.js, Java, Python) spawning systemctl with persistence-related subcommands — a reliable signal for post-exploitation web shell pivot to service persistence. Rule 2 detects .service unit file creation in systemd directories by non-package-manager processes, especially those with command-line indicators of payloads in staging directories or mining/reverse-shell tool names. Rule 3 catches unprivileged accounts enabling services outside of normal administrative workflows, indicating a low-privilege account attempting to register persistence.

Data Sources

Google ChronicleGoogle Chronicle Unified Data Model (UDM)Linux Endpoint telemetry via Chronicle forwarderauditd or EDR agent feeding Chronicle

Required Tables

UDM events: PROCESS_LAUNCH, FILE_CREATION

False Positives & Tuning

  • CI/CD pipeline runners (GitHub Actions, GitLab CI, Jenkins) that execute as www-data or application service accounts and call systemctl as part of automated deployment scripts — add runner hostname patterns to exclusion lists in rule meta conditions
  • Container-based workloads using systemd inside containers (systemd-nspawn, podman with --systemd=true) where web-facing processes legitimately manage container-internal services via systemctl
  • Third-party software installation scripts (e.g., Elastic Agent, Datadog Agent, CrowdStrike Falcon installer) that run from temporary download paths and create .service files — correlate with known installer hashes to suppress
Download portable Sigma rule (.yml)

Other platforms for T1569.003


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Create and Start Persistence Service with Benign Payload

    Expected signal: Auditd PATH record: write to /etc/systemd/system/df00tech-persist.service. Auditd EXECVE records: (1) systemctl daemon-reload, (2) systemctl enable df00tech-persist.service, (3) systemctl start df00tech-persist.service. Syslog/journal: 'Created symlink /etc/systemd/system/multi-user.target.wants/df00tech-persist.service', 'Starting System Performance Monitor...', 'Started System Performance Monitor'. MDE DeviceFileEvents: file create in /etc/systemd/system/. MDE DeviceProcessEvents: systemctl invocations with daemon-reload and enable subcommands.

  2. Test 2TeamTNT-Style Cryptomining Service Registration

    Expected signal: Auditd PATH: write to /etc/systemd/system/kworker-d.service. Auditd EXECVE: systemctl daemon-reload, systemctl enable kworker-d.service. Syslog: 'Created symlink...kworker-d.service'. MDE DeviceFileEvents: new .service file in /etc/systemd/system/ with InitiatingProcessCommandLine containing 'cp /tmp/df00tech-kworker.service'. SPL SuspiciousServiceName=1 fires on 'pool.example.com:4444' pattern and /tmp/ path reference in ExecStart.

  3. Test 3Reverse Shell Service Unit with /dev/shm Payload Path

    Expected signal: Auditd PATH: write to /etc/systemd/system/netconfig.service. Auditd EXECVE: systemctl daemon-reload, systemctl enable netconfig.service. Syslog: 'Created symlink...netconfig.service'. MDE DeviceFileEvents: new service file in /etc/systemd/system/ with /dev/shm pattern detectable if file content is captured.

  4. Test 4Web Process Spawning Systemctl (Web Shell Simulation)

    Expected signal: Auditd EXECVE: systemctl daemon-reload with uid=33 (www-data on Debian/Ubuntu) or current test UID. Auditd SYSCALL: uid/auid fields identifying the web process account. MDE DeviceProcessEvents: systemctl with AccountName=www-data, InitiatingProcessFileName=bash, InitiatingProcessParentFileName may show sudo. Syslog: service enable/start events. The key telemetry is systemctl running under a web service account UID.

Unlock Pro Content

Get the full detection package for T1569.003 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections