// question

Using Linux process or syslog logs, identify the executable that was run to output the system's locale information.

Reference KQL answer and model-by-model comparison.

837d609b-845e-4519-90ce-edc3b4b0e138
question id
14/23
models correct
1
valid answer
61%
success rate
// reference answer

Human-validated correct answer for this question.

locale
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
locale
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where ProcessCommandLine has_any ("locale", "localectl", "env ") or ProcessCommandLine contains " grep locale"
| project Timestamp, DeviceName, FileName, ProcessCommandLine
pass19.74s0.0065
gpt-35-turbo
locale
DeviceProcessEvents | where ProcessCommandLine contains 'locale' | project ProcessId, FileName, ProcessCommandLine
pass11.86s0.0035
gpt-4-turbo-2024-04-09
locale
DeviceProcessEvents
| where ProcessCommandLine has 'locale'
| project DeviceName, FileName, ProcessCommandLine, TimeGenerated
pass19.72s0.0741
gpt-4.1
locale
DeviceProcessEvents
| where FileName in~ ('locale', 'localectl') or ProcessCommandLine has_any ('locale', 'localectl', '/etc/locale.conf')
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, FolderPath
| order by TimeGenerated desc
pass15.94s0.0172
gpt-4.1-finetuned
/usr/bin/locale, /usr/bin/localectl, /usr/bin/cat, /usr/bin/dash, /usr/bin/locale-check, /usr/sbin/runuser, /usr/bin/curl
DeviceProcessEvents
| where TimeGenerated > ago(30d)
| where ProcessCommandLine has_any ("locale", "localectl", "/etc/default/locale", "/etc/locale.conf", "/etc/sysconfig/i18n")
| summarize count() by FolderPath, ProcessCommandLine
| order by count_ desc
| extend MITRE_Technique = "T1033"
| extend MITRE_TechniqueName = "System Owner/User Discovery"
| extend MITRE_IDs_URL = "https://attack.mitre.org/techniques/T1033/"
| extend MITRE_Technique_URL = "https://attack.mitre.org/techniques/T1033/"
pass1580.68s0.0176
gpt-4.1-mini
locale
union DeviceProcessEvents, DeviceEvents
| where ProcessCommandLine has_any ("locale", "localectl", "echo $LANG") or ActionType has_any ("locale", "localectl", "echo $LANG")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, ActionType
| sort by TimeGenerated desc
pass13.46s0.0033
gpt-4.1-nano
dash
DeviceProcessEvents
| where ProcessCommandLine contains 'localectl' or ProcessCommandLine contains 'locale' or ProcessCommandLine contains 'echo $LANG' or ProcessCommandLine contains 'echo $LC_ALL'
| project InitiatingProcessFileName, ProcessCommandLine, TimeGenerated, DeviceName
fail46.36s0.0017
gpt-4o
dash
DeviceProcessEvents
| where InitiatingProcessCommandLine contains "locale"
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessCreationTime
fail117.60s0.0149
gpt-5-high
locale
let linuxDevices = DeviceInfo
| where OSPlatform =~ "Linux"
| project DeviceId, DeviceName;
let procLocale =
    DeviceProcessEvents
    | where ActionType == "ProcessCreated"
    | join kind=inner (linuxDevices) on DeviceId
    | extend Cmd = tostring(ProcessCommandLine)
    | where
        FileName in~ ("localectl", "locale")
        or Cmd matches regex @"\blocalectl\s+(?:status|show|list-locales)\b"
        or Cmd matches regex @"\blocale(\s+(-{1,2}\w+|\w+)*)?\b"
        or (FileName in~ ("printenv","env") and Cmd matches regex @"\b(?:LANG|LC_[A-Z_]+)\b")
        or (FileName in~ ("cat","grep","awk","sed") and Cmd matches regex @"\b(?:/etc/(?:locale\.conf|default/locale|environment)|(?:LANG|LC_[A-Z_]+))\b")
    | extend Executable = coalesce(extract(@"^(?:sudo\s+(?:-[^\s]+\s+)*)?(\S+)", 1, Cmd), FolderPath, FileName)
    | project TimeGenerated, DeviceName, AccountName, Executable, CommandLine=Cmd, SourceTable="DeviceProcessEvents";
