// question

On a Windows host, suspicious PowerShell activity adjusted the system clock and recorded a value. What numeric value was used to slip the system date?

Reference KQL answer and model-by-model comparison.

7bcf83bf-f5ef-425c-9d9a-71618ad9ed12
question id
15/23
models correct
1
valid answer
65%
success rate
// reference answer

Human-validated correct answer for this question.

3
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
3
DeviceProcessEvents
| where InitiatingProcessFileName =~ "powershell.exe" or FileName =~ "powershell.exe"
| where ProcessCommandLine has "Set-Date" or InitiatingProcessCommandLine has "Set-Date"
| extend CommandLine = coalesce(ProcessCommandLine, InitiatingProcessCommandLine)
| extend ExtractedValue = extract(@'Set-Date.*?(-?\d+(\.\d+)?)', 1, CommandLine)
| where isnotempty(ExtractedValue)
| project Timestamp, DeviceName, CommandLine, ExtractedValue
pass241.63s0.0209
gpt-35-turbo
no answer
no query generatedfail50.00s0.0110
gpt-4-turbo-2024-04-09
no answer
no query generatedfail50.00s0.2359
gpt-4.1
3
DeviceProcessEvents
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where ProcessCommandLine has_any ("set-date", "Set-Date", "date ", "time ", "w32tm", "/set", "-date")
| extend SlippedValue = extract(@'(-?\d{1,5})', 1, ProcessCommandLine)
| where isnotempty(SlippedValue)
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, SlippedValue
| order by TimeGenerated desc
pass314.22s0.0270
gpt-4.1-finetuned
no answer
no query generatedfail50.00s0.0497
gpt-4.1-mini
3
DeviceProcessEvents
| where FileName contains "powershell" and (ProcessCommandLine contains "date" or ProcessCommandLine contains "Set-Date" or ProcessCommandLine contains "system clock")
| project DeviceName, InitiatingProcessAccountName, TimeGenerated, ProcessCommandLine, AdditionalFields
| extend NumericValue = extract(@"(\d+)", 1, ProcessCommandLine)
| summarize by NumericValue, ProcessCommandLine, DeviceName, InitiatingProcessAccountName, TimeGenerated
| where isnotempty(NumericValue)
pass116.62s0.0023
gpt-4.1-nano
3
DeviceProcessEvents 
| where ProcessCommandLine contains 'Set-Date' or ProcessCommandLine contains 'set-date' 
// Filter for suspicious activities involving system clock adjustments
| project TimeGenerated, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessId
| extend CommandLineLower = tolower(ProcessCommandLine)
| where CommandLineLower contains 'set-date'
// Attempt to extract the date value used
| extend SlipValue = extract(@'([+-]?\d+\b)', 1, ProcessCommandLine)
| project TimeGenerated, ProcessCommandLine, SlipValue
pass12.57s0.0005
gpt-4o
3
DeviceProcessEvents
| where InitiatingProcessFileName == "powershell.exe" 
| where InitiatingProcessCommandLine has_any ("Set-Date", "Adjust", "SystemTime")
| extend NumericValue = extract("\\d+", 0, InitiatingProcessCommandLine)
| project DeviceId, DeviceName, InitiatingProcessCommandLine, NumericValue, TimeGenerated
pass14.19s0.0146
gpt-5-high
3
let suspicious_ps = union isfuzzy=true
(
    DeviceProcessEvents
    | where tolower(FileName) in ("powershell.exe","pwsh.exe","powershell_ise.exe")
    | extend Text = coalesce(ProcessCommandLine, InitiatingProcessCommandLine)
),
(
    DeviceEvents
    | where ActionType has "PowerShell"
    | extend Text = coalesce(tostring(AdditionalFields.ScriptBlockText), tostring(AdditionalFields.Command), tostring(AdditionalFields.ScriptLine), ProcessCommandLine, InitiatingProcessCommandLine)
);
suspicious_ps
| where Text has_any ("set-date","adddays","addhours","addminutes","addseconds","-adjust")
| extend OffsetFromAdd = extract(@"(?i)Add(?:Days|Hours|Minutes|Seconds|Months)\s*\(\s*(-?\d+)\s*\)", 1, Text),
         UnitFromAdd   = extract(@"(?i)Add(Days|Hours|Minutes|Seconds|Months)", 1, Text),
         DaysAdj    = extract(@"(?i)-Days\s+(-?\d+)", 1, Text),
         HoursAdj   = extract(@"(?i)-Hours\s+(-?\d+)", 1, Text),
         MinutesAdj = extract(@"(?i)-Minutes\s+(-?\d+)", 1, Text),
         SecondsAdj = extract(@"(?i)-Seconds\s+(-?\d+)", 1, Text)
