// question

A threat actor on a Windows system crafted and registered a service named almost identically to the standard time service, but redirecting execution to a custom script. Review the logging data to determine which native command-line tool was used to perform this action. What utility was invoked?

Reference KQL answer and model-by-model comparison.

b721c6ef-472c-4263-a0d9-37f1f4ecff66
question id
9/23
models correct
1
valid answer
39%
success rate
// reference answer

Human-validated correct answer for this question.

sc
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
no answer
no query generatedfail50.00s0.0532
gpt-35-turbo
no answer
no query generatedfail50.00s0.0110
gpt-4-turbo-2024-04-09
sc
DeviceProcessEvents
| where FileName has_any ('sc.exe', 'svchost.exe')
| where ProcessCommandLine contains 'create' or ProcessCommandLine contains 'config' or ProcessCommandLine contains 'delete'
| summarize Count=count() by ProcessCommandLine, InitiatingProcessFileName
| order by Count desc
pass114.63s0.0552
gpt-4.1
sc.exe
DeviceProcessEvents
| where Timestamp >= ago(7d) // Adjust as needed for your investigation window
| where FileName in~ ("sc.exe", "powershell.exe", "cmd.exe", "reg.exe")
| where ProcessCommandLine has_any ("create", "config", "service")
| where ProcessCommandLine matches regex @"(?i)w?32?time"
| project Timestamp, DeviceName, FileName, ProcessCommandLine
pass17.84s0.0124
gpt-4.1-finetuned
no answer
no query generatedfail50.00s0.0413
gpt-4.1-mini
sc
DeviceProcessEvents
| where ProcessCommandLine has_any ("create", "config", "delete")
| where ProcessCommandLine contains_cs "time" or ProcessCommandLine contains_cs "w32time" or ProcessCommandLine contains_cs "tim"
| where InitiatingProcessFileName in ("sc.exe", "powershell.exe", "cmd.exe", "New-Service", "net.exe") or FileName in ("sc.exe", "powershell.exe", "cmd.exe", "net.exe")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, ProcessCommandLine
| sort by TimeGenerated desc
| distinct InitiatingProcessFileName, ProcessCommandLine, DeviceName, TimeGenerated
pass28.54s0.0047
gpt-4.1-nano
no answer
no query generatedfail50.00s0.0015
gpt-4o
no answer
no query generatedfail50.00s0.0494
gpt-5-high
reg.exe
let script_indicators = dynamic([".ps1", ".bat", ".cmd", ".vbs", ".js", "wscript.exe", "cscript.exe", "powershell.exe", "cmd.exe", " /c ", " -file "]);
let svc_mods =
    DeviceEvents
    | where ActionType in ("ServiceInstalled","ServiceCreated","ServiceRegistered","ServiceModified","ServiceConfigurationChanged")
    | extend svcName = tostring(AdditionalFields.ServiceName),
             svcDisp = tostring(AdditionalFields.ServiceDisplayName),
             imgPath = tolower(coalesce(tostring(AdditionalFields.NewBinaryPathName), tostring(AdditionalFields.BinaryPathName), tostring(AdditionalFields.ImagePath), tostring(AdditionalFields.ServiceImagePath)))
    // Heuristics: name/display similar to time service (contains w32+time or windows+time) OR image path points to a script
    | extend name_l = tolower(svcName), disp_l = tolower(svcDisp)
    | extend IsTimeLike = (name_l has "time" or disp_l has "time")
    | extend IsW32Timeish = (name_l has "w32" and name_l has "time") or (disp_l has "windows" and disp_l has "time")
    | extend IsScriptPath = iff(isempty(imgPath), bool(false), imgPath has_any (script_indicators))
    | where IsScriptPath or IsW32Timeish
    | project TimeGenerated, DeviceId, DeviceName, Source="ServiceEvent", ServiceName=svcName, ServiceDisplayName=svcDisp, ImagePath=imgPath,
              ActorProcess=tolower(InitiatingProcessFileName), ActorCommand=InitiatingProcessCommandLine;
let reg_mods =
    DeviceRegistryEvents
    | where ActionType in ("RegistryValueSet","RegistryKeyCreated","RegistryKeyRenamed")
    | where tolower(RegistryValueName) == "imagepath"
    | extend ServiceName = extract(@"\\services\\([^\\]+)", 1, tostring(RegistryKey))
    | extend name_l = tolower(ServiceName), key_l = tolower(RegistryKey)
    | where key_l contains "\\system\\currentcontrolset\\services\\"
    // Heuristics: similar to time service
    | where (name_l has "time" and (name_l has "w32" or name_l has "windows"))
    | extend ImagePath = tolower(tostring(RegistryValueData))
    | where ImagePath has_any (script_indicators)
    | project TimeGenerated, DeviceId, DeviceName, Source="Registry", ServiceName, ServiceDisplayName=strcat(""), ImagePath,
              ActorProcess=tolower(InitiatingProcessFileName), ActorCommand=InitiatingProcessCommandLine;
