T1569

System Services

Execution Last updated:

This detection identifies adversaries abusing Windows services, Linux systemd units, and macOS launchd daemons to execute malicious code. Attackers commonly leverage sc.exe, net start, PsExec, systemctl, and launchctl to create or start services that run attacker-controlled binaries. Indicators include services with suspicious binary paths (temp directories, user profile paths, UNC paths), service names mimicking legitimate system services, new service installations from unusual parent processes (cmd.exe, powershell.exe, wscript.exe), and service creations from non-standard accounts. This technique is frequently chained with lateral movement and persistence techniques to achieve remote code execution or maintain footholds across reboots.

What is T1569 System Services?

System Services (T1569) maps to the Execution tactic — the adversary is trying to run malicious code in MITRE ATT&CK.

This page provides production-ready detection logic for System Services, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint, Microsoft Sentinel, Windows Security Events. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Execution
Technique
T1569 System Services
Canonical reference
https://attack.mitre.org/techniques/T1569/
Microsoft Sentinel / Defender
kusto
let SuspiciousPaths = dynamic(["\\Temp\\", "\\Users\\", "\\AppData\\", "\\ProgramData\\", "\\Downloads\\", "\\Public\\", "%TEMP%", "%APPDATA%"]);
let SuspiciousParents = dynamic(["cmd.exe", "powershell.exe", "pwsh.exe", "wscript.exe", "cscript.exe", "mshta.exe", "rundll32.exe", "regsvr32.exe", "msiexec.exe"]);
let LolBins = dynamic(["certutil.exe", "bitsadmin.exe", "wmic.exe", "mshta.exe", "regsvr32.exe", "rundll32.exe"]);
union
(
    // New service installations via Security event log
    SecurityEvent
    | where EventID == 7045
    | extend ServiceName = tostring(EventData.ServiceName),
             ServiceFileName = tostring(EventData.ImagePath),
             ServiceType = tostring(EventData.ServiceType),
             ServiceAccount = tostring(EventData.ServiceAccount)
    | where ServiceFileName has_any (SuspiciousPaths)
          or ServiceFileName matches regex @"\\\\[0-9]{1,3}\.[0-9]{1,3}\."  // UNC path
          or ServiceFileName has_any (LolBins)
          or ServiceAccount == "LocalSystem" and ServiceFileName has_any (SuspiciousPaths)
    | project TimeGenerated, Computer, EventID, ServiceName, ServiceFileName, ServiceType, ServiceAccount,
              SourceType = "SecurityEvent-7045"
),
(
    // sc.exe and net.exe service manipulation
    DeviceProcessEvents
    | where FileName in~ ("sc.exe", "net.exe", "net1.exe")
      and ProcessCommandLine has_any ("create", "start", "config", "binpath")
    | where InitiatingProcessFileName has_any (SuspiciousParents)
          or ProcessCommandLine matches regex @"binpath\s*=\s*[^\"]*\\(Temp|AppData|Downloads|Public|Users)\\"
          or ProcessCommandLine has "cmd.exe /c"
          or ProcessCommandLine has "powershell"
    | project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine,
              InitiatingProcessFileName, InitiatingProcessCommandLine,
              InitiatingProcessParentFileName, SourceType = "DeviceProcessEvents-sc"
),
(
    // PsExec-style remote service creation indicators
    DeviceProcessEvents
    | where FileName =~ "services.exe"
    | where InitiatingProcessFileName has_any ("psexec.exe", "psexec64.exe", "paexec.exe", "remcom.exe", "csexec.exe")
    | project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine,
              InitiatingProcessFileName, InitiatingProcessCommandLine, SourceType = "DeviceProcessEvents-psexec"
),
(
    // Suspicious service binaries created in temp paths
    DeviceFileEvents
    | where ActionType == "FileCreated"
    | where FolderPath has_any (SuspiciousPaths)
    | where FileName endswith ".exe" or FileName endswith ".dll"
    | join kind=inner (
        SecurityEvent
        | where EventID == 7045
        | extend ServiceFileName = tostring(EventData.ImagePath)
        | project ServiceFileName, ServiceName = tostring(EventData.ServiceName), ServiceInstallTime = TimeGenerated
    ) on $left.FolderPath == $right.ServiceFileName
    | project TimeGenerated, DeviceName, FileName, FolderPath, ServiceName, ServiceInstallTime, SourceType = "FileCreated-ServiceBinary"
)
| order by TimeGenerated desc

