|
| 1 | +name: Windows Local LLM Framework Execution |
| 2 | +id: a3f8e2c9-7d4b-4e1f-9c6a-2b5d8f3e1a7c |
| 3 | +version: 1 |
| 4 | +date: '2025-11-20' |
| 5 | +author: Rod Soto, Splunk |
| 6 | +status: production |
| 7 | +type: Hunting |
| 8 | +description: | |
| 9 | + 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. |
| 10 | + It identifies cases where known LLM framework executables are launched or command-line arguments reference AI/ML libraries. |
| 11 | + This activity is significant as it may indicate shadow AI deployments, unauthorized model inference operations, or potential data exfiltration through local AI systems. |
| 12 | + If confirmed malicious, this could lead to unauthorized access to sensitive data, intellectual property theft, or circumvention of organizational AI governance policies. |
| 13 | +data_source: |
| 14 | + - Sysmon EventID 1 |
| 15 | + - Windows Event Log Security 4688 |
| 16 | + - CrowdStrike ProcessRollup2 |
| 17 | +search: | |
| 18 | + | tstats `security_content_summariesonly` count |
| 19 | + min(_time) as firstTime |
| 20 | + max(_time) as lastTime |
| 21 | + from datamodel=Endpoint.Processes |
| 22 | + where |
| 23 | + ( |
| 24 | + Processes.process_name IN ( |
| 25 | + "gpt4all.exe", |
| 26 | + "jan.exe", |
| 27 | + "kobold.exe", |
| 28 | + "koboldcpp.exe", |
| 29 | + "llama-run.exe", |
| 30 | + "llama.cpp.exe", |
| 31 | + "lmstudio.exe", |
| 32 | + "nutstudio.exe", |
| 33 | + "ollama.exe", |
| 34 | + "oobabooga.exe", |
| 35 | + "text-generation-webui.exe" |
| 36 | + ) |
| 37 | + OR |
| 38 | + Processes.original_file_name IN ( |
| 39 | + "ollama.exe", |
| 40 | + "lmstudio.exe", |
| 41 | + "gpt4all.exe", |
| 42 | + "jan.exe", |
| 43 | + "llama-run.exe", |
| 44 | + "koboldcpp.exe", |
| 45 | + "nutstudio.exe" |
| 46 | + ) |
| 47 | + OR |
| 48 | + Processes.process IN ( |
| 49 | + "*\\gpt4all\\*", |
| 50 | + "*\\jan\\*", |
| 51 | + "*\\koboldcpp\\*", |
| 52 | + "*\\llama.cpp\\*", |
| 53 | + "*\\lmstudio\\*", |
| 54 | + "*\\nutstudio\\*", |
| 55 | + "*\\ollama\\*", |
| 56 | + "*\\oobabooga\\*", |
| 57 | + "*huggingface*", |
| 58 | + "*langchain*", |
| 59 | + "*llama-run*", |
| 60 | + "*transformers*" |
| 61 | + ) |
| 62 | + OR |
| 63 | + Processes.parent_process_name IN ( |
| 64 | + "gpt4all.exe", |
| 65 | + "jan.exe", |
| 66 | + "kobold.exe", |
| 67 | + "koboldcpp.exe", |
| 68 | + "llama-run.exe", |
| 69 | + "llama.cpp.exe", |
| 70 | + "lmstudio.exe", |
| 71 | + "nutstudio.exe", |
| 72 | + "ollama.exe", |
| 73 | + "oobabooga.exe", |
| 74 | + "text-generation-webui.exe" |
| 75 | + ) |
| 76 | + ) |
| 77 | + by Processes.action Processes.dest Processes.original_file_name Processes.parent_process |
| 78 | + Processes.parent_process_exec Processes.parent_process_guid Processes.parent_process_id |
| 79 | + Processes.parent_process_name Processes.parent_process_path Processes.process |
| 80 | + Processes.process_exec Processes.process_guid Processes.process_hash Processes.process_id |
| 81 | + Processes.process_integrity_level Processes.process_name Processes.process_path Processes.user |
| 82 | + Processes.user_id Processes.vendor_product |
| 83 | + | `drop_dm_object_name(Processes)` |
| 84 | + | eval Framework=case( |
| 85 | + match(process_name, "(?i)ollama") OR match(process, "(?i)ollama"), "Ollama", |
| 86 | + match(process_name, "(?i)lmstudio") OR match(process, "(?i)lmstudio") OR match(process, "(?i)lm-studio"), "LM Studio", |
| 87 | + match(process_name, "(?i)gpt4all") OR match(process, "(?i)gpt4all"), "GPT4All", |
| 88 | + match(process_name, "(?i)kobold") OR match(process, "(?i)kobold"), "KoboldCPP", |
| 89 | + match(process_name, "(?i)jan") OR match(process, "(?i)jan"), "Jan AI", |
| 90 | + match(process_name, "(?i)nutstudio") OR match(process, "(?i)nutstudio"), "NutStudio", |
| 91 | + match(process_name, "(?i)llama") OR match(process, "(?i)llama"), "llama.cpp", |
| 92 | + match(process_name, "(?i)oobabooga") OR match(process, "(?i)oobabooga") OR match(process, "(?i)text-generation-webui"), "Oobabooga", |
| 93 | + match(process, "(?i)transformers") OR match(process, "(?i)huggingface"), "HuggingFace/Transformers", |
| 94 | + match(process, "(?i)langchain"), "LangChain", |
| 95 | + 1=1, "Other" |
| 96 | + ) |
| 97 | + | `security_content_ctime(firstTime)` |
| 98 | + | `security_content_ctime(lastTime)` |
| 99 | + | table action dest Framework original_file_name parent_process parent_process_exec |
| 100 | + parent_process_guid parent_process_id parent_process_name parent_process_path |
| 101 | + process process_exec process_guid process_hash process_id process_integrity_level |
| 102 | + process_name process_path user user_id vendor_product |
| 103 | + | `windows_local_llm_framework_execution_filter` |
| 104 | +how_to_implement: | |
| 105 | + The detection is based on data that originates from Endpoint Detection |
| 106 | + and Response (EDR) agents. These agents are designed to provide security-related |
| 107 | + telemetry from the endpoints where the agent is installed. To implement this search, |
| 108 | + you must ingest logs that contain the process GUID, process name, and parent process. |
| 109 | + Additionally, you must ingest complete command-line executions. These logs must |
| 110 | + be processed using the appropriate Splunk Technology Add-ons that are specific to |
| 111 | + the EDR product. The logs must also be mapped to the `Processes` node of the `Endpoint` |
| 112 | + data model. Use the Splunk Common Information Model (CIM) to normalize the field |
| 113 | + names and speed up the data modeling process. |
| 114 | +known_false_positives: Legitimate development, data science, and AI/ML workflows where |
| 115 | + authorized developers, researchers, or engineers intentionally execute local LLM |
| 116 | + frameworks (Ollama, LM Studio, GPT4All, Jan, NutStudio) for model experimentation, |
| 117 | + fine-tuning, or prototyping. Python developers using HuggingFace Transformers or |
| 118 | + LangChain for legitimate AI/ML projects. Approved sandbox and lab environments where |
| 119 | + framework testing is authorized. Open-source contributors and hobbyists running |
| 120 | + frameworks for educational purposes. Third-party applications that bundle or invoke |
| 121 | + LLM frameworks as dependencies (e.g., IDE plugins, analytics tools, chatbot integrations). |
| 122 | + System administrators deploying frameworks as part of containerized services or |
| 123 | + orchestrated ML workloads. Process name keyword overlap with unrelated utilities |
| 124 | + (e.g., "llama-backup", "janimation"). Recommended tuning — baseline approved frameworks |
| 125 | + and users by role/department, exclude sanctioned dev/lab systems via the filter |
| 126 | + macro, correlate with user identity and peer group anomalies before escalating to |
| 127 | + incident response. |
| 128 | +references: |
| 129 | +- https://splunkbase.splunk.com/app/8024 |
| 130 | +- https://www.ibm.com/think/topics/shadow-ai |
| 131 | +- https://www.splunk.com/en_us/blog/artificial-intelligence/splunk-technology-add-on-for-ollama.html |
| 132 | +- https://blogs.cisco.com/security/detecting-exposed-llm-servers-shodan-case-study-on-ollama |
| 133 | +- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon |
| 134 | +tags: |
| 135 | + analytic_story: |
| 136 | + - Suspicious Local LLM Frameworks |
| 137 | + asset_type: Endpoint |
| 138 | + mitre_attack_id: |
| 139 | + - T1543 |
| 140 | + product: |
| 141 | + - Splunk Enterprise |
| 142 | + - Splunk Enterprise Security |
| 143 | + - Splunk Cloud |
| 144 | + security_domain: endpoint |
| 145 | +tests: |
| 146 | +- name: True Positive Test - Sysmon |
| 147 | + attack_data: |
| 148 | + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/suspicious_behaviour/local_llms/sysmon_local_llms.log |
| 149 | + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational |
| 150 | + sourcetype: XmlWinEventLog |
0 commit comments