// question

A Linux host briefly hosted an HTTP service under /tmp. Examine process creation logs to determine the exact python3 command that was used to start the server on port 9090.

Reference KQL answer and model-by-model comparison.

3ea1f938-f80a-4305-9aa8-431bc4867313
question id
13/23
models correct
1
valid answer
57%
success rate
// reference answer

Human-validated correct answer for this question.

python3 -m http.server 9090
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
no answer
no query generatedfail50.00s0.0238
gpt-35-turbo
no answer
no query generatedfail50.00s0.0110
gpt-4-turbo-2024-04-09
no answer
no query generatedfail50.00s0.2219
gpt-4.1
no answer
no query generatedfail50.00s0.0470
gpt-4.1-finetuned
no answer
no query generatedfail50.00s0.0334
gpt-4.1-mini
python3 -m http.server 9090
DeviceProcessEvents
| where ProcessCommandLine contains "python3"
    and ProcessCommandLine contains "/tmp"
    and ProcessCommandLine contains "9090"
| project TimeGenerated, DeviceName, ProcessId, ProcessCommandLine
| sort by TimeGenerated desc
pass14.03s0.0024
gpt-4.1-nano
python3 -m http.server 9090
DeviceProcessEvents
| where ProcessCommandLine contains "python3"
| where ProcessCommandLine contains "9090"
| project ProcessCommandLine, InitiatingProcessCreationTime, DeviceName, ProcessId
pass12.04s0.0006
gpt-4o
python3 -m http.server 9090
DeviceProcessEvents
| where InitiatingProcessCommandLine has "python3" and InitiatingProcessCommandLine has "-m http.server" and InitiatingProcessCommandLine has "9090" and InitiatingProcessCommandLine has "/tmp"
| project TimeGenerated, DeviceName, InitiatingProcessCommandLine
pass13.60s0.0164
gpt-5-high
python3 -m http.server 9090
let targetPort = 9090;
let portRegex = strcat(@"(^|[^\d])", tostring(targetPort), @"([^\d]|$)");
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| join kind=innerunique (
    DeviceInfo
    | where OSPlatform == "Linux"
    | project DeviceId, DeviceName
) on DeviceId
| extend cmdl = tostring(ProcessCommandLine)
| where isnotempty(cmdl)
// python3 starting http.server on the target port
| where tolower(cmdl) has "http.server" and cmdl matches regex portRegex
| where tolower(FileName) matches regex @"^python3(\.\d+)?$" or tolower(cmdl) has "python3"
// get working directory from various possible keys in AdditionalFields
| extend WorkingDirectory = coalesce(
    tostring(AdditionalFields["cwd"]),
    tostring(AdditionalFields["Cwd"]),
    tostring(AdditionalFields["WorkingDirectory"]),
    tostring(AdditionalFields["workdir"]),
    tostring(AdditionalFields["CurrentDirectory"]))
// hosted under /tmp: either CWD is /tmp or command references /tmp (e.g., --directory /tmp)
| where tolower(cmdl) has "/tmp" or (isnotempty(WorkingDirectory) and tolower(WorkingDirectory) has "/tmp")
| project TimeGenerated, DeviceName, AccountName, FileName, FolderPath, ProcessId, ProcessCommandLine=cmdl, WorkingDirectory
| order by TimeGenerated asc
pass3212.20s0.1324
gpt-5-mini-high
no answer
no query generatedfail50.00s0.0206
gpt-5-mini-low
python3 -m http.server 9090
// Search DeviceProcessEvents and DeviceEvents for python3 starting an http server on port 9090 under /tmp
let lookback = 30d;
let pythonPatterns = dynamic(["python3","python","/usr/bin/python3","/usr/bin/python"]);
let httpModuleRegex = @"(?i)\b-m\s+http\.server\b|\bSimpleHTTPServer\b|\bhttp\.server\b|python\s+-m\s+http";

// Helper to normalize fields from both tables
let procs = (
    DeviceProcessEvents
    | where TimeGenerated >= ago(lookback)
    | where isnotempty(ProcessCommandLine) or isnotempty(FileName)
    | extend Cmd = coalesce(ProcessCommandLine, strcat(FileName, " ", tostring(ProcessId)))
    | extend SourceTable = "DeviceProcessEvents", ProcTime = ProcessCreationTime
    | project TimeGenerated, ProcTime, DeviceName, DeviceId, ProcessId, FileName, Cmd, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessAccountDomain, SourceTable
);

let events = (
    DeviceEvents
    | where TimeGenerated >= ago(lookback)
    | where ActionType == "ProcessCreated" or ActionType == "CreateProcess"
    | where isnotempty(ProcessCommandLine) or isnotempty(FileName)
    | extend Cmd = coalesce(ProcessCommandLine, strcat(FileName, " ", tostring(ProcessId)))
    | extend SourceTable = "DeviceEvents", ProcTime = ProcessCreationTime
    | project TimeGenerated, ProcTime, DeviceName, DeviceId, ProcessId, FileName, Cmd, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessAccountDomain, SourceTable
);