| extend SlipValue = toint(coalesce(OffsetFromAdd, DaysAdj, HoursAdj, MinutesAdj, SecondsAdj)),
         SlipUnit  = coalesce(UnitFromAdd,
                              iff(isnotempty(DaysAdj), "Days", ""),
                              iff(isnotempty(HoursAdj), "Hours", ""),
                              iff(isnotempty(MinutesAdj), "Minutes", ""),
                              iff(isnotempty(SecondsAdj), "Seconds", ""))
| where isnotempty(SlipValue)
| project TimeGenerated, DeviceName, AccountName, InitiatingProcessAccountName, FileName, CommandText = Text, SlipUnit, SlipValue
| order by TimeGenerated desc
| summarize LatestTime = arg_max(TimeGenerated, *) by DeviceName, SlipUnit, SlipValue
| order by LatestTime desc
pass190.12s0.0511
gpt-5-mini-high
3
union isfuzzy=true DeviceProcessEvents, DeviceEvents
| extend Cmd = strcat(tostring(ProcessCommandLine), " ", tostring(InitiatingProcessCommandLine), " ", tostring(AdditionalFields))
| where tolower(Cmd) contains "powershell" or tolower(Cmd) contains "pwsh"
| where tolower(Cmd) contains "set-date" or tolower(Cmd) contains "-date" or tolower(Cmd) contains "adddays" or tolower(Cmd) contains "addmonths" or tolower(Cmd) contains "addyears" or tolower(Cmd) contains "-adjust" or tolower(Cmd) contains "w32tm" or tolower(Cmd) contains "setlocaltime"
| extend Numbers = extract_all(@"(-?\d+(?:\.\d+)?)", Cmd)
| where array_length(Numbers) > 0
| mv-expand Numbers to typeof(string)
| extend NumericValue = todouble(Numbers)
| summarize Count = count(), LastSeen = max(TimeGenerated), SampleCommand = any(Cmd) by DeviceName, NumericValue
| order by LastSeen desc
| project LastSeen, DeviceName, NumericValue, Count, SampleCommand
pass239.94s0.0100
gpt-5-mini-low
3
let ps_processes = DeviceProcessEvents
| where (ProcessCommandLine has_cs "powershell" or ProcessCommandLine has_cs "pwsh" or InitiatingProcessCommandLine has_cs "powershell" or InitiatingProcessCommandLine has_cs "pwsh")
| extend cmd = coalesce(ProcessCommandLine, InitiatingProcessCommandLine)
| where cmd has_any ("Set-Date","Get-Date","AddDays","AddHours","AddMonths","-Adjust")
| extend cmd_str = tostring(cmd)
// capture numbers used directly in AddDays/AddHours/AddMonths(...) calls
| extend addvals = extract_all(@"(?:AddDays|AddHours|AddMonths)\(\s*([-+]?\d+(?:\.\d+)?)", cmd_str)
| mv-expand addvals to typeof(string)
| extend number = toreal(addvals)
| where isnotnull(number)
| project TimeGenerated, DeviceName, FileName, ProcessId, ProcessCommandLine = cmd_str, number;

let ps_deviceevents = DeviceEvents
| where (ProcessCommandLine has_cs "powershell" or ProcessCommandLine has_cs "pwsh" or InitiatingProcessCommandLine has_cs "powershell" or InitiatingProcessCommandLine has_cs "pwsh")
| extend cmd = coalesce(ProcessCommandLine, InitiatingProcessCommandLine, tostring(AdditionalFields))
| where isnotempty(cmd) and (cmd has_any ("Set-Date","Get-Date","AddDays","AddHours","AddMonths","-Adjust"))
| extend cmd_str = tostring(cmd)
| extend addvals = extract_all(@"(?:AddDays|AddHours|AddMonths)\(\s*([-+]?\d+(?:\.\d+)?)", cmd_str)
| mv-expand addvals to typeof(string)
| extend number = toreal(addvals)
| where isnotnull(number)
| project TimeGenerated, DeviceName, FileName, ProcessId, ProcessCommandLine = cmd_str, number;

