// question

An attacker leveraged a PowerShell command on a Windows host to enumerate browser bookmark files across all user profiles. Examine the process execution logs to determine the exact filename that was being searched for.

Reference KQL answer and model-by-model comparison.

faab755e-4299-48ec-8202-fc7885eb6545
question id
8/23
models correct
1
valid answer
35%
success rate
// reference answer

Human-validated correct answer for this question.

Bookmarks
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
Bookmarks
DeviceProcessEvents
| where FileName =~ "powershell.exe"
| where ProcessCommandLine has "Get-ChildItem" or ProcessCommandLine has "dir"
| where ProcessCommandLine has @"C:\Users\"
| where ProcessCommandLine has "Bookmarks" or ProcessCommandLine has "places.sqlite" or ProcessCommandLine has "*.html" or ProcessCommandLine has "*.url"
| project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
pass439.64s0.0206
gpt-35-turbo
no answer
no query generatedfail50.00s0.0118
gpt-4-turbo-2024-04-09
no answer
no query generatedfail50.00s0.2306
gpt-4.1
Bookmarks
DeviceProcessEvents
| where FileName =~ "powershell.exe"
| where ProcessCommandLine has_any ("Bookmarks", "bookmarks", "Bookmarks.bak", "Favorites", "favorites.db", "favicons.db", "places.sqlite", "user_data")
| extend SearchedFile = extract(@"(Bookmarks(\\.bak)?|favorites\\.db|favicons\\.db|places\\.sqlite|user_data)", 0, ProcessCommandLine)
| where isnotempty(SearchedFile)
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, SearchedFile
pass19.20s0.0114
gpt-4.1-finetuned
/.config/chromium/Bookmarks
// Step 1: Find PowerShell events related to Chrome Bookmark
DeviceProcessEvents
| where InitiatingProcessCommandLine has "Bookmarks" and InitiatingProcessCommandLine has "Chrome"
// Step 2: Extract the exact filename being searched for
| summarize arg_max(Timestamp, *) by InitiatingProcessCommandLine
| extend RawFileName = extract(@'Open-FileName\s+"?([a-zA-Z0-9 _.-]*)', 1, InitiatingProcessCommandLine)
// Step 3: Clean up the filename value
| extend Filename = trim("\"", RawFileName)
| project Filename, InitiatingProcessCommandLine, AccountName, DeviceName, Timestamp
// Step 4: Keep the latest entry if there are duplicates
| summarize arg_max(Timestamp, *) by Filename
| sort by Filename asc
pass327.27s0.0337
gpt-4.1-mini
\Desktop\YOUR_FILES.txt
DeviceProcessEvents
| where InitiatingProcessFileName contains "powershell"
| where ProcessCommandLine has_any (".url", ".website", "bookmarks", "favorites", ".json", ".adr", ".bookmark", ".dat", ".txt")
| extend SearchedFilePattern = extract(@"([\w:\\\/\._\-]+\.(url|website|json|adr|txt|dat|bookmark|favorites?))", 0, ProcessCommandLine)
| where isnotempty(SearchedFilePattern)
| summarize Count = count(), Devices = make_set(DeviceName), Users = make_set(InitiatingProcessAccountName) by SearchedFilePattern
| order by Count desc
| project SearchedFilePattern, Count, Devices, Users
fail429.90s0.0053
gpt-4.1-nano
no answer
no query generatedfail50.00s0.0013
gpt-4o
no answer
no query generatedfail50.00s0.0471
gpt-5-high
no answer
no query generatedfail50.00s0.3160
gpt-5-mini-high
Bookmarks
union DeviceProcessEvents, DeviceEvents
| where isnotempty(ProcessCommandLine) or isnotempty(InitiatingProcessCommandLine)
| extend Cmd = coalesce(ProcessCommandLine, InitiatingProcessCommandLine)
| where tolower(Cmd) contains "powershell"
// Narrow to commands that look like directory enumeration/search or reference user profile paths
| where Cmd has_any ("Get-ChildItem","gci","-Filter","-Include","Select-String","Get-Item","-Recurse") or Cmd matches regex "Users[\\\\/]"
// Extract candidate filename or search tokens that reference common bookmark artifacts (case-insensitive)
| extend candidates = extract_all(@"(?i)([^\s'\""]*(?:bookmark|bookmarks|places\.sqlite|favorites)[^\s'\""]*)", Cmd)
| mv-expand candidate = candidates to typeof(string)
| where isnotempty(candidate)
| project TimeGenerated, DeviceName, AccountName, ProcessId, InitiatingProcessFileName, Cmd, candidate
| summarize Count = count(), Devices = make_set(DeviceName,10), ExampleTime = min(TimeGenerated), ExampleCmd = any(Cmd) by candidate
| order by Count desc
pass121.91s0.0061
gpt-5-mini-low
no answer
no query generatedfail50.00s0.0152
gpt-5-mini-medium
no answer
no query generatedfail50.00s0.0263
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0097
gpt-5-nano-medium
no answer
no query generatedfail50.00s0.0113
grok-3-beta
no answer
no query generatedfail50.00s0.0979
grok-3-mini-beta
Bookmarks
DeviceProcessEvents
| where FileName endswith "powershell.exe"
| where ProcessCommandLine contains "Get-ChildItem" or ProcessCommandLine contains "dir" or ProcessCommandLine contains "bookmarks"
| project DeviceName, Timestamp, ProcessCommandLine
| order by Timestamp desc
pass115.79s0.0024
o1-high
Bookmarks
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where tolower(FileName) contains "powershell" or tolower(InitiatingProcessFileName) contains "powershell"
| where tolower(ProcessCommandLine) contains "bookmark"
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, FolderPath, FileName
| order by TimeGenerated desc
pass256.02s0.3955
o1-low
Bookmarks
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where FileName =~ "powershell.exe"
| where tolower(ProcessCommandLine) contains "bookmark" or tolower(ProcessCommandLine) contains "favorites"
| project TimeGenerated, DeviceName, AccountDomain, AccountName, FolderPath, ProcessCommandLine
pass243.12s0.3485
o3-high
Bookmarks
let PowerShellNames = dynamic(["powershell.exe","pwsh.exe","powershell_ise.exe"]);
DeviceProcessEvents
| where FileName in~ (PowerShellNames)
| where ActionType == "ProcessCreated"
// focus on commands that mention browser-bookmark artefacts
| where ProcessCommandLine has_any ("bookmark","Bookmarks","places.sqlite","Favicons","favorites")
// try to extract the concrete artefact/filename that was supplied
| extend SearchedFile = extract('(?i)(Bookmarks(?:\\.json|\\.sqlite|\\.bak)?|places\\.sqlite|Favicons(?:\\.db)?)',1,ProcessCommandLine)
| extend SearchedFile = iff(isempty(SearchedFile),
                            extract('(?i)-Filter\\s+[\'\"]?([^\\s\'\"]+)',1,ProcessCommandLine),
                            SearchedFile)
| where isnotempty(SearchedFile)
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, SearchedFile
| summarize Executions=count(), Hosts=make_set(DeviceName,20) by SearchedFile
| order by Executions desc
pass268.37s0.0500
o3-mini-high
no answer
no query generatedfail50.00s0.0493
o3-mini-low
no answer
no query generatedfail50.00s0.0433
o4-mini-high
no answer
no query generatedfail50.00s0.0387
o4-mini-low
no answer
no query generatedfail50.00s0.0358