System Services
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/
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.
Data Sources
Required Tables
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:
Platform-specific guides for T1569
References (8)
- https://attack.mitre.org/techniques/T1569/
- https://attack.mitre.org/techniques/T1569/001/
- https://attack.mitre.org/techniques/T1569/002/
- https://attack.mitre.org/techniques/T1569/003/
- https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4697
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1569.002/T1569.002.md
- https://www.cybereason.com/blog/research/cybereason-vs-darkside-ransomware
- https://www.crowdstrike.com/blog/wizard-spider-adversary-update/
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.
- 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
- 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
- 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
- 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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
- 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.
- 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.
- 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.
- Block the malicious binary hash in your EDR/AV solution to prevent re-execution on this endpoint and deployment to others across the fleet.
- 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
- 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.
- 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
- 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.
- 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.
- 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
- 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.
// 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 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.
// 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 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.
// 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 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
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
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
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
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
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
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
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
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
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
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
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
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