Question Analysis
On a Linux host, process execution logs show a chmod invocation with a recursive flag. Which file or folder was targeted by this recursive permission change?
ea79f937-4a4d-4348-ace6-9916aec453a4
Question ID
18/23
Models Correct
1
Valid Answer
78%
Success Rate
Reference Answer
Human-validated correct answer for this question
T1222.002
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 | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where FileName == "chmod"
| where ProcessCommandLine has "-R" or ProcessCommandLine has "-r"
// Extract the target path assuming it's the first sequence of non-space characters after the recursive flag and a space.
// This regex (?:-R|-r)\s+(\S+) matches:
// (?:-R|-r) - a non-capturing group for either "-R" or "-r"
// \s+ - one or more whitespace characters
// (\S+) - one or more non-whitespace characters (this is captured in group 1)
| extend TargetedPath = extract(@"(?:-R|-r)\s+(\S+)", 1, ProcessCommandLine)
| where isnotempty(TargetedPath) // Filter out events where extraction failed or didn't find a target
| project Timestamp, DeviceName, InitiatingProcessCommandLine, ProcessCommandLine, TargetedPath, AccountName, AccountDomain | Correct | 1 | 25.72s | 0.0131 |
gpt-35-turbo | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0110 |
gpt-4-turbo-2024-04-09 | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where InitiatingProcessCommandLine contains 'chmod' and InitiatingProcessCommandLine contains '-R'
| project Timestamp, DeviceName, InitiatingProcessCommandLine, FolderPath | Correct | 1 | 12.89s | 0.1258 |
gpt-4.1 | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where FileName == "chmod" or ProcessCommandLine has "chmod"
| where ProcessCommandLine has "-R" or ProcessCommandLine has "--recursive"
| extend TargetPath = extract("chmod .*-R(?:[ =]?|[[:space:]]+| --recursive[ =]?)([^ ]+)", 1, ProcessCommandLine)
| project TimeGenerated, DeviceName, AccountName, AccountDomain, ProcessCommandLine, TargetPath
| order by TimeGenerated desc | Correct | 1 | 6.75s | 0.0144 |
gpt-4.1-finetuned | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0514 |
gpt-4.1-mini | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where FileName == "chmod" and (ProcessCommandLine has "-R" or ProcessCommandLine has "--recursive")
| project TimeGenerated, DeviceName, InitiatingProcessAccountName, TargetPath = strcat(FolderPath, "/", FileName), ProcessCommandLine
| order by TimeGenerated desc | Correct | 2 | 22.23s | 0.0041 |
gpt-4.1-nano | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where ActionType == 'ProcessCreated' and FileName endswith 'chmod'
| where ProcessCommandLine contains '-R' or ProcessCommandLine contains '--recursive'
| extend TargetPath = extract(@'chmod\s+[\S]+\s+(\S+)', 1, ProcessCommandLine)
| project TimeGenerated, DeviceName, InitiatingProcessFileName, ProcessCommandLine, TargetPath
| where isnotempty(TargetPath)
| take 10 | Correct | 2 | 5.71s | 0.0007 |
gpt-4o | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where InitiatingProcessCommandLine contains "chmod" and InitiatingProcessCommandLine contains "-R"
| extend TargetFileOrFolder = extract(@"chmod\s.*\-R\s(\S+)", 1, InitiatingProcessCommandLine)
| project TimeGenerated, DeviceName, TargetFileOrFolder, InitiatingProcessCommandLine | Correct | 3 | 30.53s | 0.0551 |
gpt-5-high | /tmp/AtomicRedTeam/atomics/T1222.002 | let LinuxDevices = DeviceInfo
| where OSPlatform == "Linux"
| project DeviceId, DeviceName;
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where FileName =~ "chmod"
| where ProcessCommandLine has_any ("-R", "--recursive")
| join kind=inner (LinuxDevices) on DeviceId
// Get everything after the recursive flag
| extend afterR = coalesce(
extract(@"--recursive(?:\s+|=)(.*)$", 1, ProcessCommandLine),
extract(@"-R\s+(.*)$", 1, ProcessCommandLine)
)
| where isnotempty(afterR)
// From the substring, remove further options and the mode, leaving the targets
| extend targets_str = extract(@"^(?:\s*-[^\s]+\s+)*\s*(?:--\s+)?(?:[0-7]{3,4}|[ugoa]*[-+=][rwxXstugo]+(?:,[ugoa]*[-+=][rwxXstugo]+)*)\s+(.*)$", 1, tostring(afterR))
| extend targets_str = iff(isempty(targets_str), tostring(afterR), targets_str)
// Best-effort split to list individual targets (quoted paths with spaces may split)
| extend Targets = split(trim(" ", tostring(targets_str)), " ")
| extend FirstTarget = tostring(Targets[0])
| project TimeGenerated, DeviceName, DeviceId, AccountName, ProcessId, FirstTarget, Targets, TargetsText=tostring(targets_str), ProcessCommandLine
| where isnotempty(FirstTarget)
| order by TimeGenerated desc | Correct | 2 | 238.51s | 0.1162 |
gpt-5-mini-high | /tmp/AtomicRedTeam/atomics/T1222.002 | union DeviceProcessEvents, DeviceEvents, DeviceFileEvents
| extend cmd = tostring(coalesce(ProcessCommandLine, InitiatingProcessCommandLine, tostring(AdditionalFields["CommandLine"])))
| where isnotempty(cmd)
// ensure this is a chmod invocation
| where tolower(cmd) contains "chmod"
// ensure a recursive flag is present (-r or -R or --recursive)
| where tolower(cmd) matches regex @"\bchmod\b.*(?:\s-[^\s]*r[^\s]*\b|--recursive\b)"
// split the command into tokens and normalize
| extend tokens = split(cmd, ' ')
| mv-expand token = tokens to typeof(string)
| extend token = trim('\'"`', tostring(token))
// keep tokens that look like paths and exclude flags/options
| where token != '' and not(token startswith('-'))
and (token startswith('/') or token startswith('./') or token startswith('~/') or token contains('/'))
// summarize candidate targets per device/process/command
| summarize Targets = make_set(token), TargetCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by DeviceName, ProcessId, InitiatingProcessFileName, InitiatingProcessAccountName, cmd
| project FirstSeen, LastSeen, DeviceName, ProcessId, InitiatingProcessFileName, InitiatingProcessAccountName, cmd, Targets, TargetCount
| order by LastSeen desc
| take 250 | Correct | 3 | 64.49s | 0.0155 |
gpt-5-mini-low | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0147 |
gpt-5-mini-medium | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0211 |
gpt-5-nano-high | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where InitiatingProcessCommandLine contains "chmod" and (InitiatingProcessCommandLine contains "-R" or InitiatingProcessCommandLine contains "--recursive")
| extend TargetPath = coalesce(
extract(@"chmod\\s+-R\\s+(?:\\d+\\s+)?([^\\s]+)", 1, InitiatingProcessCommandLine),
extract(@"chmod\\s+-R\\s+([^\\s]+)", 1, InitiatingProcessCommandLine),
FolderPath,
FileName
)
| where isnotempty(TargetPath)
| distinct TargetPath, InitiatingProcessCreationTime, InitiatingProcessId, InitiatingProcessCommandLine, FolderPath, FileName, TimeGenerated
| project InitiatingProcessCreationTime, InitiatingProcessId, InitiatingProcessCommandLine, TargetPath, FolderPath, FileName, TimeGenerated | Correct | 1 | 41.97s | 0.0030 |
gpt-5-nano-medium | No answer provided | No query generated | Incorrect | 5 | 0.00s | 0.0088 |
grok-3-beta | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where ProcessCommandLine has 'chmod' and (ProcessCommandLine has '-R' or ProcessCommandLine has '--recursive')
| join kind=inner DeviceInfo on DeviceId
| where OSPlatform contains 'Linux'
| extend TargetPath = extract('chmod[^>]*[ ]+[^ ]*[ ]+([^ ]+)', 1, ProcessCommandLine)
| project Timestamp, DeviceName, AccountName, ProcessCommandLine, TargetPath
| order by Timestamp desc | Correct | 1 | 10.84s | 0.0435 |
grok-3-mini-beta | /tmp/AtomicRedTeam/atomics/T1222.002 | let LinuxDevices = DeviceInfo
| where OSPlatform == "Linux"
| distinct DeviceId;
DeviceProcessEvents
| where DeviceId in (LinuxDevices)
| where ProcessCommandLine contains "chmod" and ProcessCommandLine contains "-R"
| extend TargetPath = extract(@"chmod\s+-R\s+\\S+\\s+([^\\s]+)", 1, ProcessCommandLine) // Extracts the path after chmod -R and its arguments
| project Timestamp, DeviceName, ProcessCommandLine, TargetPath
| order by Timestamp desc
| limit 100 // Limits results for performance; adjust as needed | Correct | 1 | 21.76s | 0.0031 |
o1-high | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where DeviceId in (DeviceInfo
| where OSPlatform == "Linux"
| distinct DeviceId)
| where FileName == "chmod"
| where ProcessCommandLine contains "-R" or ProcessCommandLine contains "--recursive"
// Attempt to capture the last command line argument as the target path:
| extend TargetPath = extract(@"(/\S+)$", 1, ProcessCommandLine)
| project TimeGenerated, DeviceName, AccountName, FolderPath, ProcessCommandLine, TargetPath
| order by TimeGenerated desc | Correct | 1 | 40.60s | 0.2810 |
o1-low | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceInfo
| where OSPlatform == "Linux"
| distinct DeviceId
| join (
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where FileName =~ "chmod"
| where ProcessCommandLine has_any ("-R", "--recursive")
) on DeviceId
| project TimeGenerated, DeviceName, FolderPath, ProcessCommandLine | Correct | 1 | 38.95s | 0.2636 |
o3-high | /tmp/AtomicRedTeam/atomics/T1222.002 | // List of Linux devices
let linux_devices = DeviceInfo
| where OSPlatform startswith "Linux"
| project DeviceId;
// Look for chmod commands that used the recursive flag and extract the target path
DeviceProcessEvents
| where DeviceId in (linux_devices)
| where FileName == "chmod"
| where ProcessCommandLine matches regex @"\s-[rR]\b" // ensure -R / -r was present
| extend SplitCmd = split(ProcessCommandLine, " ")
| extend TargetPathRaw = tostring(SplitCmd[-1]) // last argument should be target file/folder
| extend TargetPath = trim("\"' ", TargetPathRaw) // remove surrounding quotes or spaces
| project TimeGenerated,
DeviceName,
InitiatingProcessAccountName,
ProcessCommandLine,
TargetPath
| order by TimeGenerated desc | Correct | 3 | 94.40s | 0.0488 |
o3-mini-high | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where ProcessCommandLine contains "chmod" and ProcessCommandLine contains "-R"
| extend Target = extract(@"-R\s+(?:[0-7]{3}\s+)?([^\s]+)", 1, ProcessCommandLine)
| project TimeGenerated, DeviceName, ProcessCommandLine, Target | Correct | 2 | 71.99s | 0.0233 |
o3-mini-low | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where ProcessCommandLine has "chmod" and ProcessCommandLine has "-R"
| extend Target = extract(@"chmod\s+-R\s+(?:[0-7]{3,4}\s+)?(\S+)", 1, ProcessCommandLine)
| project TimeGenerated, DeviceName, ProcessCommandLine, Target
| order by TimeGenerated desc | Correct | 1 | 35.76s | 0.0136 |
o4-mini-high | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where ProcessCommandLine contains "chmod"
| where ProcessCommandLine matches regex @"chmod\s+(?:-[^\s]*\s+)*-R"
| extend TargetPath = extract(@"chmod\s+(?:-[^\s]*\s+)*-R\s+([^\s]+)", 1, ProcessCommandLine)
| join kind=inner (
DeviceInfo
| where OSPlatform == "Linux"
| project DeviceId
) on DeviceId
| project TimeGenerated, DeviceName, InitiatingProcessAccountName, ProcessCommandLine, TargetPath | Correct | 1 | 39.50s | 0.0132 |
o4-mini-low | /tmp/AtomicRedTeam/atomics/T1222.002 | DeviceProcessEvents
| where FileName == "chmod"
| where ProcessCommandLine has "-R"
| extend args = split(ProcessCommandLine, " ")
| extend target = args[array_length(args) - 1]
| project TimeGenerated, DeviceName, InitiatingProcessAccountName, ProcessCommandLine, target | Correct | 1 | 29.59s | 0.0108 |