let process_cmds =
    DeviceProcessEvents
    | where FileName in~ ("sc.exe","sc","reg.exe","powershell.exe","wmic.exe")
    | extend cmd_l = tolower(ProcessCommandLine)
    | where cmd_l matches regex @"\b(sc(\.exe)?\s+(create|config)|reg(\.exe)?\s+add|wmic(\.exe)?\s+service|powershell(\.exe)?\s+.*(new-service|set-service))"
    | where cmd_l has_any ("w32","windows"," time ")
    | project TimeGenerated, DeviceId, DeviceName, Source="ProcessCmd", ServiceName=strcat(""), ServiceDisplayName=strcat(""), ImagePath=strcat(""),
              ActorProcess=tolower(FileName), ActorCommand=ProcessCommandLine;
union isfuzzy=true svc_mods, reg_mods, process_cmds
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Events=count(), ExampleCommands=make_set(ActorCommand, 5) by DeviceName, ActorProcess
| order by Events desc, LastSeen desc
| project DeviceName, ActorProcess, Events, FirstSeen, LastSeen, ExampleCommands
fail2230.08s0.1359
gpt-5-mini-high
no answer
no query generatedfail50.00s0.0209
gpt-5-mini-low
sc.exe
let TimeWindow = 5m;
let ScriptIndicators = dynamic([".ps1",".bat",".cmd",".vbs",".js","powershell.exe","C:\\Users\\"]);
// Registry writes that set ImagePath under Services
let svcReg = DeviceRegistryEvents
| where RegistryKey has_cs "\\Services\\" and RegistryValueName == "ImagePath"
| where (
    RegistryValueData has_any (".ps1", ".bat", ".cmd", ".vbs", ".js")
    or tolower(RegistryValueData) contains "powershell.exe"
    or RegistryValueData contains "C:\\Users\\"
)
| project DeviceId, DeviceName, ServiceKey = RegistryKey, ImagePath = RegistryValueData, RegTime = TimeGenerated, RegInitiatingProcessFileName = InitiatingProcessFileName, RegInitiatingProcessCommandLine = InitiatingProcessCommandLine;

// Candidate processes that can create or modify services
let svcCreators = DeviceProcessEvents
| where (
        (ProcessCommandLine has_cs "sc.exe" and ProcessCommandLine has_cs "create")
        or (ProcessCommandLine has_cs "sc create")
        or (ProcessCommandLine has_cs "reg.exe" and ProcessCommandLine has_cs "add")
        or (ProcessCommandLine has_cs "reg add")
        or (ProcessCommandLine has_cs "New-Service")
        or (ProcessCommandLine has_cs "InstallUtil")
        or (ProcessCommandLine has_cs "nssm.exe")
        or (ProcessCommandLine has_cs "sdset")
        or (ProcessCommandLine has_cs "sc config")
    )
| extend ProcFile = tostring(FileName), ProcCommandLine = tostring(ProcessCommandLine), ProcTime = TimeGenerated
| project DeviceId, DeviceName, ProcFile, ProcCommandLine, ProcTime, ProcessId;

// Correlate by device and time
svcReg
| join kind=leftouter (svcCreators) on DeviceId
| where abs(RegTime - ProcTime) <= TimeWindow
| summarize Count = count(), AnyImagePath = any(ImagePath), AnyServiceKey = any(ServiceKey), AnyRegInitiatingProcessFileName = any(RegInitiatingProcessFileName), AnyRegInitiatingProcessCommandLine = any(RegInitiatingProcessCommandLine), ProcFiles = make_set(ProcFile), ProcCmds = make_set(ProcCommandLine) by DeviceId, DeviceName
| extend InvokedUtilities = strcat_array(ProcFiles, ", ")
| project DeviceId, DeviceName, Count, AnyServiceKey, AnyImagePath, AnyRegInitiatingProcessFileName, AnyRegInitiatingProcessCommandLine, InvokedUtilities, ProcCmds
| order by Count desc
| take 50