Detects service abuse for code execution by correlating Security Event 7045 (new service installed) with suspicious binary paths, sc.exe/net.exe usage from unexpected parent processes, PsExec-style remote service creation, and service binaries written to temp/user directories. Unions multiple detection angles to catch both local and remote service execution patterns.

high severity medium confidence

Data Sources

Microsoft Defender for Endpoint Microsoft Sentinel Windows Security Events

Required Tables

SecurityEvent DeviceProcessEvents DeviceFileEvents

False Positives

  • IT automation tools (SCCM, Ansible, Chef) creating services during software deployment
  • Legitimate software installers that write binaries to AppData before creating services
  • Vulnerability scanners and EDR agents that enumerate or interact with the service control manager
  • Help desk remote management tools (TeamViewer, ConnectWise) that install services temporarily
  • Developer workstations running test services from non-standard paths during development

Sigma rule & cross-platform mapping

The detection logic for System Services (T1569) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


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 Execute Malicious Service via sc.exe

    Expected signal: SecurityEvent 7045 with ServiceName=AtomicTestSvc and ImagePath containing Temp directory; DeviceProcessEvents showing sc.exe with 'create' and 'binpath' in command line; parent process cmd.exe or PowerShell

  2. Test 2Remote Service Execution via PsExec Simulation

    Expected signal: SecurityEvent 7045 on target host showing UNC path in ImagePath; Sysmon EventCode 3 (network) showing SMB connection to remote host; sc.exe process creation with remote hostname argument

  3. Test 3Linux Malicious Systemd Service Creation

    Expected signal: Syslog or auditd entries showing systemctl execution; file creation event for /etc/systemd/system/atomic-test.service; bash process spawned by systemd with UID=0 executing id command

  4. Test 4Service Creation via PowerShell New-Service Cmdlet

    Expected signal: SecurityEvent 7045 with ServiceName=PSAtomicTestSvc and ImagePath in %TEMP%; PowerShell ScriptBlock log EventID 4104 showing New-Service cmdlet; DeviceProcessEvents showing powershell.exe as initiating process for service creation API calls


Response Playbook

Triage

  1. Step 1: Identify the service binary path from EventID 7045 — determine if the path is in a standard system directory (C:\Windows\System32, C:\Program Files) versus a user-writable location (Temp, AppData, Downloads). Non-standard paths warrant immediate escalation.
  2. Step 2: Examine the account that created the service. SYSTEM or LocalSystem creating services is expected; standard user accounts or service accounts creating new services is highly suspicious. Check the AccountName field in the event.
  3. Step 3: Review the parent process chain for sc.exe or service creation events. Map the full ancestry using DeviceProcessEvents: what spawned sc.exe or net.exe? If the parent is cmd.exe spawned by an Office application, email client, or browser, treat as high-confidence compromise.
  4. Step 4: Check if the service binary existed before the service creation event. Query DeviceFileEvents for the binary's creation timestamp. If the file was created minutes before the service, it was likely dropped as part of an attack chain.
  5. Step 5: Look for network connections from the service binary using DeviceNetworkEvents filtered on InitiatingProcessFileName matching the service executable. Outbound connections to non-standard ports or known-bad IPs indicate active C2.
  6. Step 6: Search for lateral movement indicators — was the same service name or binary hash observed on multiple endpoints within the same time window? Query across your fleet for the ServiceName and file hash.
  7. Step 7: Verify the service's display name and description against known-good baselines. Attackers often misspell common service names (e.g., 'Windоws Update' with a Cyrillic 'о') or use names that match legitimate services but with different binary paths.

Containment

  1. Stop the malicious service immediately using: sc stop <ServiceName> followed by sc delete <ServiceName>. Do this before isolation to generate additional telemetry and confirm the service name.
  2. Isolate the affected endpoint from the network using EDR isolation or firewall rule to prevent C2 communication and lateral movement origination. Preserve the endpoint for forensic investigation — do not reimage without evidence collection.
  3. If a domain account was used to create the service, disable that account and force a password reset. Review the account's recent activity in AADSignInLogs and AuditLogs for other compromised actions.
  4. Block the malicious binary hash in your EDR/AV solution to prevent re-execution on this endpoint and deployment to others across the fleet.
  5. If PsExec or a similar remote execution tool was detected, identify the source host from which the connection originated. That source host is likely already compromised and requires parallel investigation and isolation.