let linuxHosts = linuxDevices | project DeviceName;
let syslogLocale =
    Syslog
    | where SyslogMessage has "COMMAND="
    | extend Cmd = extract(@"COMMAND=([^\r\n]+)", 1, SyslogMessage)
    | where isnotempty(Cmd)
    | where Cmd matches regex @"\b(localectl|locale)\b"
        or Cmd matches regex @"\b(?:printenv|env)\b.*\b(?:LANG|LC_[A-Z_]+)\b"
        or Cmd matches regex @"\b(?:cat|grep|awk|sed)\b.*\b(?:/etc/(?:locale\.conf|default/locale|environment)|(?:LANG|LC_[A-Z_]+))\b"
    | extend Executable = extract(@"^(?:sudo\s+(?:-[^\s]+\s+)*)?(\S+)", 1, Cmd)
    | extend DeviceName = coalesce(column_ifexists("HostName",""), column_ifexists("Computer",""))
    | where isnotempty(DeviceName)
    | join kind=inner (linuxHosts) on DeviceName
    | extend AccountName = extract(@"sudo:\s*([^:]+)\s*:", 1, SyslogMessage)
    | project TimeGenerated, DeviceName, AccountName, Executable, CommandLine=Cmd, SourceTable="Syslog";
union procLocale, syslogLocale
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Count=count() by DeviceName, AccountName, Executable, CommandLine, SourceTable
| order by LastSeen desc
pass4460.13s0.2293
gpt-5-mini-high
no answer
no query generatedfail50.00s0.0144
gpt-5-mini-low
locale
// Identify executables used to output system locale information on Linux
// Adjust the time range as needed (caller may override)
let TimeWindow = ago(30d);
let localeRegex = @"\b(locale|localectl|lang|locale\s+-a)\b|cat\s+/etc/(default/)?locale|grep\s+LANG|printenv\s+LANG|env\s*\|\s*grep\s+LANG";

// Search DeviceProcessEvents for process command lines
let proc = DeviceProcessEvents
| where TimeGenerated >= TimeWindow and isnotempty(ProcessCommandLine)
| extend cmd = tostring(ProcessCommandLine), exePath = coalesce(tolower(FileName), tostring(split(tolower(ProcessCommandLine), ' ')[0]))
| where cmd matches regex localeRegex
| project TimeGenerated, SourceTable = 'DeviceProcessEvents', DeviceName, AccountName, ProcessId, exePath, cmd, InitiatingProcessFileName, InitiatingProcessCommandLine;

// Search DeviceEvents
let dev = DeviceEvents
| where TimeGenerated >= TimeWindow
| extend cmd = coalesce(ProcessCommandLine, InitiatingProcessCommandLine, tostring(AdditionalFields)), exePath = coalesce(tolower(FileName), tostring(split(tolower(ProcessCommandLine), ' ')[0]))
| where isnotempty(cmd) and tostring(cmd) matches regex localeRegex
| project TimeGenerated, SourceTable = 'DeviceEvents', DeviceName, AccountName, ProcessId = tostring(ProcessId), exePath, cmd;

// Search DeviceFileEvents
let file = DeviceFileEvents
| where TimeGenerated >= TimeWindow
| extend cmd = coalesce(InitiatingProcessCommandLine, FileName, tostring(AdditionalFields)), exePath = coalesce(tolower(FileName), tostring(split(tolower(InitiatingProcessCommandLine), ' ')[0]))
| where isnotempty(cmd) and tostring(cmd) matches regex localeRegex
| project TimeGenerated, SourceTable = 'DeviceFileEvents', DeviceName, AccountName = InitiatingProcessAccountName, ProcessId = tostring(InitiatingProcessId), exePath, cmd;

// Combine and normalize executable name
union isfuzzy=true proc, dev, file
| extend exe = replace(".*/", "", tostring(exePath))
| summarize Count = count(), Devices = dcount(DeviceName), Latest = max(TimeGenerated), Samples = make_set(cmd, 10) by exe
| where exe != ''
| order by Latest desc, Count desc
| top 100 by Latest
pass442.03s0.0107
gpt-5-mini-medium
locale
// Identify executables that were run to output system locale information on Linux
// Adjust time range using 'where Timestamp between (start .. end)'

let locale_terms = dynamic([" locale ", "localectl", "/etc/locale.conf", "LANG=", "grep LANG", "/etc/default/locale", "update-locale", "/etc/locale.gen"]);

// Search process events (Linux) for locale-related commands
let procs = DeviceProcessEvents
| where isnotempty(ProcessCommandLine) or isnotempty(FileName)
// Optional: filter by OSPlatform if available (some tenants populate OSPlatform in DeviceInfo)
// | where tostring(OSPlatform) has "Linux"
| where (
    ProcessCommandLine has "locale"
    or ProcessCommandLine has "localectl"
    or ProcessCommandLine has "/etc/locale.conf"
    or ProcessCommandLine contains "LANG="
    or ProcessCommandLine has "grep LANG"
    or ProcessCommandLine has "cat /etc/default/locale"
    or ProcessCommandLine has "update-locale"
    or ProcessCommandLine has "/etc/locale.gen"
)
| extend Executable = coalesce(FileName, tostring(split(ProcessCommandLine," ")[0]), InitiatingProcessFileName, InitiatingProcessCommandLine)
| project Timestamp, DeviceName, AccountName, ProcessId, ParentProcessId=InitiatingProcessParentId, Executable, ProcessCommandLine, InitiatingProcessCommandLine, InitiatingProcessFileName, FileName, SourceTable = "DeviceProcessEvents";