procs
| union events
| where tolower(Cmd) contains "python" // ensure python invocations
| where (Cmd matches regex httpModuleRegex) or Cmd contains "9090" or Cmd contains ":9090" or Cmd contains "port 9090" or Cmd contains "--bind" and Cmd contains "9090"
| where Cmd contains "/tmp" or Cmd contains "tmp/" or InitiatingProcessCommandLine contains "/tmp" or InitiatingProcessCommandLine contains "tmp/"
| extend MatchedHttp = extract(@"(-m\s+http\.server\b.*?|http\.server.*?|SimpleHTTPServer.*?|\b\d{2,5}\b)", 1, Cmd)
| extend FullCommand = trim('"', Cmd)
| project ProcTime = coalesce(ProcTime, TimeGenerated), TimeGenerated, DeviceName, DeviceId, ProcessId, FileName, FullCommand, MatchedHttp, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessAccountDomain, SourceTable
| order by ProcTime desc
| take 50
pass115.16s0.0041
gpt-5-mini-medium
no answer
no query generatedfail50.00s0.0238
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0091
gpt-5-nano-medium
no answer
no query generatedfail50.00s0.0095
grok-3-beta
no answer
no query generatedfail50.00s0.0931
grok-3-mini-beta
python3 -m http.server 9090
DeviceProcessEvents
| where ProcessCommandLine contains "python3" and ProcessCommandLine contains "9090"
| project TimeGenerated, DeviceName, ProcessCommandLine
| order by TimeGenerated desc
| take 10
pass111.03s0.0017
o1-high
python3 -m http.server 9090
DeviceInfo
| where OSPlatform == "Linux"
| distinct DeviceId
| join kind=inner (
    DeviceProcessEvents
    | where ProcessCommandLine has "python3"
    | where ProcessCommandLine has "9090"
    | where ProcessCommandLine has "/tmp"
) on DeviceId
| project TimeGenerated, DeviceName, FolderPath, ProcessCommandLine
| order by TimeGenerated desc
pass146.59s0.3239
o1-low
python3 -m http.server 9090
DeviceProcessEvents
| join kind=inner (
    DeviceInfo
    | where OSPlatform contains "Linux"
) on DeviceId
| where (FileName in~ ("python", "python3") or ProcessCommandLine contains "python")
| where ProcessCommandLine contains "9090"
| where ProcessCommandLine contains "/tmp" or FolderPath has "/tmp" or InitiatingProcessFolderPath has "/tmp"
| project TimeGenerated, DeviceName, FolderPath, FileName, ProcessCommandLine, ProcessCreationTime
| order by TimeGenerated desc
pass399.55s0.6801
o3-high
python3 -m http.server 9090
// 1) restrict the hunt to Linux machines that sent telemetry in the selected time window
let LinuxDevices = DeviceInfo
    | where OSPlatform has "Linux"
    | summarize by DeviceId;

// 2) find python3 processes that look like a one-off HTTP server under /tmp listening on port 9090
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where DeviceId in (LinuxDevices)
// make sure we are looking at python3 (name or command-line)
| where FileName startswith "python3" or ProcessCommandLine has "python3"
// invocation of the built-in web-server module (modern & legacy forms)
| where ProcessCommandLine has "http.server" or ProcessCommandLine matches regex "(?i)SimpleHTTPServer"
// command must mention the port number and the /tmp directory
| where ProcessCommandLine has "9090" and ProcessCommandLine has "/tmp"
// extract any 4- or 5-digit number surrounded by whitespace or punctuation, treat it as a candidate port
| extend ExtractedPort = toint(extract(@"(?:\s|:)(\d{4,5})(?:\s|$)", 1, ProcessCommandLine))
| where ExtractedPort == 9090
// if the same process logged multiple creation events, keep the most recent
| summarize arg_max(TimeGenerated, *) by DeviceId, ProcessId
| project TimeGenerated,
          DeviceName,
          AccountName,
          ProcessId,
          ProcessCommandLine,
          FolderPath,
          InitiatingProcessCommandLine
pass5170.59s0.0920
o3-mini-high
python3 -m http.server 9090
DeviceProcessEvents
| extend CMD = coalesce(ProcessCommandLine, InitiatingProcessCommandLine)
| where CMD contains "python3"
      and CMD contains "/tmp"
      and CMD contains "9090"
| project TimeGenerated, DeviceName, FileName, CMD
| order by TimeGenerated desc
pass367.81s0.0280
o3-mini-low
python3 -m http.server 9090
DeviceProcessEvents
| where ProcessCommandLine contains "python3"
| where ProcessCommandLine contains "/tmp"
| where ProcessCommandLine contains "9090"
| project TimeGenerated, DeviceName, ProcessCommandLine, InitiatingProcessCommandLine
| order by TimeGenerated asc
pass248.49s0.0214
o4-mini-high
python3 -m http.server 9090
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where ProcessCommandLine has "python3" and ProcessCommandLine has "9090" and ProcessCommandLine has "/tmp"
| project ProcessCreationTime, DeviceName, ProcessId, ProcessCommandLine
| order by ProcessCreationTime desc
pass133.09s0.0126
o4-mini-low
python3 -m http.server 9090
DeviceProcessEvents
| where FileName == "python3" or ProcessCommandLine has "python3"
| where ProcessCommandLine has "/tmp"
    and (ProcessCommandLine has "http.server" or ProcessCommandLine has "SimpleHTTPServer" or ProcessCommandLine has "-m http.server")
| where ProcessCommandLine has "9090"
| project ProcessCreationTime, DeviceName, ProcessId, ProcessCommandLine
| sort by ProcessCreationTime asc
pass3101.79s0.0294