Evidence Collection

  1. Collect the malicious service binary before deletion: copy it to an evidence share or encrypted container. Hash it with SHA256 for IOC sharing and VirusTotal lookup.
  2. Export Windows Event Logs: System log (for 7045), Security log (for 4697, 4688), and Application log from the affected endpoint. Use wevtutil: wevtutil epl System C:\evidence\system.evtx
  3. Collect Prefetch files from C:\Windows\Prefetch\ — the service binary's .pf file will show historical execution count and linked DLLs, revealing how long the service has been active.
  4. Export the service registry key: reg export HKLM\SYSTEM\CurrentControlSet\Services\<ServiceName> C:\evidence\service_reg.reg — this captures the full service configuration including ImagePath, Start type, and parameters.
  5. Collect memory dump of the running service process using Task Manager, ProcDump, or your EDR's memory acquisition capability before stopping the service: procdump -ma <PID> C:\evidence\service_dump.dmp
  6. Pull PowerShell ScriptBlock logs (Event ID 4104 from Microsoft-Windows-PowerShell/Operational) covering the hour before service creation to identify the attack chain that led to service installation.

Escalation Criteria

  • ! Escalate immediately if the service is detected on more than 3 endpoints — this indicates automated lateral movement or a worm-like propagation pattern requiring incident response team engagement.
  • ! Escalate if the service binary communicates with external IPs or domains, especially if traffic is encrypted or uses non-standard ports, indicating active C2 infrastructure.
  • ! Escalate if the service was created by a privileged domain account (Domain Admin, Service Account, IT admin), suggesting credential compromise at a level that could affect the entire domain.
  • ! Escalate if the service name or binary matches known ransomware families or publicly documented malware (check hash against threat intel feeds) — this requires immediate crisis response.
  • ! Escalate if evidence collection reveals the service has been running for more than 24 hours without detection, indicating a dwell time that may have allowed significant data access or exfiltration.

Investigation Guide

Forensic Artifacts

  • > Windows Event Log: System EventID 7045 (service installed) and 7036 (service state changed)
  • > Windows Event Log: Security EventID 4697 (service installed with audit policy), 4688 (process creation if auditing enabled)
  • > Registry: HKLM\SYSTEM\CurrentControlSet\Services\<ServiceName> — full service configuration
  • > Registry: HKLM\SYSTEM\CurrentControlSet\Services\<ServiceName>\Parameters — additional service parameters
  • > File system: Service binary at the ImagePath location with creation/modification timestamps
  • > Prefetch: C:\Windows\Prefetch\<SERVICEBINARY>-XXXXXXXX.pf showing execution history
  • > Windows.edb (search index): May contain metadata about recently created files
  • > Scheduled Task XML (if service was created via task): C:\Windows\System32\Tasks\
  • > AmCache.hve: Records first execution of service binary with hash and path
  • > ShimCache (AppCompatCache): HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache

Tuning Guidance

Start by building an allowlist of known-good service names and their expected binary paths using the first 30 days of SecurityEvent 7045 data. Baseline which accounts and parent processes legitimately create services in your environment — SCCM, Ansible Tower, and software deployment tools are common sources of noise. Apply the risk scoring model and tune thresholds: suspicious_path scoring of 40 may be too low for environments with AppData-based legitimate software. Consider adding your software deployment server IPs to an exclusion list for the PsExec detection. For the short-lived service hunt, adjust the 300-second window based on your environment's normal software installation patterns — some installers create and remove services in <60 seconds legitimately.


Hunting Queries

Hunts for services with binaries in user-writable directories across the entire fleet over 30 days, identifying attacker-planted service executables that bypass standard program installation paths.

Hunting — KQL
kql
// Hunt for services with binary paths in writable locations across the fleet
SecurityEvent
| where EventID == 7045
| where TimeGenerated > ago(30d)
| extend ServiceName = tostring(EventData.ServiceName),
         ServiceFileName = tostring(EventData.ImagePath),
         ServiceAccount = tostring(EventData.ServiceAccount)
| where ServiceFileName matches regex @"(?i)(\\temp\\|\\users\\(?!default|public)[^\\]+\\|\\appdata\\|\\downloads\\|%temp%|%appdata%)"
| summarize HostCount = dcount(Computer),
            Hosts = make_set(Computer, 20),
            FirstSeen = min(TimeGenerated),
            LastSeen = max(TimeGenerated)
    by ServiceName, ServiceFileName, ServiceAccount
| where HostCount >= 1
| order by HostCount desc, LastSeen desc
Hunting — SPL
spl
index=* (sourcetype="WinEventLog:System" EventCode=7045 OR sourcetype="WinEventLog:Security" EventCode=4697)
| rex field=_raw "ImagePath\s*=\s*(?<ImagePath>[^\r\n]+)"
| rex field=_raw "ServiceName\s*=\s*(?<ServiceName>[^\r\n]+)"
| where match(ImagePath, "(?i)(\\\\temp\\\\|\\\\users\\\\|\\\\appdata\\\\|\\\\downloads\\\\)")
| stats count dc(host) as host_count values(host) as hosts min(_time) as first_seen max(_time) as last_seen by ServiceName ImagePath
| sort - host_count

