From 0bc64708fc39076a8dae5c13b37c665b64733b61 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 09:47:24 -0500 Subject: [PATCH 01/26] newstory --- stories/suspicious_local_llm_frameworks.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 stories/suspicious_local_llm_frameworks.yml diff --git a/stories/suspicious_local_llm_frameworks.yml b/stories/suspicious_local_llm_frameworks.yml new file mode 100644 index 0000000000..e0cc2c17e9 --- /dev/null +++ b/stories/suspicious_local_llm_frameworks.yml @@ -0,0 +1,21 @@ +name: Suspicious Local Llm Frameworks +id: 0b4396a1-aeff-412e-b39e-4e26457c780d +version: 1 +date: '2025-11-12' +author: Rod Soto, Splunk +status: production +description: Leverage advanced Splunk searches to detect and investigate suspicious activities targeting possibly unauthorized local LLM frameworks. This analytic story addresses discovery and detection of unauthorized local llm frameworks and related shadow AI artifacts. +narrative: Detect and triage unauthorized local LLM frameworks (shadow AI) to prevent covert model manipulation, data exfiltration, and persistent behavioral changes. +references: +- https://splunkbase.splunk.com/app/8024 +- https://www.ibm.com/think/topics/shadow-ai +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +tags: + category: + - Adversary Tactics + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + usecase: Advanced Threat Detection \ No newline at end of file From 66e5a8a4304078c5729252eaf98b6a3f7546735c Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 10:33:11 -0500 Subject: [PATCH 02/26] firstdet --- .../suspicious_local_llm_framework.yml | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 detections/endpoint/suspicious_local_llm_framework.yml diff --git a/detections/endpoint/suspicious_local_llm_framework.yml b/detections/endpoint/suspicious_local_llm_framework.yml new file mode 100644 index 0000000000..d34e8c7685 --- /dev/null +++ b/detections/endpoint/suspicious_local_llm_framework.yml @@ -0,0 +1,77 @@ +name: Suspicious Local LLM Framework +id: 657b022a-9c50-4910-8572-f036cc4a0248 +version: 1 +date: '2025-11-12' +author: Rod Soto +status: production +type: Hunting +description: This detection identifies suspicious execution of unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, NutStudio, Llama-Run) and related AI/ML libraries (HuggingFace, LangChain, Transformers) by monitoring Windows process creation events (Event ID 4688). The search correlates process names, command-line arguments, and parent processes to classify framework activity and flag potential shadow AI deployments or unauthorized model inference operations on endpoints. +data_source: +- Windows Security 4688 +search: "`wineventlog_security` EventID=4688 | spath +| rename "Event.System.Computer" as Computer, "Event.System.EventID" as EventID +| eval NewProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessName")) +| eval ParentProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ParentProcessName")) +| eval CommandLine=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "CommandLine")) +| eval SubjectUserName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectUserName")) +| search ( + NewProcessName="*ollama*" OR + NewProcessName="*llama*" OR + NewProcessName="*llama-run*" OR + NewProcessName="*gpt4all*" OR + NewProcessName="*lmstudio*" OR + NewProcessName="*nutstudio*" OR + NewProcessName="*koboldcpp*" OR + NewProcessName="*jan*" OR + NewProcessName="*jan.exe*" OR + CommandLine="*transformers*" OR + CommandLine="*langchain*" OR + CommandLine="*huggingface*" OR + CommandLine="*llama-run*" OR + CommandLine="*nutstudio*" OR + ParentProcessName="*ollama*" OR + ParentProcessName="*lmstudio*" OR + ParentProcessName="*nutstudio*" OR + ParentProcessName="*gpt4all*" OR + ParentProcessName="*jan*" OR + ParentProcessName="*llama-run*" +) +| eval Framework=case( + like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", + like(NewProcessName, "%lmstudio%") OR like(NewProcessName, "%LM Studio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", + like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%") OR like(CommandLine, "%nutstudio%"), "NutStudio", + like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", + like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%") OR like(NewProcessName, "%jan.exe%"), "Jan", + like(NewProcessName, "%koboldcpp%") OR like(CommandLine, "%koboldcpp%"), "KoboldCPP", + like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%") OR like(CommandLine, "%llama-run%"), "Llama-Run", + like(CommandLine, "%transformers%") OR like(CommandLine, "%huggingface%"), "HuggingFace/Transformers", + like(CommandLine, "%langchain%"), "LangChain", + like(NewProcessName, "%llama%") OR like(NewProcessName, "%llama.cpp%") OR like(ParentProcessName, "%llama%"), "Llama.cpp", + 1=1, "Related Activity" +) +| stats count by Computer, Framework, EventID, ParentProcessName +| sort Computer, Framework, -count | `suspicious_local_llm_framework_filter`" +how_to_implement: This search can be implemented by configuring Splunk to ingest Windows Security Event logs, specifically monitoring Event ID 4688 (process creation). Ensure that process creation events include detailed command-line arguments. Deploy the search as a scheduled saved search or real-time alert within Splunk Enterprise Security or Splunk Cloud to continuously detect suspicious local LLM framework activity. Tune the search by updating the process name and command-line keywords as new frameworks emerge. Integrate with asset and identity data to enrich context and reduce false positives. +known_false_positives: Legitimate development and data science workflows where developers, ML engineers, and researchers install and run local LLM frameworks for experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments, open-source and educational use cases, third-party software bundling HuggingFace/Transformers/LangChain libraries as dependencies, and system administrators deploying frameworks as part of containerized services. Parent process and command-line keyword overlap with unrelated tools (e.g., "llama-backup", tools using "--transformers" flags for non-LLM purposes). Recommended tuning — baseline approved frameworks and users, exclude sanctioned development/lab systems, require additional context (user role, peer group, model artifacts, network exfiltration signals) before escalating to incidents. +references: +- https://splunkbase.splunk.com/app/8024 +- https://www.ibm.com/think/topics/shadow-ai +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +tags: + analytic_story: + - Suspicious Local Llm Frameworks + asset_type: 'Endpoint' + mitre_attack_id: + - T1543 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +tests: +- name: True Positive Test + attack_data: + - data: http://localhost/data/ad4688_local_llms.txt + sourcetype: XmlWinEventLog + source: XmlWinEventLog:Security From ab083a173fa7b1432ea5872219632d0b939b1779 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 12:37:23 -0500 Subject: [PATCH 03/26] fixeddatasets --- .../suspicious_local_llm_framework.yml | 50 +++++++--- ..._local_llm_framework_process_execution.yml | 98 +++++++++++++++++++ 2 files changed, 134 insertions(+), 14 deletions(-) create mode 100644 detections/endpoint/suspicious_local_llm_framework_process_execution.yml diff --git a/detections/endpoint/suspicious_local_llm_framework.yml b/detections/endpoint/suspicious_local_llm_framework.yml index d34e8c7685..c444c0ac6f 100644 --- a/detections/endpoint/suspicious_local_llm_framework.yml +++ b/detections/endpoint/suspicious_local_llm_framework.yml @@ -8,13 +8,14 @@ type: Hunting description: This detection identifies suspicious execution of unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, NutStudio, Llama-Run) and related AI/ML libraries (HuggingFace, LangChain, Transformers) by monitoring Windows process creation events (Event ID 4688). The search correlates process names, command-line arguments, and parent processes to classify framework activity and flag potential shadow AI deployments or unauthorized model inference operations on endpoints. data_source: - Windows Security 4688 -search: "`wineventlog_security` EventID=4688 | spath -| rename "Event.System.Computer" as Computer, "Event.System.EventID" as EventID -| eval NewProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessName")) -| eval ParentProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ParentProcessName")) -| eval CommandLine=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "CommandLine")) -| eval SubjectUserName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectUserName")) -| search ( +search: | + `wineventlog_security` EventID=4688 | spath + | rename "Event.System.Computer" as host, "Event.System.EventID" as EventID + | eval NewProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessName")) + | eval ParentProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ParentProcessName")) + | eval CommandLine=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "CommandLine")) + | eval SubjectUserName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectUserName")) + | search ( NewProcessName="*ollama*" OR NewProcessName="*llama*" OR NewProcessName="*llama-run*" OR @@ -35,8 +36,8 @@ search: "`wineventlog_security` EventID=4688 | spath ParentProcessName="*gpt4all*" OR ParentProcessName="*jan*" OR ParentProcessName="*llama-run*" -) -| eval Framework=case( + ) + | eval Framework=case( like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", like(NewProcessName, "%lmstudio%") OR like(NewProcessName, "%LM Studio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%") OR like(CommandLine, "%nutstudio%"), "NutStudio", @@ -48,16 +49,37 @@ search: "`wineventlog_security` EventID=4688 | spath like(CommandLine, "%langchain%"), "LangChain", like(NewProcessName, "%llama%") OR like(NewProcessName, "%llama.cpp%") OR like(ParentProcessName, "%llama%"), "Llama.cpp", 1=1, "Related Activity" -) -| stats count by Computer, Framework, EventID, ParentProcessName -| sort Computer, Framework, -count | `suspicious_local_llm_framework_filter`" + ) + | stats count by host, Framework, EventID, ParentProcessName + | sort host, Framework, -count | `suspicious_local_llm_framework_filter` how_to_implement: This search can be implemented by configuring Splunk to ingest Windows Security Event logs, specifically monitoring Event ID 4688 (process creation). Ensure that process creation events include detailed command-line arguments. Deploy the search as a scheduled saved search or real-time alert within Splunk Enterprise Security or Splunk Cloud to continuously detect suspicious local LLM framework activity. Tune the search by updating the process name and command-line keywords as new frameworks emerge. Integrate with asset and identity data to enrich context and reduce false positives. known_false_positives: Legitimate development and data science workflows where developers, ML engineers, and researchers install and run local LLM frameworks for experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments, open-source and educational use cases, third-party software bundling HuggingFace/Transformers/LangChain libraries as dependencies, and system administrators deploying frameworks as part of containerized services. Parent process and command-line keyword overlap with unrelated tools (e.g., "llama-backup", tools using "--transformers" flags for non-LLM purposes). Recommended tuning — baseline approved frameworks and users, exclude sanctioned development/lab systems, require additional context (user role, peer group, model artifacts, network exfiltration signals) before escalating to incidents. references: - https://splunkbase.splunk.com/app/8024 - https://www.ibm.com/think/topics/shadow-ai - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html -- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +drilldown_searches: +- name: View the detection results for - "$host$" + search: '%original_detection_search% | search host="$host$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$host$" + search: | + | from datamodel Risk.All_Risk + | search normalized_risk_object="$host$" starthoursago=168 + | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +rba: + message: Unauthorized local LLM framework detected on $host$ running $Framework$ spawned by $ParentProcessName$ with $count$ event occurrences. This indicates potential shadow AI deployment for unauthorized model inference, data exfiltration, or model manipulation. Immediate investigation required to assess scope and containment. + risk_objects: + - field: host + type: system + score: 60 + threat_objects: [] tags: analytic_story: - Suspicious Local Llm Frameworks @@ -72,6 +94,6 @@ tags: tests: - name: True Positive Test attack_data: - - data: http://localhost/data/ad4688_local_llms.txt + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt sourcetype: XmlWinEventLog source: XmlWinEventLog:Security diff --git a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml new file mode 100644 index 0000000000..2186fa47bb --- /dev/null +++ b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml @@ -0,0 +1,98 @@ +name: Suspicious Local LLM Framework Process Execution +id: 0ba9df5a-017c-4651-bb47-3764b06ddf28 +version: 1 +date: '2025-11-12' +author: Rod Soto +status: production +type: Hunting +description: Detects execution of unauthorized local LLM frameworks (Ollama, LM Studio, NutStudio, GPT4All, Jan, Llama-Run) on Windows endpoints by monitoring Event ID 4688 process creation events. Correlates process names and parent processes to identify shadow AI deployments, classifies integrity levels and elevation types, and surfaces process chains for investigation of potential unauthorized model inference or data exfiltration. +data_source: +- Windows Security 4688 +search: | + `wineventlog_security` sourcetype=XmlWinEventLog EventID=4688 | spath + | rename "Event.System.Computer" as host + | eval SubjectUserName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectUserName")) + | eval SubjectDomainName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectDomainName")) + | eval SubjectLogonId=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectLogonId")) + | eval NewProcessId=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessId")) + | eval NewProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessName")) + | eval TokenElevationType=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "TokenElevationType")) + | eval ProcessId=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ProcessId")) + | eval CommandLine=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "CommandLine")) + | eval ParentProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ParentProcessName")) + | eval MandatoryLabel=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "MandatoryLabel")) + | search ( + NewProcessName="*ollama*" OR NewProcessName="*lmstudio*" OR + NewProcessName="*nutstudio*" OR NewProcessName="*gpt4all*" OR + NewProcessName="*jan*" OR NewProcessName="*llama-run*" OR + ParentProcessName="*ollama*" OR ParentProcessName="*lmstudio*" OR + ParentProcessName="*nutstudio*" OR ParentProcessName="*gpt4all*" OR + ParentProcessName="*jan*" OR ParentProcessName="*llama-run*" + ) + | eval Framework=case( + like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", + like(NewProcessName, "%lmstudio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", + like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%"), "NutStudio", + like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", + like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%"), "Jan", + like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%"), "Llama-Run", + 1=1, "Other" + ) + | eval IntegrityLevel=case( + MandatoryLabel="S-1-16-16384", "System", + MandatoryLabel="S-1-16-12288", "High", + MandatoryLabel="S-1-16-8192", "Medium", + MandatoryLabel="S-1-16-4096", "Low", + MandatoryLabel="S-1-16-0", "Untrusted", + 1=1, "Unknown" + ) + | eval Elevation=case( + TokenElevationType="%%1936", "Full Token (Admin)", + TokenElevationType="%%1937", "Elevated", + TokenElevationType="%%1938", "Limited", + 1=1, "Unknown" + ) + | eval ProcessChain=ParentProcessName + " -> " + NewProcessName + | table _time host Framework SubjectUserName SubjectDomainName SubjectLogonId IntegrityLevel Elevation ProcessChain CommandLine NewProcessId ProcessId + | sort -_time + | dedup ProcessChain | `suspicious_local_llm_framework_process_execution_filter` +how_to_implement: Ensure Windows Security Event Log collection (Event ID 4688 - Process Creation) is enabled and ingested into Splunk. Configure your Windows systems to audit process creation via Group Policy (Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking > Audit Process Creation). Verify the `wineventlog_security` macro exists in your Splunk environment and points to the correct index. The detection uses `spath` to parse XML EventData fields from Windows Security logs; ensure your Splunk forwarder or Windows Event Log Input app correctly normalizes these fields. Create or update the `suspicious_local_llm_framework_process_execution_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence (e.g., every 4 hours) to detect unauthorized LLM framework execution. Alert on deviations from baseline process chains and integrity/elevation levels for your environment. +known_false_positives: Legitimate development, data science, and AI/ML workflows where authorized developers, researchers, or engineers intentionally execute local LLM frameworks (Ollama, LM Studio, GPT4All, Jan) for model experimentation, fine-tuning, or prototyping. Approved sandbox and lab environments where framework testing is authorized. Open-source contributors and hobbyists running frameworks for educational purposes or community projects. Third-party applications that bundle or invoke LLM frameworks as dependencies (e.g., IDE plugins, analytics tools, chatbot integrations). System administrators deploying frameworks as part of containerized services or orchestrated ML workloads. Process name keyword overlap with unrelated utilities (e.g., "llama-backup", "janimation", "gpt4-config"). Recommended tuning — baseline approved frameworks and users by role/department, exclude sanctioned dev/lab systems, correlate with user identity and peer group anomalies before escalating to incident response. +drilldown_searches: +- name: View the detection results for - "$host$" + search: '%original_detection_search% | search host="$host$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$host$" + search: | + | from datamodel Risk.All_Risk + | search normalized_risk_object="$host$" starthoursago=168 + | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +rba: + message: Suspicious LLM framework process execution detected on $host$ running $Framework$ with $Elevation$ elevation and $IntegrityLevel$ integrity level. Process chain - $ProcessChain$. Unauthorized model loading or injection may indicate attempts to manipulate local model behavior, extract model weights, or achieve remote code execution through crafted artifacts. + risk_objects: + - field: host + type: system + score: 60 + threat_objects: [] +tags: + analytic_story: + - Suspicious Local Llm Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1543 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +tests: +- name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt + sourcetype: XmlWinEventLog + source: XmlWinEventLog:Security From ebe530b741a0d220bfa134242461e66a15701ea6 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 13:40:07 -0500 Subject: [PATCH 04/26] 4688locallmdiscovery --- detections/endpoint/suspicious_local_llm_framework.yml | 9 +-------- .../suspicious_local_llm_framework_process_execution.yml | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/detections/endpoint/suspicious_local_llm_framework.yml b/detections/endpoint/suspicious_local_llm_framework.yml index c444c0ac6f..ee01a92ae1 100644 --- a/detections/endpoint/suspicious_local_llm_framework.yml +++ b/detections/endpoint/suspicious_local_llm_framework.yml @@ -7,7 +7,7 @@ status: production type: Hunting description: This detection identifies suspicious execution of unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, NutStudio, Llama-Run) and related AI/ML libraries (HuggingFace, LangChain, Transformers) by monitoring Windows process creation events (Event ID 4688). The search correlates process names, command-line arguments, and parent processes to classify framework activity and flag potential shadow AI deployments or unauthorized model inference operations on endpoints. data_source: -- Windows Security 4688 +- Windows Event Log Security 4688 search: | `wineventlog_security` EventID=4688 | spath | rename "Event.System.Computer" as host, "Event.System.EventID" as EventID @@ -73,13 +73,6 @@ drilldown_searches: | `security_content_ctime(lastTime)` earliest_offset: $info_min_time$ latest_offset: $info_max_time$ -rba: - message: Unauthorized local LLM framework detected on $host$ running $Framework$ spawned by $ParentProcessName$ with $count$ event occurrences. This indicates potential shadow AI deployment for unauthorized model inference, data exfiltration, or model manipulation. Immediate investigation required to assess scope and containment. - risk_objects: - - field: host - type: system - score: 60 - threat_objects: [] tags: analytic_story: - Suspicious Local Llm Frameworks diff --git a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml index 2186fa47bb..219a5aa6de 100644 --- a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml +++ b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml @@ -7,7 +7,7 @@ status: production type: Hunting description: Detects execution of unauthorized local LLM frameworks (Ollama, LM Studio, NutStudio, GPT4All, Jan, Llama-Run) on Windows endpoints by monitoring Event ID 4688 process creation events. Correlates process names and parent processes to identify shadow AI deployments, classifies integrity levels and elevation types, and surfaces process chains for investigation of potential unauthorized model inference or data exfiltration. data_source: -- Windows Security 4688 +- Windows Event Log Security 4688 search: | `wineventlog_security` sourcetype=XmlWinEventLog EventID=4688 | spath | rename "Event.System.Computer" as host @@ -72,13 +72,6 @@ drilldown_searches: | `security_content_ctime(lastTime)` earliest_offset: $info_min_time$ latest_offset: $info_max_time$ -rba: - message: Suspicious LLM framework process execution detected on $host$ running $Framework$ with $Elevation$ elevation and $IntegrityLevel$ integrity level. Process chain - $ProcessChain$. Unauthorized model loading or injection may indicate attempts to manipulate local model behavior, extract model weights, or achieve remote code execution through crafted artifacts. - risk_objects: - - field: host - type: system - score: 60 - threat_objects: [] tags: analytic_story: - Suspicious Local Llm Frameworks From 11488f2a77c5f7bd046da3d88ed72a8c0ea34c02 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 15:13:34 -0500 Subject: [PATCH 05/26] sys1 --- ...work_download_and_execution_via_sysmon.yml | 77 +++++++++++++++++++ ..._local_llm_framework_process_execution.yml | 5 ++ 2 files changed, 82 insertions(+) create mode 100644 detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml diff --git a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml new file mode 100644 index 0000000000..dfe9e30ef1 --- /dev/null +++ b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml @@ -0,0 +1,77 @@ +name: Suspicious Local LLM Framework Download and Execution via Sysmon +id: cce60a07-d6ef-4295-8964-d5ca7f492c2a +version: 1 +date: '2025-11-12' +author: Rod Soto +status: production +type: Hunting +description: Detects unauthorized local LLM framework execution and model artifact access (`.gguf` files) by monitoring Sysmon process execution, file creation, and DNS query events to identify shadow AI deployments and unauthorized model inference operations. +data_source: +- Sysmon EventID 1 +search: | + `sysmon` | spath + | eval EventID='Event.System.EventID' + | eval Image=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$")) + | eval TargetFilename=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^TargetFilename$")) + | eval QueryName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^QueryName$")) + | eval host='Event.System.Computer' + | search ( + Image="*ollama*" OR Image="*gpt4all*" OR Image="*lmstudio*" OR Image="*kobold*" OR Image="*jan*" OR Image="*llama-run*" OR Image="*llama.cpp*" OR Image="*oobabooga*" OR Image="*text-generation-webui*" OR + TargetFilename="*.gguf" OR TargetFilename="*ollama*" OR TargetFilename="*jan*" OR + QueryName="*huggingface.co*" OR QueryName="*ollama.com*" + ) + | search Image!="*MsMpEng*" AND Image!="*defender*" AND Image!="*windows\system32*" AND Image!="*syswow64*" AND Image!="*winlogon*" AND Image!="*svchost*" + | eval Framework=case( + match(Image, "(?i)ollama\.exe$"), "Ollama", + match(Image, "(?i)gpt4all\.exe$"), "GPT4All", + match(Image, "(?i)lmstudio\.exe$"), "LMStudio", + match(Image, "(?i)koboldcpp\.exe$"), "KoboldCPP", + match(Image, "(?i)jan\.exe$"), "Jan AI", + match(Image, "(?i)llama.*\.exe$"), "llama.cpp", + match(Image, "(?i)oobabooga\.exe$"), "Oobabooga", + match(TargetFilename, "\.gguf$"), "Model Weight File", + match(QueryName, "(?i)(huggingface|ollama)"), "Model Registry Query" + ) + | where isnotnull(Framework) + | stats count by Framework, host, Image + | dedup Image | sort -count + | `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` +how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation (Event ID 1), file creation (Event ID 11), and DNS query (Event ID 22) events. Configure Sysmon's XML configuration file to log detailed command-line arguments, parent processes, and file paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence (e.g., every 2 hours) to detect unauthorized LLM framework execution, model file downloads, and DNS queries to model registries. Correlate findings with endpoint asset inventory and identity data to prioritize investigation and containment of shadow AI deployments. +known_false_positives: Legitimate development and data science workflows where authorized developers, ML engineers, and researchers intentionally execute local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, Oobabooga) for model experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments where framework testing is authorized. Open-source contributors and hobbyists running frameworks for educational purposes or community projects. Third-party applications and IDEs (e.g., Visual Studio Code extensions, Jupyter notebooks, Anaconda environments) that invoke HuggingFace, Transformers, or LangChain libraries as dependencies. System administrators or DevOps engineers deploying frameworks as part of containerized services, cloud workloads, or orchestrated ML pipelines. Legitimate network traffic to HuggingFace.co and Ollama.com registries from approved model download workflows. Machine learning tools and data science platforms (e.g., MLflow, DVC, Weights & Biases) that query model registries. Recommended tuning — baseline approved frameworks and users by role/department, exclude sanctioned dev/lab systems and asset groups, correlate with user identity, peer group anomalies, and unusual off-hours activity before escalating to incident response. +references: +- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon +- https://splunkbase.splunk.com/app/8024 +- https://www.ibm.com/think/topics/shadow-ai +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +drilldown_searches: +- name: View the detection results for - "$host$" + search: '%original_detection_search% | search host="$host$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$host$" + search: | + | from datamodel Risk.All_Risk + | search normalized_risk_object="$host$" starthoursago=168 + | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - Suspicious Local Llm Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1543 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +tests: +- name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + sourcetype: sysmon + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational diff --git a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml index 219a5aa6de..4ac59003a2 100644 --- a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml +++ b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml @@ -58,6 +58,11 @@ search: | | dedup ProcessChain | `suspicious_local_llm_framework_process_execution_filter` how_to_implement: Ensure Windows Security Event Log collection (Event ID 4688 - Process Creation) is enabled and ingested into Splunk. Configure your Windows systems to audit process creation via Group Policy (Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking > Audit Process Creation). Verify the `wineventlog_security` macro exists in your Splunk environment and points to the correct index. The detection uses `spath` to parse XML EventData fields from Windows Security logs; ensure your Splunk forwarder or Windows Event Log Input app correctly normalizes these fields. Create or update the `suspicious_local_llm_framework_process_execution_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence (e.g., every 4 hours) to detect unauthorized LLM framework execution. Alert on deviations from baseline process chains and integrity/elevation levels for your environment. known_false_positives: Legitimate development, data science, and AI/ML workflows where authorized developers, researchers, or engineers intentionally execute local LLM frameworks (Ollama, LM Studio, GPT4All, Jan) for model experimentation, fine-tuning, or prototyping. Approved sandbox and lab environments where framework testing is authorized. Open-source contributors and hobbyists running frameworks for educational purposes or community projects. Third-party applications that bundle or invoke LLM frameworks as dependencies (e.g., IDE plugins, analytics tools, chatbot integrations). System administrators deploying frameworks as part of containerized services or orchestrated ML workloads. Process name keyword overlap with unrelated utilities (e.g., "llama-backup", "janimation", "gpt4-config"). Recommended tuning — baseline approved frameworks and users by role/department, exclude sanctioned dev/lab systems, correlate with user identity and peer group anomalies before escalating to incident response. +references: +- https://splunkbase.splunk.com/app/8024 +- https://www.ibm.com/think/topics/shadow-ai +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama drilldown_searches: - name: View the detection results for - "$host$" search: '%original_detection_search% | search host="$host$"' From ebb4f1e76138b0f6c6199b6f9933ee5c94244552 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 15:48:47 -0500 Subject: [PATCH 06/26] sysmon --- ...us_local_llm_framework_download_and_execution_via_sysmon.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml index dfe9e30ef1..d104c05d5a 100644 --- a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml +++ b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml @@ -7,7 +7,7 @@ status: production type: Hunting description: Detects unauthorized local LLM framework execution and model artifact access (`.gguf` files) by monitoring Sysmon process execution, file creation, and DNS query events to identify shadow AI deployments and unauthorized model inference operations. data_source: -- Sysmon EventID 1 + - Sysmon EventID 1 search: | `sysmon` | spath | eval EventID='Event.System.EventID' From 233c0a6280baed6a482522ca686093714d341f85 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 17:52:36 -0500 Subject: [PATCH 07/26] secsys --- ...work_download_and_execution_via_sysmon.yml | 70 ++++++++----------- ...ed_llm_model_file_creation_on_endpoint.yml | 56 +++++++++++++++ 2 files changed, 86 insertions(+), 40 deletions(-) create mode 100644 detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml diff --git a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml index d104c05d5a..396949dd10 100644 --- a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml +++ b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml @@ -1,49 +1,50 @@ name: Suspicious Local LLM Framework Download and Execution via Sysmon -id: cce60a07-d6ef-4295-8964-d5ca7f492c2a +id: e27da0be-838a-40f2-bd4c-2dac4e7f6031 version: 1 date: '2025-11-12' author: Rod Soto status: production type: Hunting -description: Detects unauthorized local LLM framework execution and model artifact access (`.gguf` files) by monitoring Sysmon process execution, file creation, and DNS query events to identify shadow AI deployments and unauthorized model inference operations. +description: Detects execution of local LLM frameworks on Windows endpoints by monitoring Sysmon process creation events (Event ID 1) for known LLM tools including Ollama, GPT4All, LM Studio, Jan, llama.cpp, KoboldCPP, and Oobabooga. This hunting detection identifies shadow AI deployments and unauthorized local model inference operations by analyzing process execution patterns of LLM frameworks. data_source: - - Sysmon EventID 1 -search: | +- Sysmon EventID 1 +search: | `sysmon` | spath | eval EventID='Event.System.EventID' + | eval host='Event.System.Computer' | eval Image=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$")) | eval TargetFilename=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^TargetFilename$")) | eval QueryName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^QueryName$")) - | eval host='Event.System.Computer' - | search ( - Image="*ollama*" OR Image="*gpt4all*" OR Image="*lmstudio*" OR Image="*kobold*" OR Image="*jan*" OR Image="*llama-run*" OR Image="*llama.cpp*" OR Image="*oobabooga*" OR Image="*text-generation-webui*" OR - TargetFilename="*.gguf" OR TargetFilename="*ollama*" OR TargetFilename="*jan*" OR - QueryName="*huggingface.co*" OR QueryName="*ollama.com*" - ) - | search Image!="*MsMpEng*" AND Image!="*defender*" AND Image!="*windows\system32*" AND Image!="*syswow64*" AND Image!="*winlogon*" AND Image!="*svchost*" + | search ( Image="*ollama*" OR Image="*gpt4all*" OR Image="*lmstudio*" OR Image="*kobold*" OR Image="*jan*" OR Image="*llama-run*" OR Image="*llama.cpp*" OR Image="*oobabooga*" OR Image="*text-generation-webui*" OR TargetFilename="*.gguf*" OR TargetFilename="*ollama*" OR TargetFilename="*jan*" OR QueryName="*huggingface.co*" OR QueryName="*ollama.com*" ) + | search Image!="*MsMpEng*" AND Image!="*defender*" AND Image!="*windows/system32*" AND Image!="*syswow64*" AND Image!="*winlogon*" AND Image!="*svchost*" | eval Framework=case( - match(Image, "(?i)ollama\.exe$"), "Ollama", - match(Image, "(?i)gpt4all\.exe$"), "GPT4All", - match(Image, "(?i)lmstudio\.exe$"), "LMStudio", - match(Image, "(?i)koboldcpp\.exe$"), "KoboldCPP", - match(Image, "(?i)jan\.exe$"), "Jan AI", - match(Image, "(?i)llama.*\.exe$"), "llama.cpp", - match(Image, "(?i)oobabooga\.exe$"), "Oobabooga", - match(TargetFilename, "\.gguf$"), "Model Weight File", - match(QueryName, "(?i)(huggingface|ollama)"), "Model Registry Query" + match(Image, "(?i)ollama") OR match(TargetFilename, "(?i)ollama") OR match(QueryName, "(?i)ollama"), "Ollama", + match(Image, "(?i)lmstudio") OR match(Image, "(?i)lm-studio") OR match(TargetFilename, "(?i)lmstudio"), "LMStudio", + match(Image, "(?i)gpt4all") OR match(TargetFilename, "(?i)gpt4all"), "GPT4All", + match(Image, "(?i)kobold"), "KoboldCPP", + match(Image, "(?i)jan") OR match(TargetFilename, "(?i)jan"), "Jan AI", + match(Image, "(?i)llama-run") OR match(Image, "(?i)llama-b") OR match(Image, "(?i)llama.cpp"), "llama.cpp", + match(Image, "(?i)oobabooga") OR match(Image, "(?i)text-generation-webui"), "Oobabooga", + 1=1, "Other" ) - | where isnotnull(Framework) - | stats count by Framework, host, Image - | dedup Image | sort -count - | `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` -how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation (Event ID 1), file creation (Event ID 11), and DNS query (Event ID 22) events. Configure Sysmon's XML configuration file to log detailed command-line arguments, parent processes, and file paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence (e.g., every 2 hours) to detect unauthorized LLM framework execution, model file downloads, and DNS queries to model registries. Correlate findings with endpoint asset inventory and identity data to prioritize investigation and containment of shadow AI deployments. -known_false_positives: Legitimate development and data science workflows where authorized developers, ML engineers, and researchers intentionally execute local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, Oobabooga) for model experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments where framework testing is authorized. Open-source contributors and hobbyists running frameworks for educational purposes or community projects. Third-party applications and IDEs (e.g., Visual Studio Code extensions, Jupyter notebooks, Anaconda environments) that invoke HuggingFace, Transformers, or LangChain libraries as dependencies. System administrators or DevOps engineers deploying frameworks as part of containerized services, cloud workloads, or orchestrated ML pipelines. Legitimate network traffic to HuggingFace.co and Ollama.com registries from approved model download workflows. Machine learning tools and data science platforms (e.g., MLflow, DVC, Weights & Biases) that query model registries. Recommended tuning — baseline approved frameworks and users by role/department, exclude sanctioned dev/lab systems and asset groups, correlate with user identity, peer group anomalies, and unusual off-hours activity before escalating to incident response. + | search Framework!="Other" | stats count by Framework, host, Image | sort -count | `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter`'' +how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation events (Event ID 1). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution and shadow AI deployments. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. +known_false_positives: Legitimate creation of LLM model files by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where model file creation is expected. Automated ML pipelines and workflows that generate or update model files as part of their normal operation. Third-party applications and services that manage or cache LLM model files for legitimate purposes. references: - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon -- https://splunkbase.splunk.com/app/8024 -- https://www.ibm.com/think/topics/shadow-ai - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +tags: + analytic_story: + - Suspicious Local Llm Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1543 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint drilldown_searches: - name: View the detection results for - "$host$" search: '%original_detection_search% | search host="$host$"' @@ -58,20 +59,9 @@ drilldown_searches: | `security_content_ctime(lastTime)` earliest_offset: $info_min_time$ latest_offset: $info_max_time$ -tags: - analytic_story: - - Suspicious Local Llm Frameworks - asset_type: Endpoint - mitre_attack_id: - - T1543 - product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - security_domain: endpoint tests: - name: True Positive Test attack_data: - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt - sourcetype: sysmon + sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational diff --git a/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml b/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml new file mode 100644 index 0000000000..f1a6dbf787 --- /dev/null +++ b/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml @@ -0,0 +1,56 @@ +name: Unauthorized LLM Model File Creation on Endpoint +id: 23e5b797-378d-45d6-ab3e-d034ca12a99b +version: 1 +date: '2025-11-12' +author: Rod Soto +status: production +type: Hunting +description: Detects unauthorized creation of LLM model files on endpoints by monitoring Sysmon file creation events for specific model file extensions and names. +data_source: +- Sysmon EventID 11 +search: | + `sysmon`| spath + | search Event.System.EventID=11 + | eval host='Event.System.Computer' | eval TargetFilename=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^TargetFilename$")) + | eval Image=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$")) + | search TargetFilename="*.gguf*" OR TargetFilename="*ggml*" OR TargetFilename="*safetensors*" OR TargetFilename="*Modelfile*" + | table _time, host, Image, TargetFilename + | `unauthorized_llm_model_file_creation_on_endpoint_filter` +how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture file creation (Event ID 11). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent processes, and file paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `unauthorized_llm_model_file_creation_on_endpoint_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance. +known_false_positives: Legitimate creation of LLM model files by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where model file creation is expected. Automated ML pipelines and workflows that generate or update model files as part of their normal operation. Third-party applications and services that manage or cache LLM model files for legitimate purposes. +references: +- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon +- https://www.ibm.com/think/topics/shadow-ai +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +tags: + analytic_story: + - Suspicious Local Llm Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1543 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +drilldown_searches: +- name: View the detection results for - "$host$" + search: '%original_detection_search% | search host="$host$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$host$" + search: | + | from datamodel Risk.All_Risk + | search normalized_risk_object="$host$" starthoursago=168 + | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tests: +- name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational \ No newline at end of file From 7304cfcdf82ad0a12c1e86d78a46751892dcf017 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 18:26:55 -0500 Subject: [PATCH 08/26] llmdns --- .../endpoint/local_llm_model_dns_queries.yml | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 detections/endpoint/local_llm_model_dns_queries.yml diff --git a/detections/endpoint/local_llm_model_dns_queries.yml b/detections/endpoint/local_llm_model_dns_queries.yml new file mode 100644 index 0000000000..e171f858d5 --- /dev/null +++ b/detections/endpoint/local_llm_model_dns_queries.yml @@ -0,0 +1,77 @@ +name: Local LLM Model DNS Queries +id: e0cda953-b926-4778-b7df-df61dab7bb78 +version: 1 +date: '2025-11-12' +author: Rod Soto +status: production +type: Hunting +description: Detects DNS queries related to local LLM models on endpoints by monitoring Sysmon DNS query events (Event ID 22) for known LLM model domains and services. +data_source: +- Sysmon EventID 22 +search: | + `sysmon` | spath + | search Event.System.EventID=22 + | eval host='Event.System.Computer' + | eval QueryName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^QueryName$")) + | eval Image=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$")) + | search QueryName="*huggingface*" OR + QueryName="*ollama*" OR + QueryName="*jan.ai*" OR + QueryName="*gpt4all*" OR + QueryName="*nomic*" OR + QueryName="*koboldai*" OR + QueryName="*lmstudio*" OR + QueryName="*modelscope*" OR + QueryName="*civitai*" OR + QueryName="*github.com*llama*" OR + QueryName="*github.com*oobabooga*" OR + QueryName="*github.com*koboldai*" OR + QueryName="*replicate*" OR + QueryName="*anthropic*" OR + QueryName="*openai*" OR + QueryName="*openrouter*" OR + QueryName="*api.openrouter*" OR + QueryName="*aliyun*" OR + QueryName="*alibabacloud*" OR + QueryName="*dashscope.aliyuncs*" + | search Image!="*MsMpEng.exe*" AND Image!="*Windows Defender*" AND Image!="*system32*" AND Image!="*ProgramData*" AND Image!="*syswow64*" + | stats count by _time, host, Image, QueryName + | sort -count + | `local_llm_model_dns_queries_filter` +how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture DNS query events (Event ID 22). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `local_llm_model_dns_queries_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM model DNS queries and shadow AI activities. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. +known_false_positives: Legitimate DNS queries to LLM model hosting platforms by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where LLM model downloads are expected. Automated ML pipelines and workflows that interact with LLM model hosting services as part of their normal operation. Third-party applications and services that access LLM model platforms for legitimate purposes. +references: +- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +tags: + analytic_story: + - Suspicious Local Llm Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1590 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +drilldown_searches: +- name: View the detection results for - "$host$" + search: '%original_detection_search% | search host="$host$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$host$" + search: | + | from datamodel Risk.All_Risk + | search normalized_risk_object="$host$" starthoursago=168 + | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tests: +- name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational From 7d2ceb67668eb6d7c14ed3e00d9ac28e02d9f30f Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Wed, 12 Nov 2025 18:53:19 -0500 Subject: [PATCH 09/26] suspdownfix --- ...us_local_llm_framework_download_and_execution_via_sysmon.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml index 396949dd10..138bad50f0 100644 --- a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml +++ b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml @@ -27,7 +27,7 @@ search: | match(Image, "(?i)oobabooga") OR match(Image, "(?i)text-generation-webui"), "Oobabooga", 1=1, "Other" ) - | search Framework!="Other" | stats count by Framework, host, Image | sort -count | `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter`'' + | search Framework!="Other" | stats count by Framework, host, Image | sort -count | `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation events (Event ID 1). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution and shadow AI deployments. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. known_false_positives: Legitimate creation of LLM model files by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where model file creation is expected. Automated ML pipelines and workflows that generate or update model files as part of their normal operation. Third-party applications and services that manage or cache LLM model files for legitimate purposes. references: From ea51447f2805bac656a27236f733c5158ff3255c Mon Sep 17 00:00:00 2001 From: Rod Soto <50486899+rosplk@users.noreply.github.com> Date: Tue, 18 Nov 2025 21:40:59 -0500 Subject: [PATCH 10/26] Update detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml Co-authored-by: Nasreddine Bencherchali --- ...us_local_llm_framework_download_and_execution_via_sysmon.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml index 138bad50f0..e60f7ec4c2 100644 --- a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml +++ b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml @@ -63,5 +63,5 @@ tests: - name: True Positive Test attack_data: - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt - sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational From a7f446dea5669754b6fe4e642abdc9fee72b1dfd Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 16:38:06 -0500 Subject: [PATCH 11/26] localdnstosuspicious --- ...=> unauthorized_local_llm_framework_usage.yml} | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) rename detections/endpoint/{local_llm_model_dns_queries.yml => unauthorized_local_llm_framework_usage.yml} (78%) diff --git a/detections/endpoint/local_llm_model_dns_queries.yml b/detections/endpoint/unauthorized_local_llm_framework_usage.yml similarity index 78% rename from detections/endpoint/local_llm_model_dns_queries.yml rename to detections/endpoint/unauthorized_local_llm_framework_usage.yml index e171f858d5..b205e8afc9 100644 --- a/detections/endpoint/local_llm_model_dns_queries.yml +++ b/detections/endpoint/unauthorized_local_llm_framework_usage.yml @@ -1,11 +1,11 @@ -name: Local LLM Model DNS Queries -id: e0cda953-b926-4778-b7df-df61dab7bb78 +name: Unauthorized Local LLM Framework Usage +id: d7ceffc5-a45e-412b-b9fa-2ba27c284503 version: 1 date: '2025-11-12' author: Rod Soto status: production type: Hunting -description: Detects DNS queries related to local LLM models on endpoints by monitoring Sysmon DNS query events (Event ID 22) for known LLM model domains and services. +description: Detects DNS queries related to local LLM models on endpoints by monitoring Sysmon DNS query events (Event ID 22) for known LLM model domains and services. Local LLM frameworks like Ollama, LM Studio, and GPT4All make DNS calls to repositories such as huggingface.co and ollama.ai for model downloads, updates, and telemetry. These queries can reveal unauthorized AI tool usage or data exfiltration risks on corporate networks. data_source: - Sysmon EventID 22 search: | @@ -35,10 +35,11 @@ search: | QueryName="*alibabacloud*" OR QueryName="*dashscope.aliyuncs*" | search Image!="*MsMpEng.exe*" AND Image!="*Windows Defender*" AND Image!="*system32*" AND Image!="*ProgramData*" AND Image!="*syswow64*" - | stats count by _time, host, Image, QueryName - | sort -count - | `local_llm_model_dns_queries_filter` -how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture DNS query events (Event ID 22). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `local_llm_model_dns_queries_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM model DNS queries and shadow AI activities. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. + | stats count min(_time) as firstTime max(_time) as lastTime by host, Image, QueryName + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `unauthorized_local_llm_framework_usage_filter` +how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture DNS query events (Event ID 22). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `unauthorized_local_llm_framework_usage_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM model DNS queries and shadow AI activities. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. known_false_positives: Legitimate DNS queries to LLM model hosting platforms by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where LLM model downloads are expected. Automated ML pipelines and workflows that interact with LLM model hosting services as part of their normal operation. Third-party applications and services that access LLM model platforms for legitimate purposes. references: - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon From f5b7a083e8722b5b5868fc0a365747b1d26edc3b Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 17:07:22 -0500 Subject: [PATCH 12/26] windowsexecutionoflocallllmdet --- ...ndows_execution_of_local_llm_framework.yml | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 detections/endpoint/windows_execution_of_local_llm_framework.yml diff --git a/detections/endpoint/windows_execution_of_local_llm_framework.yml b/detections/endpoint/windows_execution_of_local_llm_framework.yml new file mode 100644 index 0000000000..98a8702dd4 --- /dev/null +++ b/detections/endpoint/windows_execution_of_local_llm_framework.yml @@ -0,0 +1,88 @@ +name: Windows Execution of Local LLM Framework +id: 2397d00a-cfd3-46e1-ba73-dee6d8ba1d0c +version: 1 +date: '2025-11-12' +author: Rod Soto +status: production +type: Hunting +description: This detection identifies suspicious execution of unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, NutStudio, Llama-Run) and related AI/ML libraries (HuggingFace, LangChain, Transformers) by monitoring Windows process creation events (Event ID 4688). The search correlates process names, command-line arguments, and parent processes to classify framework activity and flag potential shadow AI deployments or unauthorized model inference operations on endpoints. +data_source: +- Windows Event Log Security 4688 +search: | + `wineventlog_security` EventCode=4688 + | search ( + NewProcessName="*ollama*" OR + NewProcessName="*llama*" OR + NewProcessName="*llama-run*" OR + NewProcessName="*gpt4all*" OR + NewProcessName="*lmstudio*" OR + NewProcessName="*nutstudio*" OR + NewProcessName="*koboldcpp*" OR + NewProcessName="*jan*" OR + NewProcessName="*jan.exe*" OR + Process_Command_Line="*transformers*" OR + Process_Command_Line="*langchain*" OR + Process_Command_Line="*huggingface*" OR + Process_Command_Line="*llama-run*" OR + Process_Command_Line="*nutstudio*" OR + ParentProcessName="*ollama*" OR + ParentProcessName="*lmstudio*" OR + ParentProcessName="*nutstudio*" OR + ParentProcessName="*gpt4all*" OR + ParentProcessName="*jan*" OR + ParentProcessName="*llama-run*" + ) + | eval Framework=case( + like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", + like(NewProcessName, "%lmstudio%") OR like(NewProcessName, "%LM Studio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", + like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%") OR like(Process_Command_Line, "%nutstudio%"), "NutStudio", + like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", + like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%") OR like(NewProcessName, "%jan.exe%"), "Jan", + like(NewProcessName, "%koboldcpp%") OR like(Process_Command_Line, "%koboldcpp%"), "KoboldCPP", + like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%") OR like(Process_Command_Line, "%llama-run%"), "Llama-Run", + like(Process_Command_Line, "%transformers%") OR like(Process_Command_Line, "%huggingface%"), "HuggingFace/Transformers", + like(Process_Command_Line, "%langchain%"), "LangChain", + like(NewProcessName, "%llama%") OR like(NewProcessName, "%llama.cpp%") OR like(ParentProcessName, "%llama%"), "Llama.cpp", + 1=1, "Related Activity" + ) + | eval host=Computer + | stats count by host, Framework, EventCode, ParentProcessName, SubjectUserName + | sort host, Framework, -count | `windows_execution_of_local_llm_framework_filter` +how_to_implement: This search can be implemented by configuring Splunk to ingest Windows Security Event logs, specifically monitoring Event ID 4688 (process creation). Ensure that process creation events include detailed command-line arguments. Deploy the search as a scheduled saved search or real-time alert within Splunk Enterprise Security or Splunk Cloud to continuously detect suspicious local LLM framework activity. Tune the search by updating the process name and command-line keywords as new frameworks emerge. Integrate with asset and identity data to enrich context and reduce false positives. +known_false_positives: Legitimate development and data science workflows where developers, ML engineers, and researchers install and run local LLM frameworks for experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments, open-source and educational use cases, third-party software bundling HuggingFace/Transformers/LangChain libraries as dependencies, and system administrators deploying frameworks as part of containerized services. Parent process and command-line keyword overlap with unrelated tools (e.g., "llama-backup", tools using "--transformers" flags for non-LLM purposes). Recommended tuning — baseline approved frameworks and users, exclude sanctioned development/lab systems, require additional context (user role, peer group, model artifacts, network exfiltration signals) before escalating to incidents. +references: +- https://splunkbase.splunk.com/app/8024 +- https://www.ibm.com/think/topics/shadow-ai +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +drilldown_searches: +- name: View the detection results for - "$host$" + search: '%original_detection_search% | search host="$host$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$host$" + search: | + | from datamodel Risk.All_Risk + | search normalized_risk_object="$host$" starthoursago=168 + | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - Suspicious Local Llm Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1543 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +tests: +- name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt + sourcetype: XmlWinEventLog + source: XmlWinEventLog:Security From 32eaac6bcb0c60e9ca6d198cf4e74e499a8d7681 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 21:43:23 -0500 Subject: [PATCH 13/26] fixeddetections --- ...ed_llm_model_file_creation_on_endpoint.yml | 4 +- ...ndows_execution_of_local_llm_framework.yml | 115 +++++++++++------- 2 files changed, 76 insertions(+), 43 deletions(-) diff --git a/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml b/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml index f1a6dbf787..811cd2c1f4 100644 --- a/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml +++ b/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml @@ -5,7 +5,7 @@ date: '2025-11-12' author: Rod Soto status: production type: Hunting -description: Detects unauthorized creation of LLM model files on endpoints by monitoring Sysmon file creation events for specific model file extensions and names. +description: Detects unauthorized creation of Large Language Model (LLM) files on Windows endpoints by monitoring Sysmon Event ID 11 (File Creation) for specific model file formats and extensions commonly used by local AI frameworks. This detection identifies shadow AI deployments, unauthorized model downloads, and rogue LLM infrastructure by detecting file creation patterns associated with quantized models (.gguf, .ggml), safetensors model format files, and Ollama Modelfiles. These file types are characteristic of local inference frameworks such as Ollama, llama.cpp, GPT4All, LM Studio, and similar tools that enable running LLMs locally without cloud dependencies. Organizations can use this detection to identify potential data exfiltration risks, policy violations related to unapproved AI usage, and security blind spots created by decentralized AI deployments that bypass enterprise governance and monitoring. data_source: - Sysmon EventID 11 search: | @@ -16,7 +16,7 @@ search: | | search TargetFilename="*.gguf*" OR TargetFilename="*ggml*" OR TargetFilename="*safetensors*" OR TargetFilename="*Modelfile*" | table _time, host, Image, TargetFilename | `unauthorized_llm_model_file_creation_on_endpoint_filter` -how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture file creation (Event ID 11). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent processes, and file paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `unauthorized_llm_model_file_creation_on_endpoint_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance. +how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation events (Event ID 1). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution and shadow AI deployments. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. known_false_positives: Legitimate creation of LLM model files by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where model file creation is expected. Automated ML pipelines and workflows that generate or update model files as part of their normal operation. Third-party applications and services that manage or cache LLM model files for legitimate purposes. references: - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon diff --git a/detections/endpoint/windows_execution_of_local_llm_framework.yml b/detections/endpoint/windows_execution_of_local_llm_framework.yml index 98a8702dd4..bab42c396e 100644 --- a/detections/endpoint/windows_execution_of_local_llm_framework.yml +++ b/detections/endpoint/windows_execution_of_local_llm_framework.yml @@ -5,50 +5,83 @@ date: '2025-11-12' author: Rod Soto status: production type: Hunting -description: This detection identifies suspicious execution of unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, NutStudio, Llama-Run) and related AI/ML libraries (HuggingFace, LangChain, Transformers) by monitoring Windows process creation events (Event ID 4688). The search correlates process names, command-line arguments, and parent processes to classify framework activity and flag potential shadow AI deployments or unauthorized model inference operations on endpoints. +description: This detection identifies suspicious execution and activity related to unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, NutStudio, Llama-Run, Oobabooga) and related AI/ML libraries (HuggingFace, LangChain, Transformers) by monitoring Windows Security Event Log 4688 (process creation), Sysmon Event ID 1 (process creation), and Sysmon Event ID 11 (file creation). The search correlates process execution, LLM model file creation (*.gguf, *.ggml, safetensors, Modelfile), process names, command-line arguments, and parent processes to classify framework activity and flag potential shadow AI deployments or unauthorized model inference operations on endpoints. data_source: - Windows Event Log Security 4688 +- Sysmon EventID 1 +- Sysmon EventID 11 search: | - `wineventlog_security` EventCode=4688 - | search ( - NewProcessName="*ollama*" OR - NewProcessName="*llama*" OR - NewProcessName="*llama-run*" OR - NewProcessName="*gpt4all*" OR - NewProcessName="*lmstudio*" OR - NewProcessName="*nutstudio*" OR - NewProcessName="*koboldcpp*" OR - NewProcessName="*jan*" OR - NewProcessName="*jan.exe*" OR - Process_Command_Line="*transformers*" OR - Process_Command_Line="*langchain*" OR - Process_Command_Line="*huggingface*" OR - Process_Command_Line="*llama-run*" OR - Process_Command_Line="*nutstudio*" OR - ParentProcessName="*ollama*" OR - ParentProcessName="*lmstudio*" OR - ParentProcessName="*nutstudio*" OR - ParentProcessName="*gpt4all*" OR - ParentProcessName="*jan*" OR - ParentProcessName="*llama-run*" - ) - | eval Framework=case( - like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", - like(NewProcessName, "%lmstudio%") OR like(NewProcessName, "%LM Studio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", - like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%") OR like(Process_Command_Line, "%nutstudio%"), "NutStudio", - like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", - like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%") OR like(NewProcessName, "%jan.exe%"), "Jan", - like(NewProcessName, "%koboldcpp%") OR like(Process_Command_Line, "%koboldcpp%"), "KoboldCPP", - like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%") OR like(Process_Command_Line, "%llama-run%"), "Llama-Run", - like(Process_Command_Line, "%transformers%") OR like(Process_Command_Line, "%huggingface%"), "HuggingFace/Transformers", - like(Process_Command_Line, "%langchain%"), "LangChain", - like(NewProcessName, "%llama%") OR like(NewProcessName, "%llama.cpp%") OR like(ParentProcessName, "%llama%"), "Llama.cpp", - 1=1, "Related Activity" - ) - | eval host=Computer - | stats count by host, Framework, EventCode, ParentProcessName, SubjectUserName - | sort host, Framework, -count | `windows_execution_of_local_llm_framework_filter` -how_to_implement: This search can be implemented by configuring Splunk to ingest Windows Security Event logs, specifically monitoring Event ID 4688 (process creation). Ensure that process creation events include detailed command-line arguments. Deploy the search as a scheduled saved search or real-time alert within Splunk Enterprise Security or Splunk Cloud to continuously detect suspicious local LLM framework activity. Tune the search by updating the process name and command-line keywords as new frameworks emerge. Integrate with asset and identity data to enrich context and reduce false positives. + ((`wineventlog_security` EventCode=4688) OR (`sysmon`)) + | spath + | eval EventID=coalesce(EventCode, 'Event.System.EventID') + | search EventID=4688 OR EventID=1 OR EventID=11 + | eval process_name=coalesce(NewProcessName, mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$"))) + | eval parent_process=coalesce(ParentProcessName, mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^ParentImage$"))) + | eval command_line=coalesce(Process_Command_Line, mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^CommandLine$"))) + | eval user=coalesce(SubjectUserName, mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^User$"))) + | eval host=coalesce(Computer, 'Event.System.Computer') + | eval target_file=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^TargetFilename$")) + | eval event_id=coalesce(EventCode, EventID) + | search ( + process_name="*ollama*" OR + process_name="*llama*" OR + process_name="*llama-run*" OR + process_name="*gpt4all*" OR + process_name="*lmstudio*" OR + process_name="*nutstudio*" OR + process_name="*koboldcpp*" OR + process_name="*kobold*" OR + process_name="*jan*" OR + process_name="*oobabooga*" OR + process_name="*text-generation-webui*" OR + command_line="*transformers*" OR + command_line="*langchain*" OR + command_line="*huggingface*" OR + parent_process="*ollama*" OR + parent_process="*lmstudio*" OR + parent_process="*gpt4all*" OR + parent_process="*jan*" OR + target_file="*.gguf*" OR + target_file="*.ggml*" OR + target_file="*safetensors*" OR + target_file="*Modelfile*" OR + target_file="*ollama*" OR + target_file="*jan*" + ) + | search process_name!="*MsMpEng*" AND process_name!="*defender*" AND process_name!="*system32*" AND process_name!="*syswow64*" AND process_name!="*winlogon*" AND process_name!="*svchost*" + | eval Framework=case( + match(process_name, "(?i)ollama") OR match(parent_process, "(?i)ollama") OR match(target_file, "(?i)ollama"), "Ollama", + match(process_name, "(?i)lmstudio") OR match(process_name, "(?i)lm-studio") OR match(parent_process, "(?i)lmstudio") OR match(target_file, "(?i)lmstudio"), "LM Studio", + match(process_name, "(?i)nutstudio") OR match(parent_process, "(?i)nutstudio") OR match(command_line, "(?i)nutstudio"), "NutStudio", + match(process_name, "(?i)gpt4all") OR match(parent_process, "(?i)gpt4all") OR match(target_file, "(?i)gpt4all"), "GPT4All", + match(process_name, "(?i)jan") OR match(parent_process, "(?i)jan") OR match(target_file, "(?i)jan"), "Jan", + match(process_name, "(?i)kobold") OR match(command_line, "(?i)kobold"), "KoboldCPP", + match(process_name, "(?i)llama-run") OR match(parent_process, "(?i)llama-run") OR match(command_line, "(?i)llama-run"), "Llama-Run", + match(process_name, "(?i)oobabooga") OR match(process_name, "(?i)text-generation-webui") OR match(parent_process, "(?i)oobabooga"), "Oobabooga", + match(command_line, "(?i)transformers") OR match(command_line, "(?i)huggingface"), "HuggingFace/Transformers", + match(command_line, "(?i)langchain"), "LangChain", + match(process_name, "(?i)llama") OR match(process_name, "(?i)llama.cpp") OR match(parent_process, "(?i)llama"), "Llama.cpp", + match(target_file, "(?i).gguf") OR match(target_file, "(?i).ggml") OR match(target_file, "(?i)safetensors"), "Model File Activity", + 1=1, "Other" + ) + | eval activity_type=case( + event_id=4688 OR event_id=1, "Process Execution", + event_id=11, "File Creation", + 1=1, "Unknown" + ) + | eval source_type=case( + event_id=4688, "Windows Security", + event_id=1, "Sysmon Process", + event_id=11, "Sysmon File", + 1=1, "Unknown" + ) + | search Framework!="Other" + | stats count min(_time) as firstTime max(_time) as lastTime values(activity_type) as activity_types values(source_type) as sources values(process_name) as processes values(target_file) as files by host, Framework, user + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | sort host, Framework, -count + | `windows_execution_of_local_llm_framework_filter` +how_to_implement: This search requires Windows Security Event Log 4688 and/or Sysmon Event IDs 1 and 11. For Windows Security logs, ensure command-line logging is enabled via Group Policy (Computer Configuration > Administrative Templates > System > Audit Process Creation > Include command line in process creation events). For Sysmon, configure your XML configuration file to capture Event ID 1 (Process Creation) and Event ID 11 (File Creation) with detailed fields including Image, CommandLine, ParentImage, and TargetFilename. The search uses spath for Sysmon XML parsing and normalizes fields across both data sources using coalesce() to handle Windows Security TA-extracted fields and raw Sysmon XML fields. Verify that the `wineventlog_security` and `sysmon` macros are configured correctly in your Splunk environment. Create or update the `windows_execution_of_local_llm_framework_filter` macro to exclude approved development environments, authorized ML/AI workstations, or sanctioned frameworks. Deploy this search as a scheduled saved search or real-time alert within Splunk Enterprise Security or Splunk Cloud to continuously detect suspicious local LLM framework activity. Tune the search by updating process names, file patterns, and command-line keywords as new frameworks emerge. known_false_positives: Legitimate development and data science workflows where developers, ML engineers, and researchers install and run local LLM frameworks for experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments, open-source and educational use cases, third-party software bundling HuggingFace/Transformers/LangChain libraries as dependencies, and system administrators deploying frameworks as part of containerized services. Parent process and command-line keyword overlap with unrelated tools (e.g., "llama-backup", tools using "--transformers" flags for non-LLM purposes). Recommended tuning — baseline approved frameworks and users, exclude sanctioned development/lab systems, require additional context (user role, peer group, model artifacts, network exfiltration signals) before escalating to incidents. references: - https://splunkbase.splunk.com/app/8024 From 94c5c8ebc51b02f251aebc999a8b5428c56a5ddb Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 21:50:24 -0500 Subject: [PATCH 14/26] deletedold --- .../suspicious_local_llm_framework.yml | 92 ------------------- 1 file changed, 92 deletions(-) delete mode 100644 detections/endpoint/suspicious_local_llm_framework.yml diff --git a/detections/endpoint/suspicious_local_llm_framework.yml b/detections/endpoint/suspicious_local_llm_framework.yml deleted file mode 100644 index ee01a92ae1..0000000000 --- a/detections/endpoint/suspicious_local_llm_framework.yml +++ /dev/null @@ -1,92 +0,0 @@ -name: Suspicious Local LLM Framework -id: 657b022a-9c50-4910-8572-f036cc4a0248 -version: 1 -date: '2025-11-12' -author: Rod Soto -status: production -type: Hunting -description: This detection identifies suspicious execution of unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, NutStudio, Llama-Run) and related AI/ML libraries (HuggingFace, LangChain, Transformers) by monitoring Windows process creation events (Event ID 4688). The search correlates process names, command-line arguments, and parent processes to classify framework activity and flag potential shadow AI deployments or unauthorized model inference operations on endpoints. -data_source: -- Windows Event Log Security 4688 -search: | - `wineventlog_security` EventID=4688 | spath - | rename "Event.System.Computer" as host, "Event.System.EventID" as EventID - | eval NewProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessName")) - | eval ParentProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ParentProcessName")) - | eval CommandLine=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "CommandLine")) - | eval SubjectUserName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectUserName")) - | search ( - NewProcessName="*ollama*" OR - NewProcessName="*llama*" OR - NewProcessName="*llama-run*" OR - NewProcessName="*gpt4all*" OR - NewProcessName="*lmstudio*" OR - NewProcessName="*nutstudio*" OR - NewProcessName="*koboldcpp*" OR - NewProcessName="*jan*" OR - NewProcessName="*jan.exe*" OR - CommandLine="*transformers*" OR - CommandLine="*langchain*" OR - CommandLine="*huggingface*" OR - CommandLine="*llama-run*" OR - CommandLine="*nutstudio*" OR - ParentProcessName="*ollama*" OR - ParentProcessName="*lmstudio*" OR - ParentProcessName="*nutstudio*" OR - ParentProcessName="*gpt4all*" OR - ParentProcessName="*jan*" OR - ParentProcessName="*llama-run*" - ) - | eval Framework=case( - like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", - like(NewProcessName, "%lmstudio%") OR like(NewProcessName, "%LM Studio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", - like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%") OR like(CommandLine, "%nutstudio%"), "NutStudio", - like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", - like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%") OR like(NewProcessName, "%jan.exe%"), "Jan", - like(NewProcessName, "%koboldcpp%") OR like(CommandLine, "%koboldcpp%"), "KoboldCPP", - like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%") OR like(CommandLine, "%llama-run%"), "Llama-Run", - like(CommandLine, "%transformers%") OR like(CommandLine, "%huggingface%"), "HuggingFace/Transformers", - like(CommandLine, "%langchain%"), "LangChain", - like(NewProcessName, "%llama%") OR like(NewProcessName, "%llama.cpp%") OR like(ParentProcessName, "%llama%"), "Llama.cpp", - 1=1, "Related Activity" - ) - | stats count by host, Framework, EventID, ParentProcessName - | sort host, Framework, -count | `suspicious_local_llm_framework_filter` -how_to_implement: This search can be implemented by configuring Splunk to ingest Windows Security Event logs, specifically monitoring Event ID 4688 (process creation). Ensure that process creation events include detailed command-line arguments. Deploy the search as a scheduled saved search or real-time alert within Splunk Enterprise Security or Splunk Cloud to continuously detect suspicious local LLM framework activity. Tune the search by updating the process name and command-line keywords as new frameworks emerge. Integrate with asset and identity data to enrich context and reduce false positives. -known_false_positives: Legitimate development and data science workflows where developers, ML engineers, and researchers install and run local LLM frameworks for experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments, open-source and educational use cases, third-party software bundling HuggingFace/Transformers/LangChain libraries as dependencies, and system administrators deploying frameworks as part of containerized services. Parent process and command-line keyword overlap with unrelated tools (e.g., "llama-backup", tools using "--transformers" flags for non-LLM purposes). Recommended tuning — baseline approved frameworks and users, exclude sanctioned development/lab systems, require additional context (user role, peer group, model artifacts, network exfiltration signals) before escalating to incidents. -references: -- https://splunkbase.splunk.com/app/8024 -- https://www.ibm.com/think/topics/shadow-ai -- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html -- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama -drilldown_searches: -- name: View the detection results for - "$host$" - search: '%original_detection_search% | search host="$host$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -- name: View risk events for the last 7 days for - "$host$" - search: | - | from datamodel Risk.All_Risk - | search normalized_risk_object="$host$" starthoursago=168 - | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -tags: - analytic_story: - - Suspicious Local Llm Frameworks - asset_type: 'Endpoint' - mitre_attack_id: - - T1543 - product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - security_domain: endpoint -tests: -- name: True Positive Test - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt - sourcetype: XmlWinEventLog - source: XmlWinEventLog:Security From a39017b61ce7c09d6970f8726d9f6427dbc3ded0 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 22:11:52 -0500 Subject: [PATCH 15/26] fixedsearch --- ...ndows_execution_of_local_llm_framework.yml | 107 ++++++------------ 1 file changed, 36 insertions(+), 71 deletions(-) diff --git a/detections/endpoint/windows_execution_of_local_llm_framework.yml b/detections/endpoint/windows_execution_of_local_llm_framework.yml index bab42c396e..dd91c0e61d 100644 --- a/detections/endpoint/windows_execution_of_local_llm_framework.yml +++ b/detections/endpoint/windows_execution_of_local_llm_framework.yml @@ -5,83 +5,48 @@ date: '2025-11-12' author: Rod Soto status: production type: Hunting -description: This detection identifies suspicious execution and activity related to unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, Llama.cpp, KoboldCPP, NutStudio, Llama-Run, Oobabooga) and related AI/ML libraries (HuggingFace, LangChain, Transformers) by monitoring Windows Security Event Log 4688 (process creation), Sysmon Event ID 1 (process creation), and Sysmon Event ID 11 (file creation). The search correlates process execution, LLM model file creation (*.gguf, *.ggml, safetensors, Modelfile), process names, command-line arguments, and parent processes to classify framework activity and flag potential shadow AI deployments or unauthorized model inference operations on endpoints. +description: Detects execution of local Large Language Model (LLM) frameworks on Windows endpoints by monitoring Windows Security Event Log 4688 (Process Creation) for known LLM tools and AI/ML libraries. This hunting detection identifies shadow AI deployments and unauthorized local model inference operations by analyzing process execution patterns, command-line arguments, and parent process relationships for frameworks including Ollama, LM Studio, GPT4All, Jan, llama.cpp, KoboldCPP, NutStudio, and Python-based libraries such as HuggingFace Transformers and LangChain. The search leverages pre-extracted fields from the Splunk Add-on for Microsoft Windows to classify framework types and correlate process activity with potential security risks including data exfiltration through local AI processing, policy violations from unapproved AI usage, and decentralized AI deployments that bypass enterprise governance. Organizations can use this detection to gain visibility into local LLM infrastructure, identify users downloading or executing AI frameworks outside approved channels, and detect potential intellectual property risks from processing sensitive data through unmonitored local models. data_source: - Windows Event Log Security 4688 -- Sysmon EventID 1 -- Sysmon EventID 11 search: | - ((`wineventlog_security` EventCode=4688) OR (`sysmon`)) - | spath - | eval EventID=coalesce(EventCode, 'Event.System.EventID') - | search EventID=4688 OR EventID=1 OR EventID=11 - | eval process_name=coalesce(NewProcessName, mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$"))) - | eval parent_process=coalesce(ParentProcessName, mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^ParentImage$"))) - | eval command_line=coalesce(Process_Command_Line, mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^CommandLine$"))) - | eval user=coalesce(SubjectUserName, mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^User$"))) - | eval host=coalesce(Computer, 'Event.System.Computer') - | eval target_file=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^TargetFilename$")) - | eval event_id=coalesce(EventCode, EventID) - | search ( - process_name="*ollama*" OR - process_name="*llama*" OR - process_name="*llama-run*" OR - process_name="*gpt4all*" OR - process_name="*lmstudio*" OR - process_name="*nutstudio*" OR - process_name="*koboldcpp*" OR - process_name="*kobold*" OR - process_name="*jan*" OR - process_name="*oobabooga*" OR - process_name="*text-generation-webui*" OR - command_line="*transformers*" OR - command_line="*langchain*" OR - command_line="*huggingface*" OR - parent_process="*ollama*" OR - parent_process="*lmstudio*" OR - parent_process="*gpt4all*" OR - parent_process="*jan*" OR - target_file="*.gguf*" OR - target_file="*.ggml*" OR - target_file="*safetensors*" OR - target_file="*Modelfile*" OR - target_file="*ollama*" OR - target_file="*jan*" - ) - | search process_name!="*MsMpEng*" AND process_name!="*defender*" AND process_name!="*system32*" AND process_name!="*syswow64*" AND process_name!="*winlogon*" AND process_name!="*svchost*" + `wineventlog_security` EventCode=4688 + (NewProcessName="*ollama*" OR + NewProcessName="*llama*" OR + NewProcessName="*llama-run*" OR + NewProcessName="*gpt4all*" OR + NewProcessName="*lmstudio*" OR + NewProcessName="*nutstudio*" OR + NewProcessName="*koboldcpp*" OR + NewProcessName="*jan*" OR + NewProcessName="*jan.exe*" OR + CommandLine="*transformers*" OR + CommandLine="*langchain*" OR + CommandLine="*huggingface*" OR + CommandLine="*llama-run*" OR + CommandLine="*nutstudio*" OR + ParentProcessName="*ollama*" OR + ParentProcessName="*lmstudio*" OR + ParentProcessName="*nutstudio*" OR + ParentProcessName="*gpt4all*" OR + ParentProcessName="*jan*" OR + ParentProcessName="*llama-run*") + | eval host=Computer | eval Framework=case( - match(process_name, "(?i)ollama") OR match(parent_process, "(?i)ollama") OR match(target_file, "(?i)ollama"), "Ollama", - match(process_name, "(?i)lmstudio") OR match(process_name, "(?i)lm-studio") OR match(parent_process, "(?i)lmstudio") OR match(target_file, "(?i)lmstudio"), "LM Studio", - match(process_name, "(?i)nutstudio") OR match(parent_process, "(?i)nutstudio") OR match(command_line, "(?i)nutstudio"), "NutStudio", - match(process_name, "(?i)gpt4all") OR match(parent_process, "(?i)gpt4all") OR match(target_file, "(?i)gpt4all"), "GPT4All", - match(process_name, "(?i)jan") OR match(parent_process, "(?i)jan") OR match(target_file, "(?i)jan"), "Jan", - match(process_name, "(?i)kobold") OR match(command_line, "(?i)kobold"), "KoboldCPP", - match(process_name, "(?i)llama-run") OR match(parent_process, "(?i)llama-run") OR match(command_line, "(?i)llama-run"), "Llama-Run", - match(process_name, "(?i)oobabooga") OR match(process_name, "(?i)text-generation-webui") OR match(parent_process, "(?i)oobabooga"), "Oobabooga", - match(command_line, "(?i)transformers") OR match(command_line, "(?i)huggingface"), "HuggingFace/Transformers", - match(command_line, "(?i)langchain"), "LangChain", - match(process_name, "(?i)llama") OR match(process_name, "(?i)llama.cpp") OR match(parent_process, "(?i)llama"), "Llama.cpp", - match(target_file, "(?i).gguf") OR match(target_file, "(?i).ggml") OR match(target_file, "(?i)safetensors"), "Model File Activity", - 1=1, "Other" - ) - | eval activity_type=case( - event_id=4688 OR event_id=1, "Process Execution", - event_id=11, "File Creation", - 1=1, "Unknown" - ) - | eval source_type=case( - event_id=4688, "Windows Security", - event_id=1, "Sysmon Process", - event_id=11, "Sysmon File", - 1=1, "Unknown" - ) - | search Framework!="Other" - | stats count min(_time) as firstTime max(_time) as lastTime values(activity_type) as activity_types values(source_type) as sources values(process_name) as processes values(target_file) as files by host, Framework, user - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` + like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", + like(NewProcessName, "%lmstudio%") OR like(NewProcessName, "%LM Studio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", + like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%") OR like(CommandLine, "%nutstudio%"), "NutStudio", + like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", + like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%") OR like(NewProcessName, "%jan.exe%"), "Jan", + like(NewProcessName, "%koboldcpp%") OR like(CommandLine, "%koboldcpp%"), "KoboldCPP", + like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%") OR like(CommandLine, "%llama-run%"), "Llama-Run", + like(CommandLine, "%transformers%") OR like(CommandLine, "%huggingface%"), "HuggingFace/Transformers", + like(CommandLine, "%langchain%"), "LangChain", + like(NewProcessName, "%llama%") OR like(NewProcessName, "%llama.cpp%") OR like(ParentProcessName, "%llama%"), "Llama.cpp", + 1=1, "Related Activity") + | stats count by host, Framework, EventCode, ParentProcessName, NewProcessName, SubjectUserName | sort host, Framework, -count | `windows_execution_of_local_llm_framework_filter` -how_to_implement: This search requires Windows Security Event Log 4688 and/or Sysmon Event IDs 1 and 11. For Windows Security logs, ensure command-line logging is enabled via Group Policy (Computer Configuration > Administrative Templates > System > Audit Process Creation > Include command line in process creation events). For Sysmon, configure your XML configuration file to capture Event ID 1 (Process Creation) and Event ID 11 (File Creation) with detailed fields including Image, CommandLine, ParentImage, and TargetFilename. The search uses spath for Sysmon XML parsing and normalizes fields across both data sources using coalesce() to handle Windows Security TA-extracted fields and raw Sysmon XML fields. Verify that the `wineventlog_security` and `sysmon` macros are configured correctly in your Splunk environment. Create or update the `windows_execution_of_local_llm_framework_filter` macro to exclude approved development environments, authorized ML/AI workstations, or sanctioned frameworks. Deploy this search as a scheduled saved search or real-time alert within Splunk Enterprise Security or Splunk Cloud to continuously detect suspicious local LLM framework activity. Tune the search by updating process names, file patterns, and command-line keywords as new frameworks emerge. +how_to_implement: Enable Windows Security Event Log auditing for Process Creation (Event ID 4688) across Windows endpoints via Group Policy. Ensure the Audit Process Creation policy is enabled under Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking. Additionally, enable command-line process auditing by configuring the Include command line in process creation events policy under Computer Configuration > Administrative Templates > System > Audit Process Creation. Ingest Windows Security Event Logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with sourcetype=WinEventLog Security or XmlWinEventLog Security. Install and configure the Splunk Add-on for Microsoft Windows (TA-microsoft-windows) to ensure proper field extractions for NewProcessName, ParentProcessName, CommandLine, SubjectUserName, and Computer fields. Verify the wineventlog_security macro exists in your Splunk environment and correctly references the Windows Security event logs. Create or update the windows_execution_of_local_llm_framework_filter macro in your detections/filters folder to exclude approved development environments, authorized ML/AI workstations, sanctioned frameworks, or known safe systems. Deploy this hunting search as a scheduled saved search in Splunk Enterprise Security or Splunk Cloud to run on a regular cadence (recommended every 30-60 minutes). Tune the detection by adding new framework process names and command-line patterns as emerging LLM tools are identified. known_false_positives: Legitimate development and data science workflows where developers, ML engineers, and researchers install and run local LLM frameworks for experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments, open-source and educational use cases, third-party software bundling HuggingFace/Transformers/LangChain libraries as dependencies, and system administrators deploying frameworks as part of containerized services. Parent process and command-line keyword overlap with unrelated tools (e.g., "llama-backup", tools using "--transformers" flags for non-LLM purposes). Recommended tuning — baseline approved frameworks and users, exclude sanctioned development/lab systems, require additional context (user role, peer group, model artifacts, network exfiltration signals) before escalating to incidents. references: - https://splunkbase.splunk.com/app/8024 From d7e72b37ad601cfdd6017c931fd6e8761d07d6b0 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 22:23:08 -0500 Subject: [PATCH 16/26] fixedsuspiciouslocalllmframeworkprocessexecnospath --- ..._local_llm_framework_process_execution.yml | 68 ++++++++----------- 1 file changed, 27 insertions(+), 41 deletions(-) diff --git a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml index 4ac59003a2..fff3dc5b34 100644 --- a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml +++ b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml @@ -9,53 +9,39 @@ description: Detects execution of unauthorized local LLM frameworks (Ollama, LM data_source: - Windows Event Log Security 4688 search: | - `wineventlog_security` sourcetype=XmlWinEventLog EventID=4688 | spath - | rename "Event.System.Computer" as host - | eval SubjectUserName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectUserName")) - | eval SubjectDomainName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectDomainName")) - | eval SubjectLogonId=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "SubjectLogonId")) - | eval NewProcessId=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessId")) - | eval NewProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "NewProcessName")) - | eval TokenElevationType=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "TokenElevationType")) - | eval ProcessId=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ProcessId")) - | eval CommandLine=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "CommandLine")) - | eval ParentProcessName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "ParentProcessName")) - | eval MandatoryLabel=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "MandatoryLabel")) - | search ( - NewProcessName="*ollama*" OR NewProcessName="*lmstudio*" OR - NewProcessName="*nutstudio*" OR NewProcessName="*gpt4all*" OR - NewProcessName="*jan*" OR NewProcessName="*llama-run*" OR - ParentProcessName="*ollama*" OR ParentProcessName="*lmstudio*" OR - ParentProcessName="*nutstudio*" OR ParentProcessName="*gpt4all*" OR - ParentProcessName="*jan*" OR ParentProcessName="*llama-run*" - ) + `wineventlog_security` EventCode=4688 + (NewProcessName="*ollama*" OR NewProcessName="*lmstudio*" OR + NewProcessName="*nutstudio*" OR NewProcessName="*gpt4all*" OR + NewProcessName="*jan*" OR NewProcessName="*llama-run*" OR + ParentProcessName="*ollama*" OR ParentProcessName="*lmstudio*" OR + ParentProcessName="*nutstudio*" OR ParentProcessName="*gpt4all*" OR + ParentProcessName="*jan*" OR ParentProcessName="*llama-run*") + | eval host=Computer | eval Framework=case( - like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", - like(NewProcessName, "%lmstudio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", - like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%"), "NutStudio", - like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", - like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%"), "Jan", - like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%"), "Llama-Run", - 1=1, "Other" - ) + like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", + like(NewProcessName, "%lmstudio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", + like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%"), "NutStudio", + like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", + like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%"), "Jan", + like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%"), "Llama-Run", + 1=1, "Other") | eval IntegrityLevel=case( - MandatoryLabel="S-1-16-16384", "System", - MandatoryLabel="S-1-16-12288", "High", - MandatoryLabel="S-1-16-8192", "Medium", - MandatoryLabel="S-1-16-4096", "Low", - MandatoryLabel="S-1-16-0", "Untrusted", - 1=1, "Unknown" - ) + MandatoryLabel="S-1-16-16384", "System", + MandatoryLabel="S-1-16-12288", "High", + MandatoryLabel="S-1-16-8192", "Medium", + MandatoryLabel="S-1-16-4096", "Low", + MandatoryLabel="S-1-16-0", "Untrusted", + 1=1, "Unknown") | eval Elevation=case( - TokenElevationType="%%1936", "Full Token (Admin)", - TokenElevationType="%%1937", "Elevated", - TokenElevationType="%%1938", "Limited", - 1=1, "Unknown" - ) + TokenElevationType="%%1936", "Full Token (Admin)", + TokenElevationType="%%1937", "Elevated", + TokenElevationType="%%1938", "Limited", + 1=1, "Unknown") | eval ProcessChain=ParentProcessName + " -> " + NewProcessName | table _time host Framework SubjectUserName SubjectDomainName SubjectLogonId IntegrityLevel Elevation ProcessChain CommandLine NewProcessId ProcessId | sort -_time - | dedup ProcessChain | `suspicious_local_llm_framework_process_execution_filter` + | dedup ProcessChain + | `suspicious_local_llm_framework_process_execution_filter` how_to_implement: Ensure Windows Security Event Log collection (Event ID 4688 - Process Creation) is enabled and ingested into Splunk. Configure your Windows systems to audit process creation via Group Policy (Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking > Audit Process Creation). Verify the `wineventlog_security` macro exists in your Splunk environment and points to the correct index. The detection uses `spath` to parse XML EventData fields from Windows Security logs; ensure your Splunk forwarder or Windows Event Log Input app correctly normalizes these fields. Create or update the `suspicious_local_llm_framework_process_execution_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence (e.g., every 4 hours) to detect unauthorized LLM framework execution. Alert on deviations from baseline process chains and integrity/elevation levels for your environment. known_false_positives: Legitimate development, data science, and AI/ML workflows where authorized developers, researchers, or engineers intentionally execute local LLM frameworks (Ollama, LM Studio, GPT4All, Jan) for model experimentation, fine-tuning, or prototyping. Approved sandbox and lab environments where framework testing is authorized. Open-source contributors and hobbyists running frameworks for educational purposes or community projects. Third-party applications that bundle or invoke LLM frameworks as dependencies (e.g., IDE plugins, analytics tools, chatbot integrations). System administrators deploying frameworks as part of containerized services or orchestrated ML workloads. Process name keyword overlap with unrelated utilities (e.g., "llama-backup", "janimation", "gpt4-config"). Recommended tuning — baseline approved frameworks and users by role/department, exclude sanctioned dev/lab systems, correlate with user identity and peer group anomalies before escalating to incident response. references: From e238ef6fe36f1faf4229fb4ba0e5efe050ae1e81 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 22:41:53 -0500 Subject: [PATCH 17/26] fixedhowtoimplement --- .../suspicious_local_llm_framework_process_execution.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml index fff3dc5b34..3aa86ffc37 100644 --- a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml +++ b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml @@ -42,7 +42,7 @@ search: | | sort -_time | dedup ProcessChain | `suspicious_local_llm_framework_process_execution_filter` -how_to_implement: Ensure Windows Security Event Log collection (Event ID 4688 - Process Creation) is enabled and ingested into Splunk. Configure your Windows systems to audit process creation via Group Policy (Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking > Audit Process Creation). Verify the `wineventlog_security` macro exists in your Splunk environment and points to the correct index. The detection uses `spath` to parse XML EventData fields from Windows Security logs; ensure your Splunk forwarder or Windows Event Log Input app correctly normalizes these fields. Create or update the `suspicious_local_llm_framework_process_execution_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence (e.g., every 4 hours) to detect unauthorized LLM framework execution. Alert on deviations from baseline process chains and integrity/elevation levels for your environment. +how_to_implement: Ensure Windows Security Event Log collection (Event ID 4688 - Process Creation) is enabled and ingested into Splunk. Configure your Windows systems to audit process creation via Group Policy (Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking > Audit Process Creation). Verify the `wineventlog_security` macro exists in your Splunk environment and points to the correct index. Ensure your Splunk forwarder or Windows Event Log Input app correctly normalizes these fields. Create or update the `suspicious_local_llm_framework_process_execution_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution. Alert on deviations from baseline process chains and integrity/elevation levels for your environment. known_false_positives: Legitimate development, data science, and AI/ML workflows where authorized developers, researchers, or engineers intentionally execute local LLM frameworks (Ollama, LM Studio, GPT4All, Jan) for model experimentation, fine-tuning, or prototyping. Approved sandbox and lab environments where framework testing is authorized. Open-source contributors and hobbyists running frameworks for educational purposes or community projects. Third-party applications that bundle or invoke LLM frameworks as dependencies (e.g., IDE plugins, analytics tools, chatbot integrations). System administrators deploying frameworks as part of containerized services or orchestrated ML workloads. Process name keyword overlap with unrelated utilities (e.g., "llama-backup", "janimation", "gpt4-config"). Recommended tuning — baseline approved frameworks and users by role/department, exclude sanctioned dev/lab systems, correlate with user identity and peer group anomalies before escalating to incident response. references: - https://splunkbase.splunk.com/app/8024 From 6ecbaaad1282022a45974595dd6729970295be42 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 22:47:50 -0500 Subject: [PATCH 18/26] fixhowtoimp --- .../unauthorized_llm_model_file_creation_on_endpoint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml b/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml index 811cd2c1f4..6f0232c255 100644 --- a/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml +++ b/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml @@ -16,7 +16,7 @@ search: | | search TargetFilename="*.gguf*" OR TargetFilename="*ggml*" OR TargetFilename="*safetensors*" OR TargetFilename="*Modelfile*" | table _time, host, Image, TargetFilename | `unauthorized_llm_model_file_creation_on_endpoint_filter` -how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation events (Event ID 1). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution and shadow AI deployments. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. +how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation events (Event ID 11). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution and shadow AI deployments. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. known_false_positives: Legitimate creation of LLM model files by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where model file creation is expected. Automated ML pipelines and workflows that generate or update model files as part of their normal operation. Third-party applications and services that manage or cache LLM model files for legitimate purposes. references: - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon From 6fbb3ba56fa13a717957b0f6d02fa4de70d0df17 Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 22:51:27 -0500 Subject: [PATCH 19/26] fixdescription --- .../endpoint/windows_execution_of_local_llm_framework.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/windows_execution_of_local_llm_framework.yml b/detections/endpoint/windows_execution_of_local_llm_framework.yml index dd91c0e61d..4a66c1a0de 100644 --- a/detections/endpoint/windows_execution_of_local_llm_framework.yml +++ b/detections/endpoint/windows_execution_of_local_llm_framework.yml @@ -46,7 +46,7 @@ search: | | stats count by host, Framework, EventCode, ParentProcessName, NewProcessName, SubjectUserName | sort host, Framework, -count | `windows_execution_of_local_llm_framework_filter` -how_to_implement: Enable Windows Security Event Log auditing for Process Creation (Event ID 4688) across Windows endpoints via Group Policy. Ensure the Audit Process Creation policy is enabled under Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking. Additionally, enable command-line process auditing by configuring the Include command line in process creation events policy under Computer Configuration > Administrative Templates > System > Audit Process Creation. Ingest Windows Security Event Logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with sourcetype=WinEventLog Security or XmlWinEventLog Security. Install and configure the Splunk Add-on for Microsoft Windows (TA-microsoft-windows) to ensure proper field extractions for NewProcessName, ParentProcessName, CommandLine, SubjectUserName, and Computer fields. Verify the wineventlog_security macro exists in your Splunk environment and correctly references the Windows Security event logs. Create or update the windows_execution_of_local_llm_framework_filter macro in your detections/filters folder to exclude approved development environments, authorized ML/AI workstations, sanctioned frameworks, or known safe systems. Deploy this hunting search as a scheduled saved search in Splunk Enterprise Security or Splunk Cloud to run on a regular cadence (recommended every 30-60 minutes). Tune the detection by adding new framework process names and command-line patterns as emerging LLM tools are identified. +how_to_implement: Enable Windows Security Event Log auditing for Process Creation (Event ID 4688) across Windows endpoints via Group Policy. Ensure the Audit Process Creation policy is enabled under Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking. Additionally, enable command-line process auditing by configuring the Include command line in process creation events policy under Computer Configuration > Administrative Templates > System > Audit Process Creation. Ingest Windows Security Event Logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with sourcetype=WinEventLog Security or XmlWinEventLog Security. Install and configure the Splunk Add-on for Microsoft Windows (TA-microsoft-windows) to ensure proper field extractions for NewProcessName, ParentProcessName, CommandLine, SubjectUserName, and Computer fields. Verify the wineventlog_security macro exists in your Splunk environment and correctly references the Windows Security event logs. Create or update the windows_execution_of_local_llm_framework_filter macro in your detections/filters folder to exclude approved development environments, authorized ML/AI workstations, sanctioned frameworks, or known safe systems. Deploy this hunting search as a scheduled saved search in Splunk Enterprise Security or Splunk Cloud to run on a regular cadence. Tune the detection by adding new framework process names and command-line patterns as emerging LLM tools are identified. known_false_positives: Legitimate development and data science workflows where developers, ML engineers, and researchers install and run local LLM frameworks for experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments, open-source and educational use cases, third-party software bundling HuggingFace/Transformers/LangChain libraries as dependencies, and system administrators deploying frameworks as part of containerized services. Parent process and command-line keyword overlap with unrelated tools (e.g., "llama-backup", tools using "--transformers" flags for non-LLM purposes). Recommended tuning — baseline approved frameworks and users, exclude sanctioned development/lab systems, require additional context (user role, peer group, model artifacts, network exfiltration signals) before escalating to incidents. references: - https://splunkbase.splunk.com/app/8024 From 7fd819051361b24ad8c15c1fa7465ca1d56a61da Mon Sep 17 00:00:00 2001 From: Rod Soto Date: Tue, 18 Nov 2025 22:55:48 -0500 Subject: [PATCH 20/26] moredetails --- stories/suspicious_local_llm_frameworks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stories/suspicious_local_llm_frameworks.yml b/stories/suspicious_local_llm_frameworks.yml index e0cc2c17e9..18db7128e3 100644 --- a/stories/suspicious_local_llm_frameworks.yml +++ b/stories/suspicious_local_llm_frameworks.yml @@ -5,7 +5,7 @@ date: '2025-11-12' author: Rod Soto, Splunk status: production description: Leverage advanced Splunk searches to detect and investigate suspicious activities targeting possibly unauthorized local LLM frameworks. This analytic story addresses discovery and detection of unauthorized local llm frameworks and related shadow AI artifacts. -narrative: Detect and triage unauthorized local LLM frameworks (shadow AI) to prevent covert model manipulation, data exfiltration, and persistent behavioral changes. +narrative: This analytic story addresses the growing security challenge of Shadow AI - the deployment and use of unauthorized Large Language Model (LLM) frameworks and AI tools within enterprise environments without proper governance, oversight, or security controls. Shadow AI deployments pose significant risks including data exfiltration through local model inference (where sensitive corporate data is processed by unmonitored AI systems), intellectual property leakage, policy violations, and creation of security blind spots that bypass enterprise data loss prevention and monitoring solutions. Local LLM frameworks such as Ollama, LM Studio, GPT4All, Jan, llama.cpp, and KoboldCPP enable users to download and run powerful language models entirely on their endpoints, processing sensitive information without cloud-based safeguards or enterprise visibility. These detections monitor process execution patterns, file creation activities (model files with .gguf, .ggml, safetensors extensions), DNS queries to model repositories, and network connections to identify unauthorized AI infrastructure. By correlating Windows Security Event Logs (Event ID 4688), Sysmon telemetry (Events 1, 11, 22), and behavioral indicators, security teams can detect shadow AI deployments early, investigate the scope of unauthorized model usage, assess data exposure risks, and enforce AI governance policies to prevent covert model manipulation, persistent endpoint compromise, and uncontrolled AI experimentation that bypasses established security frameworks. references: - https://splunkbase.splunk.com/app/8024 - https://www.ibm.com/think/topics/shadow-ai From 099db8567c86b8569262d2638233bdb41a471338 Mon Sep 17 00:00:00 2001 From: Nasreddine Bencherchali Date: Fri, 21 Nov 2025 00:45:45 +0100 Subject: [PATCH 21/26] update detections --- .../endpoint/llm_model_file_creation.yml | 77 +++++++++ .../local_llm_framework_dns_query.yml | 90 ++++++++++ ...work_download_and_execution_via_sysmon.yml | 67 ------- ...spicious_local_llm_framework_execution.yml | 163 ++++++++++++++++++ ..._local_llm_framework_process_execution.yml | 82 --------- ...ed_llm_model_file_creation_on_endpoint.yml | 56 ------ ...unauthorized_local_llm_framework_usage.yml | 78 --------- ...ndows_execution_of_local_llm_framework.yml | 86 --------- stories/suspicious_local_llm_frameworks.yml | 32 ++-- 9 files changed, 350 insertions(+), 381 deletions(-) create mode 100644 detections/endpoint/llm_model_file_creation.yml create mode 100644 detections/endpoint/local_llm_framework_dns_query.yml delete mode 100644 detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml create mode 100644 detections/endpoint/suspicious_local_llm_framework_execution.yml delete mode 100644 detections/endpoint/suspicious_local_llm_framework_process_execution.yml delete mode 100644 detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml delete mode 100644 detections/endpoint/unauthorized_local_llm_framework_usage.yml delete mode 100644 detections/endpoint/windows_execution_of_local_llm_framework.yml diff --git a/detections/endpoint/llm_model_file_creation.yml b/detections/endpoint/llm_model_file_creation.yml new file mode 100644 index 0000000000..1ff42203f3 --- /dev/null +++ b/detections/endpoint/llm_model_file_creation.yml @@ -0,0 +1,77 @@ +name: LLM Model File Creation +id: 23e5b797-378d-45d6-ab3e-d034ca12a99b +version: 1 +date: '2025-11-12' +author: Rod Soto +status: production +type: Hunting +description: | + Detects the creation of Large Language Model (LLM) files on Windows endpoints by monitoring file creation events for specific model file formats and extensions commonly used by local AI frameworks. + This detection identifies potential shadow AI deployments, unauthorized model downloads, and rogue LLM infrastructure by detecting file creation patterns associated with quantized models (.gguf, .ggml), safetensors model format files, and Ollama Modelfiles. + These file types are characteristic of local inference frameworks such as Ollama, llama.cpp, GPT4All, LM Studio, and similar tools that enable running LLMs locally without cloud dependencies. + Organizations can use this detection to identify potential data exfiltration risks, policy violations related to unapproved AI usage, and security blind spots created by decentralized AI deployments that bypass enterprise governance and monitoring. +data_source: + - Sysmon EventID 11 +search: | + | tstats `security_content_summariesonly` count + min(_time) as firstTime + max(_time) as lastTime + from datamodel=Endpoint.Filesystem + where Filesystem.file_name IN ( + "*.gguf*", + "*ggml*", + "*Modelfile*", + "*safetensors*" + ) + by Filesystem.action Filesystem.dest Filesystem.file_access_time Filesystem.file_create_time + Filesystem.file_hash Filesystem.file_modify_time Filesystem.file_name Filesystem.file_path + Filesystem.file_acl Filesystem.file_size Filesystem.process_guid Filesystem.process_id + Filesystem.user Filesystem.vendor_product + | `drop_dm_object_name(Filesystem)` + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `llm_model_file_creation_filter` +how_to_implement: | + To successfully implement this search, you need to be ingesting logs with file creation events from your endpoints. + Ensure that the Endpoint data model is properly populated with filesystem events from EDR agents or Sysmon Event ID 11. + The logs must be processed using the appropriate Splunk Technology Add-ons that are specific to the EDR product. + The logs must also be mapped to the `Filesystem` node of the `Endpoint` data model. + Use the Splunk Common Information Model (CIM) to normalize the field names and speed up the data modeling process. +known_false_positives: | + Legitimate creation of LLM model files by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where model file creation is expected. Automated ML pipelines and workflows that generate or update model files as part of their normal operation. Third-party applications and services that manage or cache LLM model files for legitimate purposes. +references: + - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon + - https://www.ibm.com/think/topics/shadow-ai + - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html + - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +tags: + analytic_story: + - Suspicious Local LLM Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1543 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +drilldown_searches: + - name: View the detection results for - "$host$" + search: '%original_detection_search% | search host="$host$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ + - name: View risk events for the last 7 days for - "$host$" + search: | + | from datamodel Risk.All_Risk + | search normalized_risk_object="$host$" starthoursago=168 + | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tests: + - name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational \ No newline at end of file diff --git a/detections/endpoint/local_llm_framework_dns_query.yml b/detections/endpoint/local_llm_framework_dns_query.yml new file mode 100644 index 0000000000..acb7ea7479 --- /dev/null +++ b/detections/endpoint/local_llm_framework_dns_query.yml @@ -0,0 +1,90 @@ +name: Local LLM Framework DNS Query +id: d7ceffc5-a45e-412b-b9fa-2ba27c284503 +version: 1 +date: '2025-11-12' +author: Rod Soto +status: production +type: Hunting +description: | + Detects DNS queries related to local LLM models on endpoints by monitoring Sysmon DNS query events (Event ID 22) for known LLM model domains and services. + Local LLM frameworks like Ollama, LM Studio, and GPT4All make DNS calls to repositories such as huggingface.co and ollama.ai for model downloads, updates, and telemetry. + These queries can reveal unauthorized AI tool usage or data exfiltration risks on corporate networks. +data_source: + - Sysmon EventID 22 +search: | + `sysmon` + EventID=22 + query IN ( + "*huggingface*", + "*ollama*", + "*jan.ai*", + "*gpt4all*", + "*nomic*", + "*koboldai*", + "*lmstudio*", + "*modelscope*", + "*civitai*", + "*github.com*llama*", + "*github.com*oobabooga*", + "*github.com*koboldai*", + "*replicate*", + "*anthropic*", + "*openai*", + "*openrouter*", + "*api.openrouter*", + "*aliyun*", + "*alibabacloud*", + "*dashscope.aliyuncs*" + ) + NOT Image IN ( + "*\\MsMpEng.exe", + "C:\\ProgramData\\*", + "C:\\Windows\\System32\\*", + "C:\\Windows\\SysWOW64\\*" + ) + | stats count + min(_time) as firstTime + max(_time) as lastTime + by src dest Image query query_count answer answer_count reply_code_id vendor_product + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `local_llm_framework_dns_query_filter` +how_to_implement: | + Ensure Sysmon is deployed across Windows endpoints and configured to capture DNS query events (Event ID 22). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `unauthorized_local_llm_framework_usage_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM model DNS queries and shadow AI activities. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. +known_false_positives: | + Legitimate DNS queries to LLM model hosting platforms by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where LLM model downloads are expected. Automated ML pipelines and workflows that interact with LLM model hosting services as part of their normal operation. Third-party applications and services that access LLM model platforms for legitimate purposes. +references: + - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon + - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html + - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +drilldown_searches: + - name: View the detection results for - "$host$" + search: '%original_detection_search% | search host="$host$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ + - name: View risk events for the last 7 days for - "$host$" + search: | + | from datamodel Risk.All_Risk + | search normalized_risk_object="$host$" starthoursago=168 + | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - Suspicious Local LLM Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1590 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational diff --git a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml b/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml deleted file mode 100644 index e60f7ec4c2..0000000000 --- a/detections/endpoint/suspicious_local_llm_framework_download_and_execution_via_sysmon.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Suspicious Local LLM Framework Download and Execution via Sysmon -id: e27da0be-838a-40f2-bd4c-2dac4e7f6031 -version: 1 -date: '2025-11-12' -author: Rod Soto -status: production -type: Hunting -description: Detects execution of local LLM frameworks on Windows endpoints by monitoring Sysmon process creation events (Event ID 1) for known LLM tools including Ollama, GPT4All, LM Studio, Jan, llama.cpp, KoboldCPP, and Oobabooga. This hunting detection identifies shadow AI deployments and unauthorized local model inference operations by analyzing process execution patterns of LLM frameworks. -data_source: -- Sysmon EventID 1 -search: | - `sysmon` | spath - | eval EventID='Event.System.EventID' - | eval host='Event.System.Computer' - | eval Image=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$")) - | eval TargetFilename=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^TargetFilename$")) - | eval QueryName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^QueryName$")) - | search ( Image="*ollama*" OR Image="*gpt4all*" OR Image="*lmstudio*" OR Image="*kobold*" OR Image="*jan*" OR Image="*llama-run*" OR Image="*llama.cpp*" OR Image="*oobabooga*" OR Image="*text-generation-webui*" OR TargetFilename="*.gguf*" OR TargetFilename="*ollama*" OR TargetFilename="*jan*" OR QueryName="*huggingface.co*" OR QueryName="*ollama.com*" ) - | search Image!="*MsMpEng*" AND Image!="*defender*" AND Image!="*windows/system32*" AND Image!="*syswow64*" AND Image!="*winlogon*" AND Image!="*svchost*" - | eval Framework=case( - match(Image, "(?i)ollama") OR match(TargetFilename, "(?i)ollama") OR match(QueryName, "(?i)ollama"), "Ollama", - match(Image, "(?i)lmstudio") OR match(Image, "(?i)lm-studio") OR match(TargetFilename, "(?i)lmstudio"), "LMStudio", - match(Image, "(?i)gpt4all") OR match(TargetFilename, "(?i)gpt4all"), "GPT4All", - match(Image, "(?i)kobold"), "KoboldCPP", - match(Image, "(?i)jan") OR match(TargetFilename, "(?i)jan"), "Jan AI", - match(Image, "(?i)llama-run") OR match(Image, "(?i)llama-b") OR match(Image, "(?i)llama.cpp"), "llama.cpp", - match(Image, "(?i)oobabooga") OR match(Image, "(?i)text-generation-webui"), "Oobabooga", - 1=1, "Other" - ) - | search Framework!="Other" | stats count by Framework, host, Image | sort -count | `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` -how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation events (Event ID 1). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution and shadow AI deployments. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. -known_false_positives: Legitimate creation of LLM model files by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where model file creation is expected. Automated ML pipelines and workflows that generate or update model files as part of their normal operation. Third-party applications and services that manage or cache LLM model files for legitimate purposes. -references: -- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon -- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html -- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama -tags: - analytic_story: - - Suspicious Local Llm Frameworks - asset_type: Endpoint - mitre_attack_id: - - T1543 - product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - security_domain: endpoint -drilldown_searches: -- name: View the detection results for - "$host$" - search: '%original_detection_search% | search host="$host$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -- name: View risk events for the last 7 days for - "$host$" - search: | - | from datamodel Risk.All_Risk - | search normalized_risk_object="$host$" starthoursago=168 - | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -tests: -- name: True Positive Test - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt - sourcetype: XmlWinEventLog - source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational diff --git a/detections/endpoint/suspicious_local_llm_framework_execution.yml b/detections/endpoint/suspicious_local_llm_framework_execution.yml new file mode 100644 index 0000000000..38dbc941bb --- /dev/null +++ b/detections/endpoint/suspicious_local_llm_framework_execution.yml @@ -0,0 +1,163 @@ +name: Local LLM Framework Execution +id: a3f8e2c9-7d4b-4e1f-9c6a-2b5d8f3e1a7c +version: 1 +date: '2025-11-20' +author: Rod Soto, Splunk +status: production +type: Hunting +description: | + The following analytic detects execution of unauthorized local LLM frameworks (Ollama, LM Studio, GPT4All, Jan, llama.cpp, KoboldCPP, Oobabooga, NutStudio) and Python-based AI/ML libraries (HuggingFace Transformers, LangChain) on Windows endpoints by leveraging process creation events. + It identifies cases where known LLM framework executables are launched or command-line arguments reference AI/ML libraries. + This activity is significant as it may indicate shadow AI deployments, unauthorized model inference operations, or potential data exfiltration through local AI systems. + If confirmed malicious, this could lead to unauthorized access to sensitive data, intellectual property theft, or circumvention of organizational AI governance policies. +data_source: + - Sysmon EventID 1 + - Windows Event Log Security 4688 + - CrowdStrike ProcessRollup2 +search: | + | tstats `security_content_summariesonly` count + min(_time) as firstTime + max(_time) as lastTime + from datamodel=Endpoint.Processes + where + Processes.process_name IN ( + "gpt4all.exe", + "jan.exe", + "kobold.exe", + "koboldcpp.exe", + "llama-run.exe", + "llama.cpp.exe", + "lmstudio.exe", + "nutstudio.exe", + "ollama.exe", + "oobabooga.exe", + "text-generation-webui.exe" + ) + OR Processes.original_file_name IN ( + "ollama.exe", + "lmstudio.exe", + "gpt4all.exe", + "jan.exe", + "llama-run.exe", + "koboldcpp.exe", + "nutstudio.exe" + ) + OR Processes.process IN ( + "*\\gpt4all\\*", + "*\\jan\\*", + "*\\koboldcpp\\*", + "*\\llama.cpp\\*", + "*\\lmstudio\\*", + "*\\nutstudio\\*", + "*\\ollama\\*", + "*\\oobabooga\\*", + "*huggingface*", + "*langchain*", + "*llama-run*", + "*transformers*" + ) + OR + Processes.parent_process_name IN ( + "gpt4all.exe", + "jan.exe", + "kobold.exe", + "koboldcpp.exe", + "llama-run.exe", + "llama.cpp.exe", + "lmstudio.exe", + "nutstudio.exe", + "ollama.exe", + "oobabooga.exe", + "text-generation-webui.exe" + ) + + by Processes.action Processes.dest Processes.original_file_name Processes.parent_process + Processes.parent_process_exec Processes.parent_process_guid Processes.parent_process_id + Processes.parent_process_name Processes.parent_process_path Processes.process + Processes.process_exec Processes.process_guid Processes.process_hash Processes.process_id + Processes.process_integrity_level Processes.process_name Processes.process_path Processes.user + Processes.user_id Processes.vendor_product + + | `drop_dm_object_name(Processes)` + | eval Framework=case( + match(process_name, "(?i)ollama") OR match(process, "(?i)ollama"), "Ollama", + match(process_name, "(?i)lmstudio") OR match(process, "(?i)lmstudio") OR match(process, "(?i)lm-studio"), "LM Studio", + match(process_name, "(?i)gpt4all") OR match(process, "(?i)gpt4all"), "GPT4All", + match(process_name, "(?i)kobold") OR match(process, "(?i)kobold"), "KoboldCPP", + match(process_name, "(?i)jan") OR match(process, "(?i)jan"), "Jan AI", + match(process_name, "(?i)nutstudio") OR match(process, "(?i)nutstudio"), "NutStudio", + match(process_name, "(?i)llama") OR match(process, "(?i)llama"), "llama.cpp", + match(process_name, "(?i)oobabooga") OR match(process, "(?i)oobabooga") OR match(process, "(?i)text-generation-webui"), "Oobabooga", + match(process, "(?i)transformers") OR match(process, "(?i)huggingface"), "HuggingFace/Transformers", + match(process, "(?i)langchain"), "LangChain", + 1=1, "Other" + ) + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `suspicious_local_llm_framework_execution_filter`' +how_to_implement: | + The detection is based on data that originates from Endpoint Detection + and Response (EDR) agents. These agents are designed to provide security-related + telemetry from the endpoints where the agent is installed. To implement this search, + you must ingest logs that contain the process GUID, process name, and parent process. + Additionally, you must ingest complete command-line executions. These logs must + be processed using the appropriate Splunk Technology Add-ons that are specific to + the EDR product. The logs must also be mapped to the `Processes` node of the `Endpoint` + data model. Use the Splunk Common Information Model (CIM) to normalize the field + names and speed up the data modeling process. +known_false_positives: Legitimate development, data science, and AI/ML workflows where + authorized developers, researchers, or engineers intentionally execute local LLM + frameworks (Ollama, LM Studio, GPT4All, Jan, NutStudio) for model experimentation, + fine-tuning, or prototyping. Python developers using HuggingFace Transformers or + LangChain for legitimate AI/ML projects. Approved sandbox and lab environments where + framework testing is authorized. Open-source contributors and hobbyists running + frameworks for educational purposes. Third-party applications that bundle or invoke + LLM frameworks as dependencies (e.g., IDE plugins, analytics tools, chatbot integrations). + System administrators deploying frameworks as part of containerized services or + orchestrated ML workloads. Process name keyword overlap with unrelated utilities + (e.g., "llama-backup", "janimation"). Recommended tuning — baseline approved frameworks + and users by role/department, exclude sanctioned dev/lab systems via the filter + macro, correlate with user identity and peer group anomalies before escalating to + incident response. +references: +- https://splunkbase.splunk.com/app/8024 +- https://www.ibm.com/think/topics/shadow-ai +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama +- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon +drilldown_searches: +- name: View the detection results for "$dest$" + search: '%original_detection_search% | search dest="$dest$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for "$dest$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object="$dest$" + starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime + values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) + as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) + as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - Suspicious Local LLM Frameworks + asset_type: Endpoint + mitre_attack_id: + - T1543 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +tests: + - name: True Positive Test - Sysmon + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog + - name: True Positive Test - Windows Event Log Security + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt + sourcetype: XmlWinEventLog + source: XmlWinEventLog:Security diff --git a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml b/detections/endpoint/suspicious_local_llm_framework_process_execution.yml deleted file mode 100644 index 3aa86ffc37..0000000000 --- a/detections/endpoint/suspicious_local_llm_framework_process_execution.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Suspicious Local LLM Framework Process Execution -id: 0ba9df5a-017c-4651-bb47-3764b06ddf28 -version: 1 -date: '2025-11-12' -author: Rod Soto -status: production -type: Hunting -description: Detects execution of unauthorized local LLM frameworks (Ollama, LM Studio, NutStudio, GPT4All, Jan, Llama-Run) on Windows endpoints by monitoring Event ID 4688 process creation events. Correlates process names and parent processes to identify shadow AI deployments, classifies integrity levels and elevation types, and surfaces process chains for investigation of potential unauthorized model inference or data exfiltration. -data_source: -- Windows Event Log Security 4688 -search: | - `wineventlog_security` EventCode=4688 - (NewProcessName="*ollama*" OR NewProcessName="*lmstudio*" OR - NewProcessName="*nutstudio*" OR NewProcessName="*gpt4all*" OR - NewProcessName="*jan*" OR NewProcessName="*llama-run*" OR - ParentProcessName="*ollama*" OR ParentProcessName="*lmstudio*" OR - ParentProcessName="*nutstudio*" OR ParentProcessName="*gpt4all*" OR - ParentProcessName="*jan*" OR ParentProcessName="*llama-run*") - | eval host=Computer - | eval Framework=case( - like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", - like(NewProcessName, "%lmstudio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", - like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%"), "NutStudio", - like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", - like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%"), "Jan", - like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%"), "Llama-Run", - 1=1, "Other") - | eval IntegrityLevel=case( - MandatoryLabel="S-1-16-16384", "System", - MandatoryLabel="S-1-16-12288", "High", - MandatoryLabel="S-1-16-8192", "Medium", - MandatoryLabel="S-1-16-4096", "Low", - MandatoryLabel="S-1-16-0", "Untrusted", - 1=1, "Unknown") - | eval Elevation=case( - TokenElevationType="%%1936", "Full Token (Admin)", - TokenElevationType="%%1937", "Elevated", - TokenElevationType="%%1938", "Limited", - 1=1, "Unknown") - | eval ProcessChain=ParentProcessName + " -> " + NewProcessName - | table _time host Framework SubjectUserName SubjectDomainName SubjectLogonId IntegrityLevel Elevation ProcessChain CommandLine NewProcessId ProcessId - | sort -_time - | dedup ProcessChain - | `suspicious_local_llm_framework_process_execution_filter` -how_to_implement: Ensure Windows Security Event Log collection (Event ID 4688 - Process Creation) is enabled and ingested into Splunk. Configure your Windows systems to audit process creation via Group Policy (Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking > Audit Process Creation). Verify the `wineventlog_security` macro exists in your Splunk environment and points to the correct index. Ensure your Splunk forwarder or Windows Event Log Input app correctly normalizes these fields. Create or update the `suspicious_local_llm_framework_process_execution_filter` macro in your detections/filters folder to exclude approved systems, users, or frameworks as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution. Alert on deviations from baseline process chains and integrity/elevation levels for your environment. -known_false_positives: Legitimate development, data science, and AI/ML workflows where authorized developers, researchers, or engineers intentionally execute local LLM frameworks (Ollama, LM Studio, GPT4All, Jan) for model experimentation, fine-tuning, or prototyping. Approved sandbox and lab environments where framework testing is authorized. Open-source contributors and hobbyists running frameworks for educational purposes or community projects. Third-party applications that bundle or invoke LLM frameworks as dependencies (e.g., IDE plugins, analytics tools, chatbot integrations). System administrators deploying frameworks as part of containerized services or orchestrated ML workloads. Process name keyword overlap with unrelated utilities (e.g., "llama-backup", "janimation", "gpt4-config"). Recommended tuning — baseline approved frameworks and users by role/department, exclude sanctioned dev/lab systems, correlate with user identity and peer group anomalies before escalating to incident response. -references: -- https://splunkbase.splunk.com/app/8024 -- https://www.ibm.com/think/topics/shadow-ai -- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html -- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama -drilldown_searches: -- name: View the detection results for - "$host$" - search: '%original_detection_search% | search host="$host$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -- name: View risk events for the last 7 days for - "$host$" - search: | - | from datamodel Risk.All_Risk - | search normalized_risk_object="$host$" starthoursago=168 - | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -tags: - analytic_story: - - Suspicious Local Llm Frameworks - asset_type: Endpoint - mitre_attack_id: - - T1543 - product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - security_domain: endpoint -tests: -- name: True Positive Test - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt - sourcetype: XmlWinEventLog - source: XmlWinEventLog:Security diff --git a/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml b/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml deleted file mode 100644 index 6f0232c255..0000000000 --- a/detections/endpoint/unauthorized_llm_model_file_creation_on_endpoint.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Unauthorized LLM Model File Creation on Endpoint -id: 23e5b797-378d-45d6-ab3e-d034ca12a99b -version: 1 -date: '2025-11-12' -author: Rod Soto -status: production -type: Hunting -description: Detects unauthorized creation of Large Language Model (LLM) files on Windows endpoints by monitoring Sysmon Event ID 11 (File Creation) for specific model file formats and extensions commonly used by local AI frameworks. This detection identifies shadow AI deployments, unauthorized model downloads, and rogue LLM infrastructure by detecting file creation patterns associated with quantized models (.gguf, .ggml), safetensors model format files, and Ollama Modelfiles. These file types are characteristic of local inference frameworks such as Ollama, llama.cpp, GPT4All, LM Studio, and similar tools that enable running LLMs locally without cloud dependencies. Organizations can use this detection to identify potential data exfiltration risks, policy violations related to unapproved AI usage, and security blind spots created by decentralized AI deployments that bypass enterprise governance and monitoring. -data_source: -- Sysmon EventID 11 -search: | - `sysmon`| spath - | search Event.System.EventID=11 - | eval host='Event.System.Computer' | eval TargetFilename=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^TargetFilename$")) - | eval Image=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$")) - | search TargetFilename="*.gguf*" OR TargetFilename="*ggml*" OR TargetFilename="*safetensors*" OR TargetFilename="*Modelfile*" - | table _time, host, Image, TargetFilename - | `unauthorized_llm_model_file_creation_on_endpoint_filter` -how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture process creation events (Event ID 11). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `suspicious_local_llm_framework_download_and_execution_via_sysmon_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM framework execution and shadow AI deployments. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. -known_false_positives: Legitimate creation of LLM model files by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where model file creation is expected. Automated ML pipelines and workflows that generate or update model files as part of their normal operation. Third-party applications and services that manage or cache LLM model files for legitimate purposes. -references: -- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon -- https://www.ibm.com/think/topics/shadow-ai -- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html -- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama -tags: - analytic_story: - - Suspicious Local Llm Frameworks - asset_type: Endpoint - mitre_attack_id: - - T1543 - product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - security_domain: endpoint -drilldown_searches: -- name: View the detection results for - "$host$" - search: '%original_detection_search% | search host="$host$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -- name: View risk events for the last 7 days for - "$host$" - search: | - | from datamodel Risk.All_Risk - | search normalized_risk_object="$host$" starthoursago=168 - | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -tests: -- name: True Positive Test - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt - sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational - source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational \ No newline at end of file diff --git a/detections/endpoint/unauthorized_local_llm_framework_usage.yml b/detections/endpoint/unauthorized_local_llm_framework_usage.yml deleted file mode 100644 index b205e8afc9..0000000000 --- a/detections/endpoint/unauthorized_local_llm_framework_usage.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Unauthorized Local LLM Framework Usage -id: d7ceffc5-a45e-412b-b9fa-2ba27c284503 -version: 1 -date: '2025-11-12' -author: Rod Soto -status: production -type: Hunting -description: Detects DNS queries related to local LLM models on endpoints by monitoring Sysmon DNS query events (Event ID 22) for known LLM model domains and services. Local LLM frameworks like Ollama, LM Studio, and GPT4All make DNS calls to repositories such as huggingface.co and ollama.ai for model downloads, updates, and telemetry. These queries can reveal unauthorized AI tool usage or data exfiltration risks on corporate networks. -data_source: -- Sysmon EventID 22 -search: | - `sysmon` | spath - | search Event.System.EventID=22 - | eval host='Event.System.Computer' - | eval QueryName=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^QueryName$")) - | eval Image=mvindex('Event.EventData.Data', mvfind('Event.EventData.Data{@Name}', "^Image$")) - | search QueryName="*huggingface*" OR - QueryName="*ollama*" OR - QueryName="*jan.ai*" OR - QueryName="*gpt4all*" OR - QueryName="*nomic*" OR - QueryName="*koboldai*" OR - QueryName="*lmstudio*" OR - QueryName="*modelscope*" OR - QueryName="*civitai*" OR - QueryName="*github.com*llama*" OR - QueryName="*github.com*oobabooga*" OR - QueryName="*github.com*koboldai*" OR - QueryName="*replicate*" OR - QueryName="*anthropic*" OR - QueryName="*openai*" OR - QueryName="*openrouter*" OR - QueryName="*api.openrouter*" OR - QueryName="*aliyun*" OR - QueryName="*alibabacloud*" OR - QueryName="*dashscope.aliyuncs*" - | search Image!="*MsMpEng.exe*" AND Image!="*Windows Defender*" AND Image!="*system32*" AND Image!="*ProgramData*" AND Image!="*syswow64*" - | stats count min(_time) as firstTime max(_time) as lastTime by host, Image, QueryName - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - | `unauthorized_local_llm_framework_usage_filter` -how_to_implement: Ensure Sysmon is deployed across Windows endpoints and configured to capture DNS query events (Event ID 22). Configure Sysmon's XML configuration file to log detailed command-line arguments, parent process information, and full process image paths. Ingest Sysmon event logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with `sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational`. Verify the `sysmon` macro exists in your Splunk environment and correctly references the Sysmon event logs. Create or update the `unauthorized_local_llm_framework_usage_filter` macro in your detections/filters folder to exclude approved systems, authorized developers, sanctioned ML/AI workstations, or known development/lab environments as needed. Deploy this hunting search to your Splunk Enterprise Security or Splunk Enterprise instance and schedule it to run on a regular cadence to detect unauthorized LLM model DNS queries and shadow AI activities. Correlate findings with endpoint asset inventory and user identity data to prioritize investigation. -known_false_positives: Legitimate DNS queries to LLM model hosting platforms by authorized developers, ML engineers, and researchers during model training, fine-tuning, or experimentation. Approved AI/ML sandboxes and lab environments where LLM model downloads are expected. Automated ML pipelines and workflows that interact with LLM model hosting services as part of their normal operation. Third-party applications and services that access LLM model platforms for legitimate purposes. -references: -- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon -- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html -- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama -tags: - analytic_story: - - Suspicious Local Llm Frameworks - asset_type: Endpoint - mitre_attack_id: - - T1590 - product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - security_domain: endpoint -drilldown_searches: -- name: View the detection results for - "$host$" - search: '%original_detection_search% | search host="$host$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -- name: View risk events for the last 7 days for - "$host$" - search: | - | from datamodel Risk.All_Risk - | search normalized_risk_object="$host$" starthoursago=168 - | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -tests: -- name: True Positive Test - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt - sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational - source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational diff --git a/detections/endpoint/windows_execution_of_local_llm_framework.yml b/detections/endpoint/windows_execution_of_local_llm_framework.yml deleted file mode 100644 index 4a66c1a0de..0000000000 --- a/detections/endpoint/windows_execution_of_local_llm_framework.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Windows Execution of Local LLM Framework -id: 2397d00a-cfd3-46e1-ba73-dee6d8ba1d0c -version: 1 -date: '2025-11-12' -author: Rod Soto -status: production -type: Hunting -description: Detects execution of local Large Language Model (LLM) frameworks on Windows endpoints by monitoring Windows Security Event Log 4688 (Process Creation) for known LLM tools and AI/ML libraries. This hunting detection identifies shadow AI deployments and unauthorized local model inference operations by analyzing process execution patterns, command-line arguments, and parent process relationships for frameworks including Ollama, LM Studio, GPT4All, Jan, llama.cpp, KoboldCPP, NutStudio, and Python-based libraries such as HuggingFace Transformers and LangChain. The search leverages pre-extracted fields from the Splunk Add-on for Microsoft Windows to classify framework types and correlate process activity with potential security risks including data exfiltration through local AI processing, policy violations from unapproved AI usage, and decentralized AI deployments that bypass enterprise governance. Organizations can use this detection to gain visibility into local LLM infrastructure, identify users downloading or executing AI frameworks outside approved channels, and detect potential intellectual property risks from processing sensitive data through unmonitored local models. -data_source: -- Windows Event Log Security 4688 -search: | - `wineventlog_security` EventCode=4688 - (NewProcessName="*ollama*" OR - NewProcessName="*llama*" OR - NewProcessName="*llama-run*" OR - NewProcessName="*gpt4all*" OR - NewProcessName="*lmstudio*" OR - NewProcessName="*nutstudio*" OR - NewProcessName="*koboldcpp*" OR - NewProcessName="*jan*" OR - NewProcessName="*jan.exe*" OR - CommandLine="*transformers*" OR - CommandLine="*langchain*" OR - CommandLine="*huggingface*" OR - CommandLine="*llama-run*" OR - CommandLine="*nutstudio*" OR - ParentProcessName="*ollama*" OR - ParentProcessName="*lmstudio*" OR - ParentProcessName="*nutstudio*" OR - ParentProcessName="*gpt4all*" OR - ParentProcessName="*jan*" OR - ParentProcessName="*llama-run*") - | eval host=Computer - | eval Framework=case( - like(NewProcessName, "%ollama%") OR like(ParentProcessName, "%ollama%"), "Ollama", - like(NewProcessName, "%lmstudio%") OR like(NewProcessName, "%LM Studio%") OR like(ParentProcessName, "%lmstudio%"), "LM Studio", - like(NewProcessName, "%nutstudio%") OR like(ParentProcessName, "%nutstudio%") OR like(CommandLine, "%nutstudio%"), "NutStudio", - like(NewProcessName, "%gpt4all%") OR like(ParentProcessName, "%gpt4all%"), "GPT4All", - like(NewProcessName, "%jan%") OR like(ParentProcessName, "%jan%") OR like(NewProcessName, "%jan.exe%"), "Jan", - like(NewProcessName, "%koboldcpp%") OR like(CommandLine, "%koboldcpp%"), "KoboldCPP", - like(NewProcessName, "%llama-run%") OR like(ParentProcessName, "%llama-run%") OR like(CommandLine, "%llama-run%"), "Llama-Run", - like(CommandLine, "%transformers%") OR like(CommandLine, "%huggingface%"), "HuggingFace/Transformers", - like(CommandLine, "%langchain%"), "LangChain", - like(NewProcessName, "%llama%") OR like(NewProcessName, "%llama.cpp%") OR like(ParentProcessName, "%llama%"), "Llama.cpp", - 1=1, "Related Activity") - | stats count by host, Framework, EventCode, ParentProcessName, NewProcessName, SubjectUserName - | sort host, Framework, -count - | `windows_execution_of_local_llm_framework_filter` -how_to_implement: Enable Windows Security Event Log auditing for Process Creation (Event ID 4688) across Windows endpoints via Group Policy. Ensure the Audit Process Creation policy is enabled under Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Detailed Tracking. Additionally, enable command-line process auditing by configuring the Include command line in process creation events policy under Computer Configuration > Administrative Templates > System > Audit Process Creation. Ingest Windows Security Event Logs into Splunk via the Splunk Universal Forwarder or Windows Event Log Input, ensuring they are tagged with sourcetype=WinEventLog Security or XmlWinEventLog Security. Install and configure the Splunk Add-on for Microsoft Windows (TA-microsoft-windows) to ensure proper field extractions for NewProcessName, ParentProcessName, CommandLine, SubjectUserName, and Computer fields. Verify the wineventlog_security macro exists in your Splunk environment and correctly references the Windows Security event logs. Create or update the windows_execution_of_local_llm_framework_filter macro in your detections/filters folder to exclude approved development environments, authorized ML/AI workstations, sanctioned frameworks, or known safe systems. Deploy this hunting search as a scheduled saved search in Splunk Enterprise Security or Splunk Cloud to run on a regular cadence. Tune the detection by adding new framework process names and command-line patterns as emerging LLM tools are identified. -known_false_positives: Legitimate development and data science workflows where developers, ML engineers, and researchers install and run local LLM frameworks for experimentation, fine-tuning, or prototyping. Approved AI/ML sandboxes and lab environments, open-source and educational use cases, third-party software bundling HuggingFace/Transformers/LangChain libraries as dependencies, and system administrators deploying frameworks as part of containerized services. Parent process and command-line keyword overlap with unrelated tools (e.g., "llama-backup", tools using "--transformers" flags for non-LLM purposes). Recommended tuning — baseline approved frameworks and users, exclude sanctioned development/lab systems, require additional context (user role, peer group, model artifacts, network exfiltration signals) before escalating to incidents. -references: -- https://splunkbase.splunk.com/app/8024 -- https://www.ibm.com/think/topics/shadow-ai -- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html -- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama -drilldown_searches: -- name: View the detection results for - "$host$" - search: '%original_detection_search% | search host="$host$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -- name: View risk events for the last 7 days for - "$host$" - search: | - | from datamodel Risk.All_Risk - | search normalized_risk_object="$host$" starthoursago=168 - | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -tags: - analytic_story: - - Suspicious Local Llm Frameworks - asset_type: Endpoint - mitre_attack_id: - - T1543 - product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - security_domain: endpoint -tests: -- name: True Positive Test - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt - sourcetype: XmlWinEventLog - source: XmlWinEventLog:Security diff --git a/stories/suspicious_local_llm_frameworks.yml b/stories/suspicious_local_llm_frameworks.yml index 18db7128e3..a1e180c190 100644 --- a/stories/suspicious_local_llm_frameworks.yml +++ b/stories/suspicious_local_llm_frameworks.yml @@ -1,21 +1,29 @@ -name: Suspicious Local Llm Frameworks +name: Suspicious Local LLM Frameworks id: 0b4396a1-aeff-412e-b39e-4e26457c780d version: 1 date: '2025-11-12' author: Rod Soto, Splunk status: production -description: Leverage advanced Splunk searches to detect and investigate suspicious activities targeting possibly unauthorized local LLM frameworks. This analytic story addresses discovery and detection of unauthorized local llm frameworks and related shadow AI artifacts. -narrative: This analytic story addresses the growing security challenge of Shadow AI - the deployment and use of unauthorized Large Language Model (LLM) frameworks and AI tools within enterprise environments without proper governance, oversight, or security controls. Shadow AI deployments pose significant risks including data exfiltration through local model inference (where sensitive corporate data is processed by unmonitored AI systems), intellectual property leakage, policy violations, and creation of security blind spots that bypass enterprise data loss prevention and monitoring solutions. Local LLM frameworks such as Ollama, LM Studio, GPT4All, Jan, llama.cpp, and KoboldCPP enable users to download and run powerful language models entirely on their endpoints, processing sensitive information without cloud-based safeguards or enterprise visibility. These detections monitor process execution patterns, file creation activities (model files with .gguf, .ggml, safetensors extensions), DNS queries to model repositories, and network connections to identify unauthorized AI infrastructure. By correlating Windows Security Event Logs (Event ID 4688), Sysmon telemetry (Events 1, 11, 22), and behavioral indicators, security teams can detect shadow AI deployments early, investigate the scope of unauthorized model usage, assess data exposure risks, and enforce AI governance policies to prevent covert model manipulation, persistent endpoint compromise, and uncontrolled AI experimentation that bypasses established security frameworks. +description: | + Leverage advanced Splunk searches to detect and investigate suspicious activities targeting possibly unauthorized local LLM frameworks. This analytic story addresses discovery and detection of unauthorized local LLM frameworks and related shadow AI artifacts. +narrative: | + This analytic story addresses the growing security challenge of Shadow AI - the deployment and use of unauthorized Large Language Model (LLM) frameworks and AI tools within enterprise environments without proper governance, oversight, or security controls. + + Shadow AI deployments pose significant risks including data exfiltration through local model inference (where sensitive corporate data is processed by unmonitored AI systems), intellectual property leakage, policy violations, and creation of security blind spots that bypass enterprise data loss prevention and monitoring solutions. + + Local LLM frameworks such as Ollama, LM Studio, GPT4All, Jan, llama.cpp, and KoboldCPP enable users to download and run powerful language models entirely on their endpoints, processing sensitive information without cloud-based safeguards or enterprise visibility. These detections monitor process execution patterns, file creation activities (model files with .gguf, .ggml, safetensors extensions), DNS queries to model repositories, and network connections to identify unauthorized AI infrastructure. + + By correlating Windows Security Event Logs (Event ID 4688), Sysmon telemetry (Events 1, 11, 22), and behavioral indicators, security teams can detect shadow AI deployments early, investigate the scope of unauthorized model usage, assess data exposure risks, and enforce AI governance policies to prevent covert model manipulation, persistent endpoint compromise, and uncontrolled AI experimentation that bypasses established security frameworks. references: -- https://splunkbase.splunk.com/app/8024 -- https://www.ibm.com/think/topics/shadow-ai -- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html -- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama + - https://splunkbase.splunk.com/app/8024 + - https://www.ibm.com/think/topics/shadow-ai + - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html + - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama tags: category: - - Adversary Tactics + - Adversary Tactics product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - usecase: Advanced Threat Detection \ No newline at end of file + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + usecase: Advanced Threat Detection From b66a683171eb71bf9732bb711e851a1b84b597e0 Mon Sep 17 00:00:00 2001 From: Nasreddine Bencherchali Date: Fri, 21 Nov 2025 00:48:03 +0100 Subject: [PATCH 22/26] small fixes --- .../endpoint/llm_model_file_creation.yml | 28 +++++++++---------- ...windows_local_llm_framework_execution.yml} | 6 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) rename detections/endpoint/{suspicious_local_llm_framework_execution.yml => windows_local_llm_framework_execution.yml} (98%) diff --git a/detections/endpoint/llm_model_file_creation.yml b/detections/endpoint/llm_model_file_creation.yml index 1ff42203f3..9896ed61cd 100644 --- a/detections/endpoint/llm_model_file_creation.yml +++ b/detections/endpoint/llm_model_file_creation.yml @@ -13,23 +13,23 @@ description: | data_source: - Sysmon EventID 11 search: | - | tstats `security_content_summariesonly` count - min(_time) as firstTime - max(_time) as lastTime - from datamodel=Endpoint.Filesystem + | tstats `security_content_summariesonly` count + min(_time) as firstTime + max(_time) as lastTime + from datamodel=Endpoint.Filesystem where Filesystem.file_name IN ( - "*.gguf*", - "*ggml*", + "*.gguf*", + "*ggml*", "*Modelfile*", - "*safetensors*" - ) + "*safetensors*" + ) by Filesystem.action Filesystem.dest Filesystem.file_access_time Filesystem.file_create_time Filesystem.file_hash Filesystem.file_modify_time Filesystem.file_name Filesystem.file_path Filesystem.file_acl Filesystem.file_size Filesystem.process_guid Filesystem.process_id - Filesystem.user Filesystem.vendor_product - | `drop_dm_object_name(Filesystem)` - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` + Filesystem.user Filesystem.vendor_product + | `drop_dm_object_name(Filesystem)` + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `llm_model_file_creation_filter` how_to_implement: | To successfully implement this search, you need to be ingesting logs with file creation events from your endpoints. @@ -43,7 +43,7 @@ references: - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon - https://www.ibm.com/think/topics/shadow-ai - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html - - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama + - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama tags: analytic_story: - Suspicious Local LLM Frameworks @@ -74,4 +74,4 @@ tests: attack_data: - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational - source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational \ No newline at end of file + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational diff --git a/detections/endpoint/suspicious_local_llm_framework_execution.yml b/detections/endpoint/windows_local_llm_framework_execution.yml similarity index 98% rename from detections/endpoint/suspicious_local_llm_framework_execution.yml rename to detections/endpoint/windows_local_llm_framework_execution.yml index 38dbc941bb..75c5b96951 100644 --- a/detections/endpoint/suspicious_local_llm_framework_execution.yml +++ b/detections/endpoint/windows_local_llm_framework_execution.yml @@ -1,4 +1,4 @@ -name: Local LLM Framework Execution +name: Windows Local LLM Framework Execution id: a3f8e2c9-7d4b-4e1f-9c6a-2b5d8f3e1a7c version: 1 date: '2025-11-20' @@ -70,7 +70,7 @@ search: | "oobabooga.exe", "text-generation-webui.exe" ) - + by Processes.action Processes.dest Processes.original_file_name Processes.parent_process Processes.parent_process_exec Processes.parent_process_guid Processes.parent_process_id Processes.parent_process_name Processes.parent_process_path Processes.process @@ -94,7 +94,7 @@ search: | ) | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `suspicious_local_llm_framework_execution_filter`' + | `windows_local_llm_framework_execution_filter`' how_to_implement: | The detection is based on data that originates from Endpoint Detection and Response (EDR) agents. These agents are designed to provide security-related From 9c75fca52c2bcef26c5013e2f45247594a4db33b Mon Sep 17 00:00:00 2001 From: Nasreddine Bencherchali Date: Fri, 21 Nov 2025 13:03:20 +0100 Subject: [PATCH 23/26] updates --- .../endpoint/llm_model_file_creation.yml | 10 +- .../local_llm_framework_dns_query.yml | 12 +- .../windows_local_llm_framework_execution.yml | 130 +++++++++--------- 3 files changed, 79 insertions(+), 73 deletions(-) diff --git a/detections/endpoint/llm_model_file_creation.yml b/detections/endpoint/llm_model_file_creation.yml index 9896ed61cd..0f586540c4 100644 --- a/detections/endpoint/llm_model_file_creation.yml +++ b/detections/endpoint/llm_model_file_creation.yml @@ -70,8 +70,8 @@ drilldown_searches: earliest_offset: $info_min_time$ latest_offset: $info_max_time$ tests: - - name: True Positive Test - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt - sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational - source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational +- name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog diff --git a/detections/endpoint/local_llm_framework_dns_query.yml b/detections/endpoint/local_llm_framework_dns_query.yml index acb7ea7479..d895e65c7e 100644 --- a/detections/endpoint/local_llm_framework_dns_query.yml +++ b/detections/endpoint/local_llm_framework_dns_query.yml @@ -13,7 +13,7 @@ data_source: - Sysmon EventID 22 search: | `sysmon` - EventID=22 + EventCode=22 query IN ( "*huggingface*", "*ollama*", @@ -83,8 +83,8 @@ tags: - Splunk Cloud security_domain: endpoint tests: - - name: True Positive Test - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt - sourcetype: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational - source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational +- name: True Positive Test + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog diff --git a/detections/endpoint/windows_local_llm_framework_execution.yml b/detections/endpoint/windows_local_llm_framework_execution.yml index 75c5b96951..2460f67b50 100644 --- a/detections/endpoint/windows_local_llm_framework_execution.yml +++ b/detections/endpoint/windows_local_llm_framework_execution.yml @@ -20,64 +20,66 @@ search: | max(_time) as lastTime from datamodel=Endpoint.Processes where - Processes.process_name IN ( - "gpt4all.exe", - "jan.exe", - "kobold.exe", - "koboldcpp.exe", - "llama-run.exe", - "llama.cpp.exe", - "lmstudio.exe", - "nutstudio.exe", - "ollama.exe", - "oobabooga.exe", - "text-generation-webui.exe" + ( + Processes.process_name IN ( + "gpt4all.exe", + "jan.exe", + "kobold.exe", + "koboldcpp.exe", + "llama-run.exe", + "llama.cpp.exe", + "lmstudio.exe", + "nutstudio.exe", + "ollama.exe", + "oobabooga.exe", + "text-generation-webui.exe" + ) + OR + Processes.original_file_name IN ( + "ollama.exe", + "lmstudio.exe", + "gpt4all.exe", + "jan.exe", + "llama-run.exe", + "koboldcpp.exe", + "nutstudio.exe" + ) + OR + Processes.process IN ( + "*\\gpt4all\\*", + "*\\jan\\*", + "*\\koboldcpp\\*", + "*\\llama.cpp\\*", + "*\\lmstudio\\*", + "*\\nutstudio\\*", + "*\\ollama\\*", + "*\\oobabooga\\*", + "*huggingface*", + "*langchain*", + "*llama-run*", + "*transformers*" + ) + OR + Processes.parent_process_name IN ( + "gpt4all.exe", + "jan.exe", + "kobold.exe", + "koboldcpp.exe", + "llama-run.exe", + "llama.cpp.exe", + "lmstudio.exe", + "nutstudio.exe", + "ollama.exe", + "oobabooga.exe", + "text-generation-webui.exe" + ) ) - OR Processes.original_file_name IN ( - "ollama.exe", - "lmstudio.exe", - "gpt4all.exe", - "jan.exe", - "llama-run.exe", - "koboldcpp.exe", - "nutstudio.exe" - ) - OR Processes.process IN ( - "*\\gpt4all\\*", - "*\\jan\\*", - "*\\koboldcpp\\*", - "*\\llama.cpp\\*", - "*\\lmstudio\\*", - "*\\nutstudio\\*", - "*\\ollama\\*", - "*\\oobabooga\\*", - "*huggingface*", - "*langchain*", - "*llama-run*", - "*transformers*" - ) - OR - Processes.parent_process_name IN ( - "gpt4all.exe", - "jan.exe", - "kobold.exe", - "koboldcpp.exe", - "llama-run.exe", - "llama.cpp.exe", - "lmstudio.exe", - "nutstudio.exe", - "ollama.exe", - "oobabooga.exe", - "text-generation-webui.exe" - ) - by Processes.action Processes.dest Processes.original_file_name Processes.parent_process Processes.parent_process_exec Processes.parent_process_guid Processes.parent_process_id Processes.parent_process_name Processes.parent_process_path Processes.process Processes.process_exec Processes.process_guid Processes.process_hash Processes.process_id Processes.process_integrity_level Processes.process_name Processes.process_path Processes.user Processes.user_id Processes.vendor_product - | `drop_dm_object_name(Processes)` | eval Framework=case( match(process_name, "(?i)ollama") OR match(process, "(?i)ollama"), "Ollama", @@ -94,7 +96,11 @@ search: | ) | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `windows_local_llm_framework_execution_filter`' + | table action dest Framework original_file_name parent_process parent_process_exec + parent_process_guid parent_process_id parent_process_name parent_process_path + process process_exec process_guid process_hash process_id process_integrity_level + process_name process_path user user_id vendor_product + | `windows_local_llm_framework_execution_filter` how_to_implement: | The detection is based on data that originates from Endpoint Detection and Response (EDR) agents. These agents are designed to provide security-related @@ -151,13 +157,13 @@ tags: - Splunk Cloud security_domain: endpoint tests: - - name: True Positive Test - Sysmon - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt - source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational - sourcetype: XmlWinEventLog - - name: True Positive Test - Windows Event Log Security - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt - sourcetype: XmlWinEventLog - source: XmlWinEventLog:Security +- name: True Positive Test - Sysmon + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog +- name: True Positive Test - Windows Event Log Security + attack_data: + - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt + sourcetype: XmlWinEventLog + source: XmlWinEventLog:Security From 22ace959403a9bce90c08f41657900bcbb76de8d Mon Sep 17 00:00:00 2001 From: Nasreddine Bencherchali Date: Fri, 21 Nov 2025 13:37:06 +0100 Subject: [PATCH 24/26] small change --- detections/endpoint/local_llm_framework_dns_query.yml | 8 +++----- .../endpoint/windows_local_llm_framework_execution.yml | 5 ----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/detections/endpoint/local_llm_framework_dns_query.yml b/detections/endpoint/local_llm_framework_dns_query.yml index d895e65c7e..d013a3701e 100644 --- a/detections/endpoint/local_llm_framework_dns_query.yml +++ b/detections/endpoint/local_llm_framework_dns_query.yml @@ -14,7 +14,7 @@ data_source: search: | `sysmon` EventCode=22 - query IN ( + QueryName IN ( "*huggingface*", "*ollama*", "*jan.ai*", @@ -24,9 +24,7 @@ search: | "*lmstudio*", "*modelscope*", "*civitai*", - "*github.com*llama*", - "*github.com*oobabooga*", - "*github.com*koboldai*", + "*oobabooga*", "*replicate*", "*anthropic*", "*openai*", @@ -45,7 +43,7 @@ search: | | stats count min(_time) as firstTime max(_time) as lastTime - by src dest Image query query_count answer answer_count reply_code_id vendor_product + by src dest Image process_name QueryName query_count answer answer_count reply_code_id vendor_product | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `local_llm_framework_dns_query_filter` diff --git a/detections/endpoint/windows_local_llm_framework_execution.yml b/detections/endpoint/windows_local_llm_framework_execution.yml index 2460f67b50..88c4ff1ebf 100644 --- a/detections/endpoint/windows_local_llm_framework_execution.yml +++ b/detections/endpoint/windows_local_llm_framework_execution.yml @@ -162,8 +162,3 @@ tests: - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog -- name: True Positive Test - Windows Event Log Security - attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/4688_local_llms.txt - sourcetype: XmlWinEventLog - source: XmlWinEventLog:Security From ce28534d0366a1db07d241e725f7722337f03eba Mon Sep 17 00:00:00 2001 From: Bhavin Patel Date: Fri, 21 Nov 2025 10:15:36 -0800 Subject: [PATCH 25/26] various fixes --- detections/endpoint/llm_model_file_creation.yml | 2 +- .../endpoint/local_llm_framework_dns_query.yml | 12 ++++++------ .../windows_local_llm_framework_execution.yml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/detections/endpoint/llm_model_file_creation.yml b/detections/endpoint/llm_model_file_creation.yml index 0f586540c4..210ad70213 100644 --- a/detections/endpoint/llm_model_file_creation.yml +++ b/detections/endpoint/llm_model_file_creation.yml @@ -72,6 +72,6 @@ drilldown_searches: tests: - name: True Positive Test attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog diff --git a/detections/endpoint/local_llm_framework_dns_query.yml b/detections/endpoint/local_llm_framework_dns_query.yml index d013a3701e..405008c550 100644 --- a/detections/endpoint/local_llm_framework_dns_query.yml +++ b/detections/endpoint/local_llm_framework_dns_query.yml @@ -43,7 +43,7 @@ search: | | stats count min(_time) as firstTime max(_time) as lastTime - by src dest Image process_name QueryName query_count answer answer_count reply_code_id vendor_product + by src Image process_name QueryName query_count answer answer_count reply_code_id vendor_product | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `local_llm_framework_dns_query_filter` @@ -56,14 +56,14 @@ references: - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama drilldown_searches: - - name: View the detection results for - "$host$" - search: '%original_detection_search% | search host="$host$"' + - name: View the detection results for - "$src$" + search: '%original_detection_search% | search src="$src$"' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ - - name: View risk events for the last 7 days for - "$host$" + - name: View risk events for the last 7 days for - "$src$" search: | | from datamodel Risk.All_Risk - | search normalized_risk_object="$host$" starthoursago=168 + | search normalized_risk_object="$src$" starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` @@ -83,6 +83,6 @@ tags: tests: - name: True Positive Test attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_dns.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog diff --git a/detections/endpoint/windows_local_llm_framework_execution.yml b/detections/endpoint/windows_local_llm_framework_execution.yml index 88c4ff1ebf..93dec1813c 100644 --- a/detections/endpoint/windows_local_llm_framework_execution.yml +++ b/detections/endpoint/windows_local_llm_framework_execution.yml @@ -159,6 +159,6 @@ tags: tests: - name: True Positive Test - Sysmon attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.txt + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog From 8d9cd1e0c99df8c2d8134e5bd4c61a2eb00af610 Mon Sep 17 00:00:00 2001 From: Bhavin Patel Date: Fri, 21 Nov 2025 10:22:51 -0800 Subject: [PATCH 26/26] remove dd for hunting detections --- detections/endpoint/llm_model_file_creation.yml | 14 -------------- .../endpoint/local_llm_framework_dns_query.yml | 14 -------------- .../windows_local_llm_framework_execution.yml | 14 -------------- 3 files changed, 42 deletions(-) diff --git a/detections/endpoint/llm_model_file_creation.yml b/detections/endpoint/llm_model_file_creation.yml index 210ad70213..77bc087350 100644 --- a/detections/endpoint/llm_model_file_creation.yml +++ b/detections/endpoint/llm_model_file_creation.yml @@ -55,20 +55,6 @@ tags: - Splunk Enterprise Security - Splunk Cloud security_domain: endpoint -drilldown_searches: - - name: View the detection results for - "$host$" - search: '%original_detection_search% | search host="$host$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ - - name: View risk events for the last 7 days for - "$host$" - search: | - | from datamodel Risk.All_Risk - | search normalized_risk_object="$host$" starthoursago=168 - | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ tests: - name: True Positive Test attack_data: diff --git a/detections/endpoint/local_llm_framework_dns_query.yml b/detections/endpoint/local_llm_framework_dns_query.yml index 405008c550..1611732e11 100644 --- a/detections/endpoint/local_llm_framework_dns_query.yml +++ b/detections/endpoint/local_llm_framework_dns_query.yml @@ -55,20 +55,6 @@ references: - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama -drilldown_searches: - - name: View the detection results for - "$src$" - search: '%original_detection_search% | search src="$src$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ - - name: View risk events for the last 7 days for - "$src$" - search: | - | from datamodel Risk.All_Risk - | search normalized_risk_object="$src$" starthoursago=168 - | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object - | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)` - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ tags: analytic_story: - Suspicious Local LLM Frameworks diff --git a/detections/endpoint/windows_local_llm_framework_execution.yml b/detections/endpoint/windows_local_llm_framework_execution.yml index 93dec1813c..f4f12f6847 100644 --- a/detections/endpoint/windows_local_llm_framework_execution.yml +++ b/detections/endpoint/windows_local_llm_framework_execution.yml @@ -131,20 +131,6 @@ references: - https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html - https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama - https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon -drilldown_searches: -- name: View the detection results for "$dest$" - search: '%original_detection_search% | search dest="$dest$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -- name: View risk events for the last 7 days for "$dest$" - search: '| from datamodel Risk.All_Risk | search normalized_risk_object="$dest$" - starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime - values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) - as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) - as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` - | `security_content_ctime(lastTime)`' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ tags: analytic_story: - Suspicious Local LLM Frameworks