// Search DeviceEvents (may include syslog/shell output) for references to locale files/variables
let events = DeviceEvents
| where isnotempty(AdditionalFields) or isnotempty(ProcessCommandLine) or isnotempty(FileName)
| where (
    tostring(AdditionalFields) contains "locale"
    or tostring(AdditionalFields) contains "LANG"
    or ProcessCommandLine has "locale"
    or ProcessCommandLine has "localectl"
    or FileName has "/etc/locale.conf"
    or ProcessCommandLine has "cat /etc/default/locale"
    or ProcessCommandLine has "grep LANG"
)
| extend Executable = coalesce(FileName, tostring(split(ProcessCommandLine," ")[0]), InitiatingProcessFileName, InitiatingProcessCommandLine)
| project Timestamp, DeviceName, AccountName, ProcessId=InitiatingProcessId, ParentProcessId=InitiatingProcessParentId, Executable, ProcessCommandLine, InitiatingProcessCommandLine, InitiatingProcessFileName, FileName, SourceTable = "DeviceEvents";

// Combine and present results; caller should apply a time filter externally via the function time range
procs
| union events
| sort by Timestamp desc
| summarize count_ct = count(), any_Timestamp = any(Timestamp), any_Device = any(DeviceName), any_Account = any(AccountName), Executables = make_set(Executable, 25), Cmdlines = make_set(ProcessCommandLine, 25) by bin(Timestamp, 1h)
| order by any_Timestamp desc
| limit 200
pass224.23s0.0076
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0079
gpt-5-nano-medium
no answer
no query generatedfail50.00s0.0069
grok-3-beta
no answer
no query generatedfail50.00s0.0873
grok-3-mini-beta
locale
DeviceProcessEvents
| where ProcessCommandLine contains "locale"
| project FileName, ProcessCommandLine, Timestamp
| order by Timestamp desc
pass111.65s0.0023
o1-high
locale
DeviceInfo
| where OSPlatform == "Linux"
| project DeviceId
| join kind=inner (
    DeviceProcessEvents
    | where ActionType == "ProcessCreated"
    | where (FileName in~ ("locale", "localectl", "cat") or (FileName == "env" and ProcessCommandLine has "LANG="))
    | where ProcessCommandLine has_any ("locale", "localectl", "LANG=", "/etc/locale.conf")
    | project TimeGenerated, DeviceId, DeviceName, InitiatingProcessAccountName, FileName, ProcessCommandLine, FolderPath
) on DeviceId
pass239.86s0.3361
o1-low
locale
DeviceInfo
| where OSPlatform == "Linux"
| distinct DeviceId
| join kind=inner (
    DeviceProcessEvents
    | where FileName in~ ("locale", "localectl") or ProcessCommandLine has_any ("locale", "localectl")
) on DeviceId
| project TimeGenerated, DeviceName, AccountName, FileName, FolderPath, ProcessCommandLine, InitiatingProcessCommandLine
pass244.33s0.4338
o3-high
locale
// Step 1 – Identify Linux devices
let linuxDevices = DeviceInfo
    | where OSPlatform =~ "Linux"
    | project DeviceId, DeviceName;

// Step 2 – Find processes that output locale information
linuxDevices
| join kind=inner (
    DeviceProcessEvents
    | where FileName in~ ("locale", "localectl")
        or ProcessCommandLine has_cs " locale"    // avoid matching “localepurge” etc.
    | project DeviceId,
              TimeGenerated,
              FileName,
              FolderPath,
              ProcessCommandLine,
              InitiatingProcessFileName,
              InitiatingProcessCommandLine
) on DeviceId
| project TimeGenerated,
          DeviceName,
          Executable = strcat(FolderPath, "/", FileName),
          CommandLine = ProcessCommandLine,
          ParentProcess = InitiatingProcessFileName,
          ParentCommandLine = InitiatingProcessCommandLine
| order by TimeGenerated desc
pass147.45s0.0461
o3-mini-high
locale
DeviceProcessEvents
| where ProcessCommandLine contains "locale"
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine
| top 100 by TimeGenerated desc
pass122.75s0.0152
o3-mini-low
dash
DeviceProcessEvents
| where InitiatingProcessCommandLine contains "locale"
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, ProcessCreationTime
| sort by ProcessCreationTime desc
fail112.23s0.0125
o4-mini-high
no answer
no query generatedfail50.00s0.0483
o4-mini-low
no answer
no query generatedfail50.00s0.0505