Question Analysis
On a Linux system, review process execution records for any shell process that set an environment variable containing executable code and then piped it into another shell instance. Determine which environment variable name was used to store the script content.
bdaebd56-368b-4970-a523-f905ff4a8a51
Question ID
5/23
Models Correct
1
Valid Answer
22%
Success Rate
Reference Answer
Human-validated correct answer for this question
ART
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 | ART | DeviceProcessEvents
| where ActionType == "ProcessCreated"
| join kind=inner DeviceInfo on DeviceId
| where OSPlatform == "Linux"
| where ProcessCommandLine contains "=" and ProcessCommandLine contains "|"
| extend parts = split(ProcessCommandLine, '|')
| extend commandBeforeFirstPipe = tostring(parts[0])
| extend commandAfterFirstPipe = tostring(parts[1])
| where commandAfterFirstPipe matches regex @"^\s*(?:/bin/)?(?:bash|sh|zsh|ksh|csh)" // Ensure the command after the pipe starts with a shell
| extend potentialVariableMatches = extract_all(@'([a-zA-Z_][a-zA-Z0-9_]*)=' , commandBeforeFirstPipe)
| where array_length(potentialVariableMatches) > 0
| mv-expand potentialVariableMatches // Each element of potentialVariableMatches is an array like ["VariableName"]
| project Timestamp, DeviceName, AccountName, InitiatingProcessCommandLine, ProcessCommandLine, AssignedVariable = tostring(potentialVariableMatches[0]) // Access the first element of the inner array | Correct | 5 | 87.70s | 0.0474 |
gpt-35-turbo | PortNumber | DeviceProcessEvents
| where ProcessCommandLine has 'set' and ProcessCommandLine has '|'
| extend ExtractedCommand = extract(@'(?i)set (?<VariableName>[^= ]*)=.*\|', 1, ProcessCommandLine)
| project ProcessId, ProcessCommandLine, ExtractedCommand | Incorrect | 4 | 11.44s | 0.0095 |
gpt-4-turbo-2024-04-09 | ENCODED | DeviceProcessEvents
| where FileName in ('bash', 'sh', 'zsh', 'csh', 'ksh', 'dash', 'tcsh')
| where ProcessCommandLine contains '=' and ProcessCommandLine contains '|'
| extend EnvVar = extract_all('(\\w+)=', ProcessCommandLine)
| mv-expand EnvVar to typeof(string)
| summarize Count = count() by tostring(EnvVar)
| order by Count desc | Correct | 4 | 35.85s | 0.2072 |
gpt-4.1 | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0461 |
gpt-4.1-finetuned | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0633 |
gpt-4.1-mini | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0122 |
gpt-4.1-nano | ART | DeviceProcessEvents
| where FileName in ('bash', 'sh') or InitiatingProcessCommandLine contains 'bash' or InitiatingProcessCommandLine contains 'sh'
| where InitiatingProcessCommandLine contains 'export ' or InitiatingProcessCommandLine contains 'environment='
| extend envVarNames = extract_all(@'\$(\w+)', InitiatingProcessCommandLine)
| mv-expand envVarNames
| where InitiatingProcessCommandLine contains '|' and (InitiatingProcessCommandLine contains 'bash' or InitiatingProcessCommandLine contains 'sh')
| project timestamp=InitiatingProcessCreationTime, ProcessId, FileName, InitiatingProcessCommandLine, envVarNames
| summarize count() by tostring(envVarNames), bin(timestamp, 1h) | Correct | 3 | 7.25s | 0.0014 |
gpt-4o | ART | let shell_processes = DeviceProcessEvents | where InitiatingProcessFileName in~ ("sh", "bash", "dash", "zsh", "ksh") or FileName in~ ("sh", "bash", "dash", "zsh", "ksh");
shell_processes
| where InitiatingProcessCommandLine contains "export" and InitiatingProcessCommandLine contains "|"
| extend EnvVariableName = extract(@"export\s+(\w+)=", 1, InitiatingProcessCommandLine)
| project TimeGenerated, DeviceName, InitiatingProcessFileName, EnvVariableName, ProcessCommandLine, InitiatingProcessCommandLine | Correct | 2 | 32.07s | 0.0263 |
gpt-5-high | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.2706 |
gpt-5-mini-high | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0184 |
gpt-5-mini-low | ART | let shellRegex = @"(?i)(?:^|/)(sh|bash|dash|zsh)$";
let ignore_vars = dynamic(["PATH","HOME","USER","SHELL","PWD","OLDPWD","PS1","PS2","LS_COLORS","LANG","TERM"]);
let source = DeviceProcessEvents;
let envSet = source
| where FileName matches regex shellRegex
| extend cmd = tostring(ProcessCommandLine)
// only consider commands that include an assignment and show script-like indicators or are long
| where cmd contains "=" and (
cmd contains "#!" or
cmd contains "function " or
cmd contains "base64" or
cmd contains "eval " or
cmd contains "curl " or
cmd contains "wget " or
cmd contains "python" or
cmd contains "perl" or
cmd contains "<<" or
cmd contains "EOF" or
strlen(cmd) > 120
)
// extract candidate variable names from assignments
| extend varCandidates = extract_all(@"([A-Za-z_][A-Za-z0-9_]*)=", cmd)
| mv-expand varCandidates to typeof(string)
| extend varname = tostring(varCandidates)
| where isnotempty(varname) and array_index_of(ignore_vars, varname) == -1
| project EnvTime = Timestamp, DeviceId, DeviceName, AccountName, SetterProcessId = ProcessId, SetterCmd = cmd, varname;
let consumers = source
| where FileName matches regex shellRegex
| extend consumer_cmd = tostring(ProcessCommandLine)
| project ConsumerTime = Timestamp, DeviceId, DeviceName, ConsumerProcessId = ProcessId, consumer_cmd;
envSet
| join kind=inner (consumers) on DeviceId
| where ConsumerTime between (EnvTime - 1m .. EnvTime + 5m)
| where (
consumer_cmd contains strcat("$", varname)
or consumer_cmd contains strcat("${", varname, "}")
or consumer_cmd contains strcat("echo $", varname)
or consumer_cmd contains strcat("printf $", varname)
or consumer_cmd contains strcat("eval $", varname)
or consumer_cmd contains strcat("-c $", varname)
or consumer_cmd contains "| sh"
or consumer_cmd contains "| bash"
or consumer_cmd contains "| /bin/sh"
or consumer_cmd contains "| /bin/bash"
)
| summarize Count = count(), ExampleSetters = make_set(SetterCmd, 5), ExampleConsumers = make_set(consumer_cmd, 5), EnvTimes = make_set(EnvTime, 5), ConsumerTimes = make_set(ConsumerTime, 5) by DeviceId, DeviceName, AccountName, varname
| where Count > 0
| order by Count desc
| project DeviceId, DeviceName, AccountName, varname, Count, ExampleSetters, ExampleConsumers, EnvTimes, ConsumerTimes | Correct | 5 | 208.31s | 0.0604 |
gpt-5-mini-medium | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0196 |
gpt-5-nano-high | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0085 |
gpt-5-nano-medium | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0098 |
grok-3-beta | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.1359 |
grok-3-mini-beta | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0078 |
o1-high | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.8144 |
o1-low | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.8969 |
o3-high | ENCODED | // Detect shell processes on Linux that build script content inside an environment variable and
// immediately pipe (|) that variable into another shell instance.
// The query extracts and reports the environment-variable name that held the script text.
// Time range is supplied automatically by the hunting query runner.
let shell_regex = @"(?:^|\/)bash$|(?:^|\/)sh$|(?:^|\/)dash$|(?:^|\/)zsh$|(?:^|\/)ksh$"; // common shell executables
DeviceProcessEvents
// ---- Scope to Linux endpoints ----
| lookup kind=leftouter (
DeviceInfo
| project DeviceId, OSPlatform
) on DeviceId
| where OSPlatform =~ "Linux"
// ----------------------------------
// Interested only in shell processes whose command line both
// 1) defines an env-var ( VAR=... or export VAR=... ) AND
// 2) pipes that variable into a *second* shell instance ( | bash , | sh , etc. )
| where FileName matches regex shell_regex
| where ProcessCommandLine has "|" and (
ProcessCommandLine matches regex @"export\s+\w+\s*=.*\|.*(bash|sh|dash|zsh|ksh)" or
ProcessCommandLine matches regex @"\b\w+\s*=.*\|.*(bash|sh|dash|zsh|ksh)"
)
// Pull out the name of the environment variable that stored the script
| extend EnvVar = coalesce(
extract(@"export\s+(\w+)\s*=", 1, ProcessCommandLine),
extract(@"\b(\w+)\s*=.*\|", 1, ProcessCommandLine)
)
// Quick sanity filter – ignore very short names like "sh"
| where isnotempty(EnvVar) and strlen(EnvVar) > 1
// Return the interesting details
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, EnvVar, InitiatingProcessCommandLine
// Highlight which variable names are most frequently used
| summarize Events = count() by EnvVar, DeviceName
| order by Events desc, EnvVar | Incorrect | 1 | 49.05s | 0.0277 |
o3-mini-high | env_var | DeviceProcessEvents
| where ProcessCommandLine has "export" and ProcessCommandLine has "|"
| where FileName has_any ("bash", "sh", "zsh", "ksh")
| extend env_var = extract(@"export\s+([A-Za-z_][A-Za-z0-9_]*)=", 1, ProcessCommandLine)
| where isnotempty(env_var)
| summarize count() by env_var, ProcessCommandLine
| project env_var | Incorrect | 1 | 15.11s | 0.0110 |
o3-mini-low | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0602 |
o4-mini-high | EnvVariable | DeviceProcessEvents
| where FileName in ("bash", "sh", "zsh", "dash")
| where ProcessCommandLine matches regex @"(?<varName>[A-Za-z_][A-Za-z0-9_]*)=.*\|\s*(bash|sh|zsh|dash)"
| extend EnvVariable = extract(@"([A-Za-z_][A-Za-z0-9_]*)=", 1, ProcessCommandLine)
| project TimeGenerated, DeviceName, ProcessId, FileName, EnvVariable, ProcessCommandLine
| distinct EnvVariable | Incorrect | 1 | 29.70s | 0.0112 |
o4-mini-low | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0359 |