Question Analysis
Suspicious PowerShell activity on a Windows machine shows an external script being fetched and executed, followed by a quiet SQL enumeration call. Using process event logs, identify the name of the tool executed immediately after the script retrieval.
0bb64470-582a-4155-bde2-d6003a95ed34
Question ID
1/23
Models Correct
1
Valid Answer
4%
Success Rate
Reference Answer
Human-validated correct answer for this question
powerSQL
Model Performance Comparison
See how different AI models performed on this question
Model | Answer | KQL Query | Status | Attempts | Time | Cost |
---|---|---|---|---|---|---|
gemini-2.5-flash-preview-04-17 | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0573 |
gpt-35-turbo | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0113 |
gpt-4-turbo-2024-04-09 | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.2544 |
gpt-4.1 | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0510 |
gpt-4.1-finetuned | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0496 |
gpt-4.1-mini | sshd.exe | DeviceProcessEvents
| where ProcessCommandLine has_any ("Invoke-WebRequest", "wget", "curl") and FileName == "powershell.exe"
| project DeviceId, InitiatingProcessSessionId, TimeGenerated, ProcessId, ProcessCommandLine
| join kind=inner (
DeviceProcessEvents
| project DeviceId, InitiatingProcessSessionId, TimeGenerated, ProcessId, FileName
) on DeviceId, InitiatingProcessSessionId
| where TimeGenerated > TimeGenerated1
| summarize min_Time = min(TimeGenerated1) by ProcessId1 = ProcessId, FileName, DeviceId, InitiatingProcessSessionId
| order by min_Time asc
| take 1
| project ToolExecutedAfterScriptRetrieval = FileName | Incorrect | 1 | 3.73s | 0.0023 |
gpt-4.1-nano | powershell.exe | let suspicious_ps = DeviceProcessEvents
| where FileName endswith '.ps1' or FileName endswith '.psm1' or tolower(FileName) contains 'powershell' or tolower(FileName) contains 'pwsh'
| extend cmdline = tolower(ProcessCommandLine)
| where cmdline contains 'invoke-webrequest' or cmdline contains 'invoke-restmethod' or cmdline contains 'downloadstring' or cmdline contains 'bitstransfer'
| project InitiatingProcessId, InitiatingProcessFileName, ProcessCommandLine, TimeGenerated;
let fetch_end_time = suspicious_ps
| summarize max(TimeGenerated) by InitiatingProcessId;
DeviceProcessEvents
| where InitiatingProcessId in (suspicious_ps | distinct InitiatingProcessId)
| join kind=inner (
fetch_end_time
) on $left.InitiatingProcessId == $right.InitiatingProcessId
| where TimeGenerated > max_TimeGenerated
| sort by TimeGenerated asc
| take 1
| project NextProcessName=InitiatingProcessFileName, TimeGenerated, InitiatingProcessId | Incorrect | 4 | 17.28s | 0.0014 |
gpt-4o | powershell.exe | let powershell_activity = DeviceProcessEvents
| where InitiatingProcessFileName has "powershell.exe" and ProcessCommandLine contains "http"
| project DeviceId, PowershellProcessCreationTime = ProcessCreationTime;
DeviceProcessEvents
| join kind=inner (powershell_activity) on DeviceId
| where ProcessCreationTime > PowershellProcessCreationTime
| summarize ToolName = any(FileName), MinTime = min(ProcessCreationTime) by DeviceId
| order by MinTime asc | Incorrect | 4 | 31.69s | 0.0565 |
gpt-5-high | csc.exe | let lookahead = 10m;
let ps_fetch =
DeviceProcessEvents
| where FileName in~ ('powershell.exe','pwsh.exe','powershell_ise.exe')
| extend cmd = tolower(tostring(ProcessCommandLine))
| where cmd has_any ('invoke-webrequest','iwr','wget','curl','start-bitstransfer','bitsadmin','downloadstring','downloadfile','net.webclient','invoke-restmethod','irm','new-object system.net.webclient')
| where cmd has_any ('iex','invoke-expression')
| project DeviceId, DeviceName, AccountDomain, AccountName, PSProcessId=ProcessId, PSProcessCreationTime=ProcessCreationTime, PSCommand=ProcessCommandLine;
let children =
DeviceProcessEvents
| project DeviceId, ChildTime=ProcessCreationTime, ChildFileName=FileName, ChildCommandLine=ProcessCommandLine, ParentPid=InitiatingProcessId, ParentCreationTime=InitiatingProcessCreationTime, ChildPid=ProcessId;
ps_fetch
| join kind=inner children on DeviceId
| where ParentPid == PSProcessId
| where ParentCreationTime between (PSProcessCreationTime - 1s .. PSProcessCreationTime + 1s)
| where ChildTime between (PSProcessCreationTime .. PSProcessCreationTime + lookahead)
| summarize arg_min(ChildTime, *) by DeviceId, DeviceName, PSProcessId, PSProcessCreationTime, PSCommand, AccountDomain, AccountName
| extend ExecutedTool = ChildFileName, ExecutedToolCommandLine = ChildCommandLine, ExecutedTime = ChildTime
| extend cmd_lc = tolower(tostring(ExecutedToolCommandLine)), tool_lc = tolower(tostring(ExecutedTool))
| extend IsLikelySqlEnum = iif(tool_lc in ('sqlcmd.exe','osql.exe','sqlplus.exe','isql.exe','sqlps.exe') or cmd_lc has_any ('invoke-sqlcmd','powerupsql',' -q ',' -Q ','select ','sp_help','xp_cmdshell'), true, false)
| project DeviceName, ExecutedTime, ExecutedTool, ExecutedToolCommandLine, FetchTime=PSProcessCreationTime, PSCommand, AccountDomain, AccountName, IsLikelySqlEnum
| order by FetchTime desc | Incorrect | 3 | 282.68s | 0.1795 |
gpt-5-mini-high | csc.exe | let fetchers = DeviceProcessEvents
| where FileName has_cs "powershell" or ProcessCommandLine has_cs "powershell" or ProcessCommandLine has_cs "pwsh"
| where ProcessCommandLine has_any ("Invoke-WebRequest", "Invoke-RestMethod", "IEX", "iex", "-EncodedCommand", "-enc", "-Command", "-c", "Start-Process", "-File")
| extend FetchTime = ProcessCreationTime
| project DeviceId, DeviceName, InitiatingProcessId, ProcessId, ProcessCommandLine, FileName, ProcessCreationTime, FetchTime;
fetchers
| join kind=inner (
DeviceProcessEvents
| where ProcessCreationTime >= ago(7d)
| project DeviceId, DeviceName, ChildProcessId = ProcessId, ChildFileName = FileName, ChildCommandLine = ProcessCommandLine, ChildCreationTime = ProcessCreationTime, InitiatingProcessId = InitiatingProcessId
) on DeviceId
| where ChildCreationTime >= FetchTime and ChildCreationTime <= FetchTime + 2m
| where ChildProcessId != ProcessId
| summarize arg_min(ChildCreationTime, *) by DeviceId, FetchTime, ProcessId
| project DeviceName, DeviceId, FetchTime, PowerShellProcessId = ProcessId, PowerShellCmdLine = ProcessCommandLine, ToolExecuted = ChildFileName, ToolCmdLine = ChildCommandLine, ToolCreationTime = ChildCreationTime
| order by FetchTime desc
| take 50 | Incorrect | 1 | 30.22s | 0.0069 |
gpt-5-mini-low | powershell | let suspicious_ps = DeviceProcessEvents
| where FileName has_cs "powershell" or ProcessCommandLine has_cs "powershell"
| where ProcessCommandLine has_any ("IEX","Invoke-Expression","DownloadString","DownloadFile","Invoke-WebRequest","Invoke-RestMethod","curl","wget","-EncodedCommand","-e","-Command","-c")
| project DeviceName, PsTime=ProcessCreationTime, PsProcessId=ProcessId, PsCommandLine=ProcessCommandLine, PsFileName=FileName, InitiatingProcessId=InitiatingProcessId;
suspicious_ps
| join kind=inner (
DeviceProcessEvents
| project DeviceName, Time=ProcessCreationTime, ProcessId, FileName, ProcessCommandLine, InitiatingProcessId
) on DeviceName
| where Time > PsTime and Time <= PsTime + 2m
| where ProcessId != PsProcessId
| summarize arg_min(Time, *) by PsProcessId, PsTime, DeviceName, PsCommandLine
| project DeviceName, PsTime, PsProcessId, PsCommandLine, SubsequentProcessName=FileName, SubsequentProcessId=ProcessId, SubsequentProcessCommandLine=ProcessCommandLine, SubsequentProcessTime=Time
| sort by PsTime asc
| take 50 | Incorrect | 1 | 22.33s | 0.0069 |
gpt-5-mini-medium | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0137 |
gpt-5-nano-high | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0118 |
gpt-5-nano-medium | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0096 |
grok-3-beta | SenseIR.exe | let TimeRange = ago(7d);
DeviceProcessEvents
| where TimeGenerated >= TimeRange
| where InitiatingProcessFileName =~ 'powershell.exe'
| where ProcessCommandLine has_any ('Invoke-WebRequest', 'DownloadString', 'http://', 'https://')
| project ScriptDownloadTime=ProcessCreationTime, DeviceId, PowerShellCommandLine=ProcessCommandLine, InitiatingProcessId
| join kind=inner (
DeviceProcessEvents
| where TimeGenerated >= TimeRange
| project SubsequentProcessTime=ProcessCreationTime, DeviceId, SubsequentProcessName=FileName, SubsequentCommandLine=ProcessCommandLine, SubsequentProcessId=ProcessId
) on DeviceId
| where SubsequentProcessTime between (ScriptDownloadTime .. (ScriptDownloadTime + 5m))
| where SubsequentProcessTime > ScriptDownloadTime
| summarize FirstToolExecuted = min(SubsequentProcessName), SubsequentCommandLine = min(SubsequentCommandLine) by DeviceId, ScriptDownloadTime, PowerShellCommandLine
| project DeviceId, ScriptDownloadTime, PowerShellCommandLine, FirstToolExecuted, SubsequentCommandLine
| order by ScriptDownloadTime asc | Incorrect | 1 | 15.70s | 0.0688 |
grok-3-mini-beta | nmap-7.80-setup.exe | DeviceProcessEvents
| where InitiatingProcessFileName =~ 'powershell.exe' and InitiatingProcessCommandLine matches regex @'\b(Invoke-WebRequest|curl|wget)\b.*'
| order by ProcessCreationTime asc
| take 1
| project ToolExecuted = FileName | Incorrect | 2 | 30.80s | 0.0030 |
o1-high | powershell.exe | let suspiciousEvents = DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where FileName =~ "powershell.exe"
| where ProcessCommandLine has "http" // indicates external script fetch
| project DeviceId, SuspiciousTime=ProcessCreationTime;
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| join kind=inner suspiciousEvents on DeviceId
| where ProcessCreationTime > SuspiciousTime
| order by ProcessCreationTime asc
| summarize arg_min(ProcessCreationTime, *) by DeviceId, SuspiciousTime
| project DeviceName,
ToolExecutedImmediatelyAfter=FileName,
CommandLine=ProcessCommandLine,
ExecutionTime=ProcessCreationTime | Incorrect | 2 | 57.06s | 0.3903 |
o1-low | nmap-7.80-setup.exe | // Replace or adjust the time filter as needed.
DeviceProcessEvents
| where FileName =~ "powershell.exe"
| where ProcessCommandLine has_any ("invoke-webrequest", "iex", "downloadstring", "curl", "bitsadmin", "http")
| project DeviceId,
DeviceName,
ParentProcessId = ProcessId,
ParentStartTime = ProcessCreationTime,
ParentCommand = ProcessCommandLine
// Join to find child processes created by this PowerShell process.
| join kind=inner (
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| project DeviceId,
ChildProcessName = FileName,
ChildCommandLine = ProcessCommandLine,
ChildProcessId = ProcessId,
ChildStartTime = ProcessCreationTime,
InitiatingProcessId
) on DeviceId
| where InitiatingProcessId == ParentProcessId
and ChildStartTime > ParentStartTime
| order by ChildStartTime asc
// For each PowerShell event, take the earliest (arg_min) child process event.
| summarize arg_min(ChildStartTime, *) by ParentProcessId, DeviceId
| project DeviceName,
ParentCommand,
ExecutedTool = ChildProcessName,
ExecutedToolCommandLine = ChildCommandLine,
ChildStartTime | Incorrect | 1 | 70.66s | 0.5200 |
o3-high | conhost.exe | // 1) Locate PowerShell processes that appear to download and immediately execute a remote script
let SuspiciousPowerShell = DeviceProcessEvents
| where FileName =~ "powershell.exe"
| extend cmd = tostring(ProcessCommandLine), cmd_lc = tolower(ProcessCommandLine)
| where cmd_lc has_any ("invoke-webrequest","invoke_webrequest","wget ","curl ","downloadstring(","bitsadmin","http://","https://") // remote fetch
| where cmd_lc has_any ("iex","invoke-expression","-exec","-encodedcommand","-executionpolicy bypass") // execution hints
| project DeviceId, DeviceName, FetchTime = ProcessCreationTime, FetchProcId = ProcessId,
FetchCmd = ProcessCommandLine, FetchParentId = InitiatingProcessId;
// 2) For each of those, find the very first child process launched after the fetch (within 10 minutes)
let ChildProcWindow = 10m;
DeviceProcessEvents
| where InitiatingProcessId in (SuspiciousPowerShell | project FetchProcId)
| join kind=inner (SuspiciousPowerShell) on $left.InitiatingProcessId == $right.FetchProcId and $left.DeviceId == $right.DeviceId
| where ProcessCreationTime > FetchTime and ProcessCreationTime <= FetchTime + ChildProcWindow
| summarize FirstChildTime = min(ProcessCreationTime) by DeviceId, DeviceName, FetchTime, FetchCmd, FetchProcId, ChildProcessId = ProcessId, ChildFileName = FileName, ChildCmd = ProcessCommandLine
| order by FetchTime desc
| project DeviceName, FetchTime, DownloaderCommand = FetchCmd, EnumerationStart = FirstChildTime,
EnumerationTool = ChildFileName, EnumerationCommand = ChildCmd | Incorrect | 1 | 100.30s | 0.0461 |
o3-mini-high | nmap | DeviceProcessEvents
| sort by DeviceName, TimeGenerated asc
| extend Prev_Process = prev(InitiatingProcessFileName), Prev_Command = prev(InitiatingProcessCommandLine)
// Filter for events where the previous event was a PowerShell fetching an external script (assuming 'http' in the command line indicates an external script call)
| where isnotempty(Prev_Command) and tolower(Prev_Process) == 'powershell.exe' and Prev_Command contains "http"
| project DeviceName, ScriptRetrievalTime = prev(TimeGenerated), RetrievalCommand = Prev_Command, SuspiciousToolTime = TimeGenerated, SuspiciousTool = InitiatingProcessFileName, SuspiciousToolCommand = ProcessCommandLine
| summarize arg_min(SuspiciousToolTime, *) by DeviceName
| Incorrect | 1 | 30.42s | 0.0161 |
o3-mini-low | powershell | DeviceProcessEvents
| sort by DeviceName asc, ProcessCreationTime asc
| serialize
| extend PrevDeviceName = prev(DeviceName)
| extend PrevFileName = prev(FileName)
| extend PrevCmdLine = prev(ProcessCommandLine)
| extend PrevCreationTime = prev(ProcessCreationTime)
| where DeviceName == PrevDeviceName
| where isnotempty(PrevCmdLine) and PrevCmdLine contains "http" and tostring(PrevFileName) =~ "powershell.exe"
| project DeviceName,
ScriptRetrievalTime = PrevCreationTime,
ScriptRetrievalCmdLine = PrevCmdLine,
ToolExecutedAfterScriptRetrieval = FileName,
NextEventTime = ProcessCreationTime,
NextEventCmdLine = ProcessCommandLine
| order by NextEventTime asc | Incorrect | 2 | 46.47s | 0.0454 |
o4-mini-high | powerSQL | // 1) Identify PowerShell script-download events
let downloads = DeviceProcessEvents
| where FileName in ("powershell.exe", "pwsh.exe")
// look for download methods in the command line
| where ProcessCommandLine matches regex @"(?i)(Invoke-WebRequest|DownloadString|DownloadFile|-Url\s+https?://)"
| project DeviceId, DownloadPid = ProcessId, DownloadTime = TimeGenerated;
// 2) Find child processes launched by those PowerShell PIDs after the download
let childProcs = DeviceProcessEvents
| where InitiatingProcessParentId in (downloads | distinct DownloadPid)
| project DeviceId, ParentPid = InitiatingProcessParentId, ChildName = FileName, ChildTime = TimeGenerated, ChildCmd = ProcessCommandLine;
// 3) Join and pick the first child process per download
downloads
| join kind=inner childProcs on DeviceId, $left.DownloadPid == $right.ParentPid
| where ChildTime > DownloadTime
| summarize arg_min(ChildTime, ChildName, ChildCmd, ChildTime) by DownloadPid, DeviceId
| project ToolExecuted = ChildName, ExecutionTime = ChildTime, CommandLine = ChildCmd | Correct | 1 | 62.90s | 0.0179 |
o4-mini-low | nmap-7.80-setup.exe | let scriptFetches = DeviceProcessEvents
| where FileName == "powershell.exe"
| where ProcessCommandLine has_any ("Invoke-WebRequest", "IWR", "wget", "curl")
| project FetchTime = TimeGenerated, FetchPID = ProcessId, DeviceId, DeviceName, FetchCommandLine = ProcessCommandLine;
let childProcesses = DeviceProcessEvents
| project ChildTime = TimeGenerated, InitiatingProcessId, ChildTool = FileName, ChildCommandLine = ProcessCommandLine, DeviceId;
scriptFetches
| join kind=inner (
childProcesses
) on $left.FetchPID == $right.InitiatingProcessId, $left.DeviceId == $right.DeviceId
| where ChildTime > FetchTime
| summarize arg_min(ChildTime, ChildTool, ChildCommandLine) by DeviceName, DeviceId, FetchTime, FetchPID, FetchCommandLine
| project DeviceName,
DeviceId,
FetchTime,
FetchCommandLine,
ToolExecuted = ChildTool,
ToolCommandLine = ChildCommandLine,
ExecutionTime = ChildTime
| sort by FetchTime asc | Incorrect | 2 | 98.61s | 0.0336 |