ps_processes
| union ps_deviceevents
| summarize Count = count(), Examples = make_list(pack_all(), 10) by number
| order by Count desc
| project number, Count, ExampleEvent = Examples[0]
pass234.68s0.0076
gpt-5-mini-medium
no answer
no query generatedfail50.00s0.0164
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0083
gpt-5-nano-medium
3
let ps_clock_adjustments = DeviceProcessEvents
| where (tolower(InitiatingProcessFileName) endswith "powershell.exe" or tolower(InitiatingProcessCommandLine) contains "powershell")
| extend CmdLine = tostring(InitiatingProcessCommandLine)
| extend CmdLower = tolower(CmdLine)
| where CmdLower contains "set-date" or CmdLower contains "get-date" or CmdLower contains "addhours" or CmdLower contains "addminutes" or CmdLower contains "adddays" or CmdLower contains "addseconds"
| extend Hours = todouble(extract(@"addhours\(([-+]?\d+)\)", 1, CmdLower))
| extend Minutes = todouble(extract(@"addminutes\(([-+]?\d+)\)", 1, CmdLower))
| extend Seconds = todouble(extract(@"addseconds\(([-+]?\d+)\)", 1, CmdLower))
| extend Days = todouble(extract(@"adddays\(([-+]?\d+)\)", 1, CmdLower))
| extend DeltaValue = coalesce(Hours, Minutes, Seconds, Days, 0.0)
| where DeltaValue != 0.0
| extend Unit = case(isnotnull(Hours), "Hours", isnotnull(Minutes), "Minutes", isnotnull(Seconds), "Seconds", isnotnull(Days), "Days", "Unknown")
| project TimeGenerated, DeviceName, InitiatingProcessId, InitiatingProcessCommandLine, DeltaValue, Unit
; 
ps_clock_adjustments
| sort by TimeGenerated desc
| take 20
pass385.73s0.0049
grok-3-beta
3
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName =~ 'powershell.exe' or InitiatingProcessFileName =~ 'pwsh.exe'
| where ProcessCommandLine has_any ('Set-Date', 'date', 'time', 'clock')
| extend NumericValue = extract('[-+]?[0-9]+', 0, ProcessCommandLine)
| where isnotempty(NumericValue)
| project Timestamp, DeviceName, InitiatingProcessFileName, ProcessCommandLine, NumericValue
| order by Timestamp desc
pass110.38s0.0258
grok-3-mini-beta
no answer
no query generatedfail50.00s0.0073
o1-high
3
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where InitiatingProcessFileName in~ ("powershell.exe", "powershell_ise.exe", "pwsh.exe") or InitiatingProcessCommandLine contains "powershell"
| where ProcessCommandLine has_any ("Set-Date", "AddDays", "AddHours", "AddMinutes", "AddSeconds", "AddMonths", "AddYears")
| parse kind=regex ProcessCommandLine with ".*Add(?:Days|Hours|Minutes|Seconds|Months|Years)\\(" numericValue:long "\\).*"
| project TimeGenerated, DeviceName, InitiatingProcessCommandLine, ProcessCommandLine, numericValue
| order by TimeGenerated desc
pass258.87s0.4726
o1-low
3
union
(
    DeviceProcessEvents
    | where ActionType =~ "ProcessCreated"
    | where FileName =~ "powershell.exe"
    // Search for commands explicitly adjusting time using Set-Date -Adjust
    | where ProcessCommandLine has_all ("Set-Date", "-Adjust")
    | extend SlippedValue = extract(@"-[Aa]djust\s+([^\s]+)", 1, ProcessCommandLine)
    | project TimeGenerated, DeviceId, DeviceName, SlippedValue, ProcessCommandLine
),
(
    DeviceProcessEvents
    | where ActionType =~ "ProcessCreated"
    | where FileName =~ "powershell.exe"
    // Search for calls to time-additive methods like AddDays, AddHours, etc.
    | where ProcessCommandLine matches regex @"Add(?:Seconds|Minutes|Hours|Days)\([^\)]*\)"
    | extend SlippedValue = extract(@"Add(?:Seconds|Minutes|Hours|Days)\(([^\)]+)\)", 1, ProcessCommandLine)
    | project TimeGenerated, DeviceId, DeviceName, SlippedValue, ProcessCommandLine
)
| order by TimeGenerated desc
pass254.65s0.3708
o3-high
3
// Suspicious PowerShell – find the numeric delta used to move the system clock
// Time range is controlled by the workbook / hunting page
let TimeWindow = 14d;  // <- overwritten by caller – placeholder
// 1. Pull PowerShell executions that are likely to modify time or timezone
let PS_TimeCmds = DeviceProcessEvents
| where TimeGenerated between (ago(TimeWindow) .. now())
| where FileName =~ "powershell.exe"
      // Common ways to tamper with time from PowerShell
      //   – Set-Date  – (Get-Date).Add*  – w32tm /config …  – net time …  – tzutil …