Hunts for services that are created and stopped within 5 minutes — a hallmark of PsExec-style remote execution where a service is used for one-time command execution and then immediately removed to reduce forensic footprint.

Hunting — KQL
kql
// Hunt for short-lived services — created and deleted within a short window (one-time execution pattern)
let ServiceCreations = SecurityEvent
    | where EventID == 7045
    | extend ServiceName = tostring(EventData.ServiceName)
    | project CreateTime = TimeGenerated, Computer, ServiceName;
let ServiceDeletions = SecurityEvent
    | where EventID == 7036
    | where EventData has "STOPPED"
    | extend ServiceName = tostring(EventData.param1)
    | project StopTime = TimeGenerated, Computer, ServiceName;
ServiceCreations
| join kind=leftouter ServiceDeletions on Computer, ServiceName
| extend LifetimeSec = datetime_diff('second', StopTime, CreateTime)
| where LifetimeSec between (1 .. 300) or isnull(StopTime)
| project CreateTime, Computer, ServiceName, StopTime, LifetimeSec
| order by CreateTime desc
Hunting — SPL
spl
index=* sourcetype="WinEventLog:System" (EventCode=7045 OR EventCode=7036)
| rex field=_raw "ServiceName\s*=\s*(?<ServiceName>[^\r\n]+)"
| rex field=_raw "param1\s*=\s*(?<param1>[^\r\n]+)"
| eval svc=coalesce(ServiceName, param1)
| eval event_type=case(EventCode="7045", "created", EventCode="7036", "stopped", true(), "other")
| stats min(eval(if(event_type="created",_time,null()))) as create_time
         max(eval(if(event_type="stopped",_time,null()))) as stop_time
         count by svc host
| eval lifetime_sec=stop_time-create_time
| where lifetime_sec < 300 AND lifetime_sec > 0
| table host svc create_time stop_time lifetime_sec
| sort - create_time

Hunts for service manipulation commands (sc.exe, net.exe create/start/config) initiated by non-standard parent processes, filtering out legitimate SCM and installer parents to surface attacker-controlled service manipulation.

Hunting — KQL
kql
// Hunt for service creation by processes that are not SCM or standard installers
DeviceProcessEvents
| where FileName in~ ("sc.exe", "net.exe", "net1.exe")
  and ProcessCommandLine has_any ("create", "start", "config")
  and TimeGenerated > ago(14d)
| where InitiatingProcessFileName !in~ ("services.exe", "svchost.exe", "msiexec.exe", "setup.exe", "install.exe")
| summarize Count = count(),
            UniqueCommands = dcount(ProcessCommandLine),
            Commands = make_set(ProcessCommandLine, 10),
            Hosts = make_set(DeviceName, 20)
    by InitiatingProcessFileName, bin(TimeGenerated, 1h)
| where Count > 1 or UniqueCommands > 1
| order by TimeGenerated desc
Hunting — SPL
spl
index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
(Image="*\\sc.exe" OR Image="*\\net.exe" OR Image="*\\net1.exe")
(CommandLine="*create*" OR CommandLine="*start*" OR CommandLine="*config*")
NOT (ParentImage="*\\services.exe" OR ParentImage="*\\svchost.exe" OR ParentImage="*\\msiexec.exe")
| stats count values(CommandLine) as commands dc(host) as hosts values(host) as host_list by ParentImage
| sort - count

Atomic Red Team Tests

Test 1 Create and Execute Malicious Service via sc.exe
windows

Simulates an attacker creating a Windows service with a binary in the Temp directory, starting it, and cleaning up. This tests detection of suspicious service binary paths and sc.exe usage from command line.

Command

powershell
copy C:\Windows\System32\cmd.exe C:\Windows\Temp\svchost32.exe
sc create AtomicTestSvc binPath= "C:\Windows\Temp\svchost32.exe /c whoami > C:\Windows\Temp\svc_output.txt" type= own start= demand DisplayName= "Atomic Test Service"
sc start AtomicTestSvc
ping -n 3 127.0.0.1 > nul
sc query AtomicTestSvc

Cleanup

powershell
sc stop AtomicTestSvc
sc delete AtomicTestSvc
del C:\Windows\Temp\svchost32.exe
del C:\Windows\Temp\svc_output.txt

Expected Telemetry

