Question Analysis

Windows process creation logs show a PowerShell-driven file transfer to an FTP service. Which executable was leveraged to perform this exfiltration?

b854eb97-bf9b-45ab-a1b5-b94e4880c56b
Question ID
16/23
Models Correct
1
Valid Answer
70%
Success Rate
Reference Answer

Human-validated correct answer for this question

rclone.exe
Model Performance Comparison

See how different AI models performed on this question

ModelAnswerKQL QueryStatusAttemptsTimeCost
gemini-2.5-flash-preview-04-17
rclone.exe
DeviceProcessEvents | where InitiatingProcessFileName =~ "powershell.exe" | where ProcessCommandLine has "ftp" | distinct FileName
Correct
1
7.19s
0.0026
gpt-35-turbo
rclone.exe
DeviceProcessEvents | where ProcessCommandLine contains 'powershell' and ProcessCommandLine contains 'ftp' | project DeviceName, ProcessId, ProcessCommandLine
Correct
1
2.31s
0.0024
gpt-4-turbo-2024-04-09
rclone.exe
DeviceProcessEvents | where InitiatingProcessFileName == 'powershell.exe' and ProcessCommandLine has 'ftp' | project DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine, TimeGenerated
Correct
1
9.39s
0.0541
gpt-4.1
rclone.exe
DeviceProcessEvents | where InitiatingProcessFileName =~ "powershell.exe" or InitiatingProcessCommandLine has "powershell" | where ProcessCommandLine has_any ("ftp", "put", "ftp:") | where FileName !~ "powershell.exe" | project TimeGenerated, DeviceName, AccountName, ParentProcess=InitiatingProcessFileName, ParentCommand=InitiatingProcessCommandLine, ExfilExecutable=FileName, ExfilCommand=ProcessCommandLine | summarize ExfilCount=count() by ExfilExecutable, ExfilCommand | sort by ExfilCount desc
Correct
2
11.56s
0.0223
gpt-4.1-finetuned
No answer provided
No query generated
Incorrect
5
0.00s
0.0445
gpt-4.1-mini
rclone.exe
DeviceProcessEvents | where InitiatingProcessFileName == "powershell.exe" | where ProcessCommandLine has_any ("ftp", "-ftp", "ftp://", "ftp.") | project TimeGenerated, DeviceName, AccountName, InitiatingProcessFileName, ProcessFileName = FileName, ProcessCommandLine | distinct ProcessFileName, ProcessCommandLine
Correct
1
6.22s
0.0023
gpt-4.1-nano
rclone.exe
DeviceProcessEvents | where ProcessCommandLine contains 'powershell' and ProcessCommandLine contains 'ftp' | project InitiatingProcessFileName, ProcessCommandLine, InitiatingProcessCreationTime, DeviceName
Correct
1
1.84s
0.0005
gpt-4o
rclone.exe
let PowerShell_FTP_Events = DeviceProcessEvents | where InitiatingProcessFileName =~ 'powershell.exe' and InitiatingProcessCommandLine contains 'ftp' | project Timestamp, InitiatingProcessCommandLine, InitiatingProcessFileName, DeviceName, AccountName; PowerShell_FTP_Events
Correct
3
23.44s
0.0350
gpt-5-high
rclone.exe
let ps_bins = dynamic(["powershell.exe","pwsh.exe","powershell_ise.exe"]); let ftp_tools = dynamic(["ftp.exe","winscp.exe","winscp.com","psftp.exe","curl.exe","wget.exe","bitsadmin.exe","certutil.exe","tftp.exe","rclone.exe"]); let ftp_markers = dynamic(["ftp://","ftps://","WebRequestMethods+Ftp","FtpWebRequest"," -Method Ftp"," -Method ftp","Invoke-WebRequest","Start-BitsTransfer"]); DeviceProcessEvents | where InitiatingProcessFileName in (ps_bins) | where FileName in (ftp_tools) or ProcessCommandLine has_any (ftp_markers) or InitiatingProcessCommandLine has_any (ftp_markers) | summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), EventCount=count(), sample_child_cmd=any(ProcessCommandLine), sample_parent_cmd=any(InitiatingProcessCommandLine) by Executable=tolower(FileName) | order by EventCount desc, LastSeen desc
Correct
2
177.34s
0.0970
gpt-5-mini-high
No answer provided
No query generated
Incorrect
5
0.00s
0.0257
gpt-5-mini-low
rclone.exe
// Detect PowerShell-driven FTP exfiltration and identify the executable used for exfiltration let ftp_regex = "(?i)(ftp://|\\bftp\\b|ftps://|\\bSTOR\\b|\\bPORT\\b|Invoke-WebRequest|Invoke-RestMethod|WebClient|UploadFile\\(|System\\.Net\\.FtpWebRequest|ftp\\.exe|\\bcurl\\b|\\bwget\\b|\\bbitsadmin\\b|\\bcertutil\\b)"; // 1) PowerShell processes that reference FTP in their commandline let ps_direct = DeviceProcessEvents | where FileName has_cs "powershell" or ProcessCommandLine has_cs "powershell" or ProcessCommandLine has_cs "pwsh" | where tostring(ProcessCommandLine) matches regex ftp_regex | project TimeGenerated, DeviceName, AccountName, ExfiltratingExecutable = tolower(FileName), ProcessId, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessId; // 2) Child processes spawned by PowerShell that look like FTP/upload tools let child_procs = DeviceProcessEvents | where isnotempty(InitiatingProcessFileName) and (tolower(InitiatingProcessFileName) has "powershell" or tolower(InitiatingProcessCommandLine) has "powershell" or tolower(InitiatingProcessCommandLine) has "pwsh") | where tolower(FileName) has_any ("ftp","curl","wget","bitsadmin","certutil","ftp.exe") or tostring(ProcessCommandLine) matches regex ftp_regex | project TimeGenerated, DeviceName, AccountName, ExfiltratingExecutable = tolower(FileName), ProcessId, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessId; // 3) Network events likely indicating FTP (port 21 or ftp:// URLs) let network_confirm = DeviceNetworkEvents | where RemotePort == 21 or tostring(RemoteUrl) has "ftp://" or tostring(RemoteUrl) has ":21" | project NetTime = TimeGenerated, NetDeviceName = DeviceName, NetInitiatingProcessId = InitiatingProcessId, NetInitiatingProcessFileName = InitiatingProcessFileName, RemoteIP = RemoteIP, RemotePort = RemotePort, RemoteUrl = RemoteUrl; // Combine detections and validate with network events. Since join with OR is not allowed, perform two joins and union results. (ps_direct | union child_procs) | as detections | join kind=leftouter (network_confirm) on $left.ProcessId == $right.NetInitiatingProcessId | project TimeGenerated, DeviceName, AccountName, ExfiltratingExecutable, ProcessId, ProcessCommandLine, InitiatingProcessFileName, NetInitiatingProcessFileName, RemoteIP, RemotePort, RemoteUrl, NetTime | union ( (ps_direct | union child_procs) | join kind=leftouter (network_confirm) on $left.InitiatingProcessId == $right.NetInitiatingProcessId | project TimeGenerated, DeviceName, AccountName, ExfiltratingExecutable, ProcessId, ProcessCommandLine, InitiatingProcessFileName, NetInitiatingProcessFileName, RemoteIP, RemotePort, RemoteUrl, NetTime ) | summarize Attempts = count(), ExampleCommands = make_set(ProcessCommandLine, 5), Initiators = make_set(InitiatingProcessFileName, 5), RemoteEndpoints = make_set(coalesce(tostring(RemoteUrl), strcat(RemoteIP, ":", tostring(RemotePort))), 10) by ExfiltratingExecutable | order by Attempts desc | take 50
Correct
4
81.69s
0.0198
gpt-5-mini-medium
rclone.exe
let ftp_ports = dynamic([21, 990, 2121, 8021]); // Candidate PowerShell process creations invoking FTP-related commands DeviceProcessEvents | where FileName =~ 'powershell.exe' or FileName =~ 'pwsh.exe' | where ProcessCommandLine has_any ('ftp','WebClient','FtpWebRequest','-Uri','-OutFile','Invoke-WebRequest','Start-BitsTransfer') | project TimeGenerated, DeviceName, ProcessId, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine | join kind=leftouter ( // Network events from same process or initiated by same process DeviceNetworkEvents | where RemotePort in (21, 990, 2121, 8021) or RemoteUrl has 'ftp' or RemoteUrl has 'ftps' | project NetworkTime=TimeGenerated, DeviceName, InitiatingProcessId, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemotePort, RemoteUrl ) on DeviceName | where isnotempty(ProcessId) and (ProcessId == InitiatingProcessId or InitiatingProcessFileName has 'powershell' or InitiatingProcessCommandLine has 'ftp') | summarize NetworkEvents = make_set(pack('NetworkTime',NetworkTime,'RemoteIP',RemoteIP,'RemotePort',RemotePort,'RemoteUrl',RemoteUrl), 50), min(TimeGenerated), max(TimeGenerated) by DeviceName, ProcessId, FileName, ProcessCommandLine | extend StartTime = todatetime(min_TimeGenerated), EndTime = todatetime(max_TimeGenerated) | project StartTime, EndTime, DeviceName, ExfiltratingExecutable = FileName, ProcessId, ProcessCommandLine, NetworkEvents | order by StartTime desc | take 50
Correct
1
15.12s
0.0046
gpt-5-nano-high
No answer provided
No query generated
Incorrect
5
0.00s
0.0115
gpt-5-nano-medium
No answer provided
No query generated
Incorrect
5
0.00s
0.0087
grok-3-beta
No answer provided
No query generated
Incorrect
5
0.00s
0.0923
grok-3-mini-beta
rclone.exe
DeviceProcessEvents | where InitiatingProcessFileName =~ 'powershell.exe' | where ProcessCommandLine has "ftp" or ProcessCommandLine has "21" | distinct FileName
Correct
2
26.93s
0.0029
o1-high
rclone.exe
DeviceProcessEvents | where ActionType == "ProcessCreated" | where InitiatingProcessFileName =~ "powershell.exe" | where ProcessCommandLine has_any ("ftp", "ftp://", "FtpWebRequest") | project TimeGenerated, DeviceName, FileName, FolderPath, ProcessCommandLine | order by TimeGenerated desc
Correct
1
25.88s
0.1952
o1-low
rclone.exe
DeviceProcessEvents | where ActionType == "ProcessCreated" | where InitiatingProcessFileName =~ "powershell.exe" | where ProcessCommandLine has "ftp" | project TimeGenerated, DeviceName, InitiatingProcessFileName, ProcessCommandLine, FileName, FolderPath | order by TimeGenerated desc
Correct
1
20.68s
0.1803
o3-high
rclone.exe
// ----------------------------------------------------------------------------- // What executable did PowerShell use to transfer data to an FTP service? // ----------------------------------------------------------------------------- // Query logic // 1. Look for processes that were spawned by PowerShell and whose command line // shows typical FTP keywords ( ftp / ftps / tftp ). // 2. Look for network connections to an FTP service (TCP/21 or ftp:// URL) // where the *connecting* process – or its parent – is PowerShell. // 3. Union both evidence sets and summarise so we can clearly see which // executable(s) were leveraged for the exfiltration, on which host and // when it was first & last observed. // // NOTE – The time-picker in the hunting portal controls the global time range. // If you want a fixed window instead, uncomment the first two lines // and adjust the value in the *ago()* operator. // ----------------------------------------------------------------------------- // let TimeWindow = 7d; // <- uncomment / change if needed // | where TimeGenerated >= ago(TimeWindow) // --------------------------------------- // 1. Process-creation evidence // --------------------------------------- let procEvidence = DeviceProcessEvents // | where TimeGenerated >= ago(TimeWindow) // (handled by portal) | where ActionType == "ProcessCreated" | where InitiatingProcessFileName =~ "powershell.exe" | where FileName != "powershell.exe" // exclude the parent itself | where ProcessCommandLine has_any ("ftp ", "ftp://", "ftps://", "tftp ") | project DeviceId, DeviceName, TimeGenerated, ExfilExecutable = FileName, ExfilCommand = ProcessCommandLine; // --------------------------------------- // 2. Network evidence (FTP traffic) // --------------------------------------- let netEvidence = DeviceNetworkEvents // | where TimeGenerated >= ago(TimeWindow) | where RemotePort == 21 or RemoteUrl startswith "ftp://" or RemoteUrl startswith_cs "ftp." | where InitiatingProcessParentFileName =~ "powershell.exe" // PowerShell launched it or InitiatingProcessFileName =~ "powershell.exe" // or is PowerShell itself | project DeviceId, DeviceName, TimeGenerated, ExfilExecutable = InitiatingProcessFileName, ExfilCommand = InitiatingProcessCommandLine; // --------------------------------------- // 3. Merge & answer // --------------------------------------- procEvidence | union netEvidence | summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), ExecCount = count() by DeviceName, ExfilExecutable, ExfilCommand | sort by ExecCount desc, FirstSeen asc | project Host = DeviceName, Executable = ExfilExecutable, ExampleCmdLine = ExfilCommand, Executions = ExecCount, FirstSeen, LastSeen
Correct
4
151.84s
0.0962
o3-mini-high
No answer provided
No query generated
Incorrect
5
0.00s
0.0515
o3-mini-low
rclone.exe
union withsource=TableName DeviceProcessEvents, DeviceEvents | extend ParentProc = tolower(InitiatingProcessFileName), ChildProc = tolower(FileName) | where ParentProc == "powershell.exe" | where (tostring(ProcessCommandLine) contains "ftp" or tostring(InitiatingProcessCommandLine) contains "ftp") | where ChildProc != "powershell.exe" | project TimeGenerated, DeviceName, ProcessId, FileName, InitiatingProcessFileName, ProcessCommandLine, InitiatingProcessCommandLine | sort by TimeGenerated asc
Correct
5
149.76s
0.0520
o4-mini-high
rclone.exe
DeviceProcessEvents | where InitiatingProcessFileName in ("powershell.exe", "pwsh.exe") | where ProcessCommandLine has "ftp" | project TimeGenerated, DeviceName, InitiatingProcessCommandLine, ExfiltrationProcess = FileName, ProcessCommandLine | summarize Count = count() by ExfiltrationProcess, ProcessCommandLine | order by Count desc
Correct
3
81.96s
0.0248
o4-mini-low
No answer provided
No query generated
Incorrect
5
0.00s
0.0413