| where ProcessCommandLine has_any ("Set-Date", "AddDays(", "AddHours(", "AddMinutes(", "AddSeconds(", "w32tm", "net time", "tzutil")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine;

// 2. Extract the numeric value that represents the amount of time the clock is shifted.
//    We try several patterns that attackers use.  The first one that matches wins.
PS_TimeCmds
| extend ShiftValue = extract(@"Add(?:Days|Hours|Minutes|Seconds)\(([-]?\d+)\)", 1, ProcessCommandLine)   // (Get-Date).AddDays(5)
| extend ShiftValue = iff(isnull(ShiftValue) or ShiftValue=="", extract(@"-Adjust\s+([+-]?\d+)", 1, ProcessCommandLine), ShiftValue) //  w32tm /config /update /manualpeerlist:"…" -Adjust 300
| extend ShiftValue = iff(isnull(ShiftValue) or ShiftValue=="", extract(@"Set-Date.*?-Date.*?([+-]?\d{1,4})", 1, ProcessCommandLine), ShiftValue) // Set-Date -Date "(Get-Date).AddHours(-2)"
| extend ShiftValue = iff(isnull(ShiftValue) or ShiftValue=="", extract(@"net\s+time.*?([+-]?\d{1,4})", 1, ProcessCommandLine), ShiftValue)
// 3. Show unique values + supporting evidence
| where ShiftValue != "" and ShiftValue != "-" and isnotnull(ShiftValue)
| summarize Events = count() by tostring(ShiftValue)
| order by Events desc
pass140.71s0.0270
o3-mini-high
no answer
no query generatedfail50.00s0.0362
o3-mini-low
no answer
no query generatedfail50.00s0.0375
o4-mini-high
3
DeviceProcessEvents
| where FileName in ("powershell.exe", "pwsh.exe")
| where ProcessCommandLine has "Set-Date"
| extend 
    directDateNumber = extract(@"-Date\s+([+-]?\d+)", 1, ProcessCommandLine),
    addMethodNumber = extract(@"Add(?:Days|Hours|Minutes|Seconds)\(([+-]?\d+)\)", 1, ProcessCommandLine)
| extend slipValue = coalesce(directDateNumber, addMethodNumber)
| where isnotempty(slipValue)
| project TimeGenerated, DeviceName, InitiatingProcessAccountName, slipValue, ProcessCommandLine
pass133.21s0.0121
o4-mini-low
3
DeviceProcessEvents
| where FileName in~ ("powershell.exe","pwsh.exe")
| where ProcessCommandLine has_any ("AddDays(", "Set-Date")
| extend SlipValueRaw = extract(@"\.AddDays\(\s*([+-]?\d+)\s*\)", 1, ProcessCommandLine)
| extend SlipValue = toint(SlipValueRaw)
| where isnotempty(SlipValue)
| project TimeGenerated, DeviceName, Account = InitiatingProcessAccountName, ProcessCommandLine, SlipValue
| sort by TimeGenerated asc
pass391.45s0.0332