SecurityEvent 7045 with ServiceName=AtomicTestSvc and ImagePath containing Temp directory; DeviceProcessEvents showing sc.exe with 'create' and 'binpath' in command line; parent process cmd.exe or PowerShell

Expected Detection

KQL union query should fire on SecurityEvent 7045 with suspicious_path match; SPL query should detect via WinEventLog:System EventCode 7045 with Temp path match and risk_score=40

Test 2 Remote Service Execution via PsExec Simulation
windows

Simulates PsExec-style remote service creation by using sc.exe to target a remote host (loopback for testing). Tests detection of UNC path service binaries and remote service execution patterns.

Command

powershell
net use \\127.0.0.1\c$ /user:%USERNAME% ""
copy C:\Windows\System32\cmd.exe \\127.0.0.1\c$\Windows\Temp\remotesvc.exe
sc \\127.0.0.1 create RemoteAtomicSvc binPath= "\\127.0.0.1\c$\Windows\Temp\remotesvc.exe" start= demand
sc \\127.0.0.1 start RemoteAtomicSvc

Cleanup

powershell
sc \\127.0.0.1 stop RemoteAtomicSvc
sc \\127.0.0.1 delete RemoteAtomicSvc
del \\127.0.0.1\c$\Windows\Temp\remotesvc.exe
net use \\127.0.0.1\c$ /delete

Expected Telemetry

SecurityEvent 7045 on target host showing UNC path in ImagePath; Sysmon EventCode 3 (network) showing SMB connection to remote host; sc.exe process creation with remote hostname argument

Expected Detection

KQL query should match unc_path regex pattern in SecurityEvent 7045; SPL risk scoring should assign risk_score=50 for UNC path detection

Test 3 Linux Malicious Systemd Service Creation
linux

Creates a malicious systemd service unit file that executes a reverse shell command, simulating adversary persistence and execution via systemd on Linux. Tests detection of systemctl usage and suspicious service unit configurations.

Command

bash
cat > /tmp/atomic-test.service << 'EOF'
[Unit]
Description=Atomic Test Service

[Service]
Type=simple
ExecStart=/bin/bash -c 'id > /tmp/atomic_svc_output.txt'
Restart=no

[Install]
WantedBy=multi-user.target
EOF
sudo cp /tmp/atomic-test.service /etc/systemd/system/atomic-test.service
sudo systemctl daemon-reload
sudo systemctl start atomic-test.service
systemctl status atomic-test.service

Cleanup

bash
sudo systemctl stop atomic-test.service
sudo systemctl disable atomic-test.service
sudo rm /etc/systemd/system/atomic-test.service
sudo systemctl daemon-reload
rm /tmp/atomic-test.service
rm /tmp/atomic_svc_output.txt

Expected Telemetry

Syslog or auditd entries showing systemctl execution; file creation event for /etc/systemd/system/atomic-test.service; bash process spawned by systemd with UID=0 executing id command

Expected Detection

Linux-focused detection should identify systemctl start on a newly-created service unit in /etc/systemd/system/ with ExecStart containing shell commands

Test 4 Service Creation via PowerShell New-Service Cmdlet
windows

Uses PowerShell's New-Service cmdlet to create a service with a binary path in the user's temp directory, simulating script-based service installation as used by PowerShell-based malware frameworks.

Command

powershell
Copy-Item $env:SystemRoot\System32\notepad.exe $env:TEMP\svctest.exe
New-Service -Name PSAtomicTestSvc -BinaryPathName "$env:TEMP\svctest.exe" -DisplayName "PS Atomic Test" -StartupType Manual -Description "Atomic Red Team Test Service"
Start-Service -Name PSAtomicTestSvc -ErrorAction SilentlyContinue
Get-Service -Name PSAtomicTestSvc

Cleanup

powershell
Stop-Service -Name PSAtomicTestSvc -Force -ErrorAction SilentlyContinue
(Get-WmiObject -Class Win32_Service -Filter "Name='PSAtomicTestSvc'").Delete()
Remove-Item $env:TEMP\svctest.exe -Force -ErrorAction SilentlyContinue

Expected Telemetry

SecurityEvent 7045 with ServiceName=PSAtomicTestSvc and ImagePath in %TEMP%; PowerShell ScriptBlock log EventID 4104 showing New-Service cmdlet; DeviceProcessEvents showing powershell.exe as initiating process for service creation API calls

Expected Detection

KQL DeviceProcessEvents query should not catch this directly (no sc.exe), but SecurityEvent 7045 union branch should fire on the %TEMP% path; analysts should note PowerShell as attack vector from 4104 logs

Related Detections

Tactic Hub