// also show direct registry initiators for entries with no matching process
| union (
    svcReg
    | where isnull(RegInitiatingProcessFileName) == false
    | summarize DirectRegWrites = count(), ExampleImagePath = any(ImagePath) by RegInitiatingProcessFileName, RegInitiatingProcessCommandLine
    | order by DirectRegWrites desc
    | project DeviceId = "-", DeviceName = "-", Count = DirectRegWrites, AnyServiceKey = "-", AnyImagePath = ExampleImagePath, AnyRegInitiatingProcessFileName = RegInitiatingProcessFileName, AnyRegInitiatingProcessCommandLine = RegInitiatingProcessCommandLine, InvokedUtilities = RegInitiatingProcessFileName, ProcCmds = pack_array(RegInitiatingProcessCommandLine)
)
pass245.87s0.0127
gpt-5-mini-medium
sc
(
    DeviceProcessEvents
    | where ProcessCommandLine has_any ("sc.exe","sc ","reg.exe","reg ","New-Service","InstallUtil.exe","installutil","schtasks","nssm","powershell")
    // match common service-creation patterns and a service name that includes "time"/"w32time"/"windows time"
    | where ProcessCommandLine matches regex @"(?i).*(((\bsc(\.exe)?\b).*\bcreate\b)|((\breg(\.exe)?\b).*\badd\b)|(\bNew-Service\b)|(\bInstallUtil\b)|(\bschtasks\b.*\bcreate\b)).*(time|w32time|windows\s*time).*"
    | project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, ProcessCommandLine, ProcessId, InitiatingProcessId
)
| union (
    DeviceRegistryEvents
    | where RegistryKey contains "SYSTEM\\CurrentControlSet\\Services"
    // registry key name contains "time" (covers similarly-named crafted service keys)
    | where tolower(RegistryKey) contains "time"
    | project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessId
)
| order by TimeGenerated desc
| limit 50
pass126.44s0.0072
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0101
gpt-5-nano-medium
no answer
no query generatedfail50.00s0.0092
grok-3-beta
sc
let TimeRange = ago(30d);
union DeviceRegistryEvents, DeviceProcessEvents, DeviceEvents
| where Timestamp > TimeRange
| where (Type == 'DeviceRegistryEvents' and RegistryKey contains 'SYSTEM\\CurrentControlSet\\Services' and RegistryKey matches regex '(?i)(w32time|time|timeservice)')
   or (Type == 'DeviceProcessEvents' and ProcessCommandLine matches regex '(?i)(sc\\s+create|sc\\s+config|New-Service|Set-Service|reg\\s+add|reg\\s+set)' and ProcessCommandLine matches regex '(?i)(w32time|time|timeservice)')
   or (Type == 'DeviceEvents' and InitiatingProcessCommandLine matches regex '(?i)(sc\\s+create|sc\\s+config|New-Service|Set-Service|reg\\s+add|reg\\s+set)' and InitiatingProcessCommandLine matches regex '(?i)(w32time|time|timeservice)')
| where InitiatingProcessFileName matches regex '(?i)(sc\\.exe|reg\\.exe|powershell\\.exe|cmd\\.exe)'
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RegistryKey, RegistryValueName, RegistryValueData, ProcessCommandLine, Type, ActionType
| order by Timestamp desc
pass553.72s0.1061
grok-3-mini-beta
no answer
no query generatedfail50.00s0.0071
o1-high
sc.exe
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where FileName in~ ("sc.exe","reg.exe","cmd.exe","powershell.exe","wmic.exe","net.exe")
| where ProcessCommandLine has_any ("create", "config", "service", "binPath", "w32time")
| project TimeGenerated, DeviceName, InitiatingProcessAccountName, FileName, ProcessCommandLine
| order by TimeGenerated desc
pass147.99s0.2770
o1-low
sc
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where tolower(ProcessCommandLine) has_any ("sc create", "sc config")
      and tolower(ProcessCommandLine) contains "time"
| project TimeGenerated, DeviceName, InitiatingProcessCommandLine, ProcessCommandLine, AccountName
| order by TimeGenerated desc
pass136.70s0.2778
o3-high
no answer
no query generatedfail50.00s0.0946
o3-mini-high
no answer
no query generatedfail50.00s0.0490
o3-mini-low
no answer
no query generatedfail50.00s0.0500
o4-mini-high
no answer
no query generatedfail50.00s0.0536
o4-mini-low
sc
DeviceProcessEvents
| where ProcessCommandLine has_cs "sc create"
| project TimeGenerated, DeviceName, Account=InitiatingProcessAccountName, FileName, ProcessCommandLine
| order by TimeGenerated desc
pass141.83s0.0126