From 485bbbb8efe5073dc4701e4757a9dd2d2c3ee5a9 Mon Sep 17 00:00:00 2001 From: oerdogan Date: Fri, 7 Aug 2026 11:14:31 +0200 Subject: [PATCH 01/10] Detections against malicious Python package activities --- ...n_network_traffic_during_package_build.yml | 67 +++++++++++++++++ ...e_creation_during_package_installation.yml | 70 ++++++++++++++++++ ...dification_during_package_installation.yml | 74 +++++++++++++++++++ ...s_creation_during_package_installation.yml | 71 ++++++++++++++++++ .../malicious_python_package_installation.yml | 36 +++++++++ 5 files changed, 318 insertions(+) create mode 100644 detections/endpoint/python_network_traffic_during_package_build.yml create mode 100644 detections/endpoint/python_pth_file_creation_during_package_installation.yml create mode 100644 detections/endpoint/python_pythonpath_modification_during_package_installation.yml create mode 100644 detections/endpoint/python_site_hooks_creation_during_package_installation.yml create mode 100644 stories/malicious_python_package_installation.yml diff --git a/detections/endpoint/python_network_traffic_during_package_build.yml b/detections/endpoint/python_network_traffic_during_package_build.yml new file mode 100644 index 0000000000..d3974d491c --- /dev/null +++ b/detections/endpoint/python_network_traffic_during_package_build.yml @@ -0,0 +1,67 @@ +name: Python Network Traffic during Package Build +id: 03c9c504-2294-44da-8180-beefe1ca8ba8 +version: 1 +creation_date: '2026-07-23' +modification_date: '2026-07-23' +author: Onur Mustafa Erdogan, Splunk +status: production +type: TTP +description: |- + The following analytic detects a Python process making an outbound network connection during package installation. + Adversaries can abuse `setup.py` build scripts by leveraging `distutils`/`setuptools` command classes to execute arbitrary code, + including network beacons to third-party domains, the moment a malicious Python package is installed. This activity is significant + because it allows adversaries to establish a foothold or exfiltrate data without any direct interaction from the victim beyond + running `pip install`. If confirmed malicious, this could indicate a successful software supply chain compromise. +data_source: + - Sysmon EventID 1 + - Sysmon EventID 3 +search: |- + `sysmon` EventID IN (1,3) + | bin _time span=5m + | stats values(parent_process_id) as parent_process_id, values(dest_ip) as dest_ip, values(QueryName) as QueryName, values(CommandLine) as CommandLine, values(parent_process) as parent_process, dc(EventID) as EventID count by _time, host, source, process_id + | search CommandLine="*_in_process.py*" AND CommandLine="* build_wheel*" AND dest_ip!="" + | `python_network_traffic_during_package_build_filter` +how_to_implement: |- + The detection is based on data that originates from Sysmon. To implement this search, you must ingest logs + with process creation (EventID 1) and network connection (EventID 3) events, mapped via the appropriate + Splunk Technology Add-on. Use the Splunk Common Information Model (CIM) to normalize the field names. +known_false_positives: Python packages may contact software repositories, mirror sites during build time. Investigate the destination and package content to determine legitimacy. +references: + - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ +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 IN ("$host$") | 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: 7d + latest_offset: "0" +finding: + title: A Python process on $host$ made an outbound network connection to $dest$ during package installation + entity: + field: host + type: system + score: 30 +analytic_story: + - Malicious Python Package Installation + - Ingress Tool Transfer + - Command And Control + - Compromised Windows Host +asset_type: Endpoint +mitre_attack_id: + - T1195.002 + - T1059.006 +product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud +category: endpoint +security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1195.002/python_network_traffic/python_network_traffic.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog + test_type: unit diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml new file mode 100644 index 0000000000..a2d53176b5 --- /dev/null +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -0,0 +1,70 @@ +name: Python PTH File Creation during Package Installation +id: bf581b86-39cd-48b7-9312-d9affb48a8bc +version: 1 +creation_date: '2026-07-23' +modification_date: '2026-07-23' +author: Onur Mustafa Erdogan, Splunk +status: production +type: TTP +description: |- + The following analytic detects the creation of a Python path configuration (`.pth`) file in conjunction + with a package installation process. Path configuration files placed under `site-packages` or `dist-packages` + are executed with every subsequent invocation of Python, allowing adversaries to achieve persistence + on the victim endpoint regardless of build method or distribution type. This technique was used by the + threat actor group TeamPCP during the supply chain compromise of the `litellm` package. If confirmed + malicious, this could result in arbitrary code execution every time Python is invoked on the compromised host. +data_source: + - Sysmon EventID 1 + - Sysmon EventID 11 +search: |- + `sysmon` EventID IN (1,11) AND (CommandLine="* install *" OR (TargetFilename="*.pth" AND action="created")) + | bin _time span=5m + | stats values(parent_process_id) as parent_process_id, values(TargetFilename) as TargetFilename, values(CommandLine) as CommandLine, values(parent_process) as parent_process, dc(EventID) as dc_event_id count by _time, host, source, process_id + | search dc_event_id>1 + | `python_pth_file_creation_during_package_installation_filter` +how_to_implement: |- + This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) + and file creation (EventID 11) events, ensuring that file creation events are collected for files with the .pth + extension. Ingest the data via the appropriate Splunk Technology Add-on and normalize field names using the + Splunk Common Information Model (CIM). +known_false_positives: |- + Legitimate packages, such as those managing namespace packages or editable installs, may create `.pth` + files as part of normal installation. Investigate the file contents and parent process to determine legitimacy. +references: + - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ +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 IN ("$host$") | 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: 7d + latest_offset: "0" +finding: + title: A Python `.pth` file called $TargetFilename$ was created on $host$ during package installation + entity: + field: host + type: system + score: 40 +analytic_story: + - Malicious Python Package Installation + - Compromised Windows Host + - Windows Persistence Techniques +asset_type: Endpoint +mitre_attack_id: + - T1546 + - T1195.002 +product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud +category: endpoint +security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1546/python_pth_file_creation/python_pth_file_creation.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog + test_type: unit diff --git a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml new file mode 100644 index 0000000000..fbbd6ae0f8 --- /dev/null +++ b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml @@ -0,0 +1,74 @@ +name: Python PYTHONPATH Modification During Package Installation +id: 00f01ba4-df01-4caa-90f6-187e4563a516 +version: 1 +creation_date: '2026-07-23' +modification_date: '2026-07-23' +author: Onur Mustafa Erdogan, Splunk +status: production +type: TTP +description: |- + The following analytic detects modification of the PYTHONPATH environment variable in conjunction + with a package installation process. Python looks up the `sys.path` variable, which is generated + by combining user and site folders with `.pth` files and the value of the PYTHONPATH environment + variable, to determine which directories to use for importing modules. If an adversary is able to + control the value of PYTHONPATH, they can point it to an attacker-controlled directory and hijack + imported packages, achieving user-level persistence across future Python invocations and new shell + sessions. If confirmed malicious, this could result in arbitrary code execution every time Python + is invoked by the affected user. +data_source: + - Sysmon EventID 1 + - Sysmon EventID 13 +search: |- + `sysmon` EventID IN (1,13) AND (CommandLine="* install *" OR (TargetObject="*PYTHONPATH" AND action="modified")) + | bin _time span=5m + | stats values(parent_process_id) as parent_process_id, values(TargetObject) as TargetObject, values(registry_value_data) as registry_value_data, values(CommandLine) as CommandLine, values(parent_process) as parent_process, dc(EventID) as dc_event_id count by _time, host, source, process_id + | search dc_event_id>1 + | `python_pythonpath_modification_during_package_installation_filter` +how_to_implement: |- + This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) + and registry modification (EventID 13) events, ensuring that registry modification events are collected for the + PYTHONPATH environment variable(\Environment\PYTHONPATH). Ingest the data via the appropriate Splunk Technology Add-on + and normalize field names using the Splunk Common Information Model (CIM). +known_false_positives: |- + Developers and legitimate installers may modify PYTHONPATH as part of normal environment configuration. + Investigate the new value and parent process to determine legitimacy. +references: + - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ +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 IN ("$host$") | 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: 7d + latest_offset: "0" +finding: + title: The PYTHONPATH environment variable was modified on $host$ during package installation + entity: + field: host + type: system + score: 40 +analytic_story: + - Malicious Python Package Installation + - Compromised Windows Host + - Windows Persistence Techniques + - Suspicious Windows Registry Activities + - Windows Registry Abuse +asset_type: Endpoint +mitre_attack_id: + - T1574.007 + - T1195.002 +product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud +category: endpoint +security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1574.007/python_pythonpath_modification/python_pythonpath_modification.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog + test_type: unit diff --git a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml new file mode 100644 index 0000000000..c1b6451360 --- /dev/null +++ b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml @@ -0,0 +1,71 @@ +name: Python Site Hooks Creation during Package Installation +id: efaf40f5-779f-4b48-a941-b7d1a7c931ed +version: 1 +creation_date: '2026-07-23' +modification_date: '2026-07-23' +author: Onur Mustafa Erdogan, Splunk +status: production +type: TTP +description: |- + The following analytic detects the creation of a Python site hook file (`sitecustomize.py` or `usercustomize.py`) + within a `site-packages`/`dist-packages` directory in conjunction with a package installation process. Python's + `site` module loads these hooks from directories on `sys.path` before Python is executed. If an adversary manipulates + or plants one of these files, they can hijack the Python environment and execute their payload with every Python + invocation, achieving persistence on the victim endpoint. The VIPERTUNNEL backdoor was reported to abuse site hooks + in order to import and trigger DLL execution. If confirmed malicious, this could result in arbitrary code execution + every time Python is invoked on the compromised host. +data_source: + - Sysmon EventID 1 + - Sysmon EventID 11 +search: |- + `sysmon` EventID IN (1,11) AND (CommandLine="* install *" OR (TargetFilename="*-packages\*" AND action="created" AND (TargetFilename="*sitecustomize.py" OR TargetFilename="*usercustomize.py"))) + | bin _time span=5m + | stats values(parent_process_id) as val_parent_process_id, values(TargetFilename) as val_target_filename, values(CommandLine) as val_cmd_line, values(parent_process) as val_parent_process, dc(EventID) as dc_event_id count by _time, host, source, process_id + | search dc_event_id>1 + | `python_site_hooks_creation_during_package_installation_filter` +how_to_implement: |- + This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) + and file creation (EventID 11) events, ensuring that file creation events are collected for files with the .py + extension. Ingest the data via the appropriate Splunk Technology Add-on and normalize field names using the + Splunk Common Information Model (CIM). +known_false_positives: |- + Some legitimate tooling and environment managers create or modify `sitecustomize.py`/`usercustomize.py` + as part of normal setup. Investigate the file contents and parent process to determine legitimacy. +references: + - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ +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 IN ("$host$") | 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: 7d + latest_offset: "0" +finding: + title: A Python site hook file was created on $host$ during package installation + entity: + field: host + type: system + score: 40 +analytic_story: + - Malicious Python Package Installation + - Compromised Windows Host + - Windows Persistence Techniques +asset_type: Endpoint +mitre_attack_id: + - T1546 + - T1195.002 +product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud +category: endpoint +security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog + test_type: unit diff --git a/stories/malicious_python_package_installation.yml b/stories/malicious_python_package_installation.yml new file mode 100644 index 0000000000..b05343eef8 --- /dev/null +++ b/stories/malicious_python_package_installation.yml @@ -0,0 +1,36 @@ +name: Malicious Python Package Installation +id: 12e51c50-6b66-4ce7-83b8-95125ffd31e9 +version: 1 +creation_date: '2026-07-23' +modification_date: '2026-07-23' +author: Onur Mustafa Erdogan, Splunk +status: production +description: |- + This analytic story provides detection coverage for abuse of the Python package installation lifecycle, + including install-time code execution, persistence via `.pth` path configuration files, Python site hooks, + and PYTHONPATH environment variable manipulation. +narrative: |- + Python's popularity, readable syntax, and extensive third-party library ecosystem make it an attractive target + for threat actors seeking to compromise developer devices and infrastructure. Malicious packages and supply-chain + attacks exploit the trust built into Python's packaging ecosystem to execute payloads at the moment of installation, + without any direct interaction from the victim. Adversaries abuse several native Python features to achieve this. + `setup.py` build scripts can leverage `distutils`/`setuptools` command classes to execute arbitrary code, including + network beacons, during package installation. Path configuration files (`.pth`) placed in `site-packages`/`dist-packages` + are executed on every subsequent Python invocation, providing persistence; this technique was used by the threat actor + group TeamPCP during the supply-chain compromise of the `litellm` package. Python's `site` module also loads `sitecustomize.py` + and `usercustomize.py` hook files from directories on `sys.path`, which adversaries can plant or manipulate to hijack + the Python environment and achieve persistence, as seen with the VIPERTUNNEL backdoor. Finally, adversaries who can + modify a user's `PYTHONPATH` environment variable can redirect module imports to attacker-controlled directories,achieving + user-level persistence across new shell sessions. This story detects these behaviors by correlating process creation, + file creation, and registry modification telemetry around Python package installation activity. +references: + - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ +category: + - Adversary Tactics +usecase: Advanced Threat Detection +threat_group: + - TeamPCP +product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud From 9f2b84635c99cf0ff019a1876e9ef1eade2d3107 Mon Sep 17 00:00:00 2001 From: oerdogan Date: Fri, 7 Aug 2026 11:54:04 +0200 Subject: [PATCH 02/10] fixed trailing spaces --- .../endpoint/python_network_traffic_during_package_build.yml | 2 +- .../python_pth_file_creation_during_package_installation.yml | 4 ++-- ...on_pythonpath_modification_during_package_installation.yml | 2 +- ...python_site_hooks_creation_during_package_installation.yml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/detections/endpoint/python_network_traffic_during_package_build.yml b/detections/endpoint/python_network_traffic_during_package_build.yml index d3974d491c..49f2164dfb 100644 --- a/detections/endpoint/python_network_traffic_during_package_build.yml +++ b/detections/endpoint/python_network_traffic_during_package_build.yml @@ -21,7 +21,7 @@ search: |- | stats values(parent_process_id) as parent_process_id, values(dest_ip) as dest_ip, values(QueryName) as QueryName, values(CommandLine) as CommandLine, values(parent_process) as parent_process, dc(EventID) as EventID count by _time, host, source, process_id | search CommandLine="*_in_process.py*" AND CommandLine="* build_wheel*" AND dest_ip!="" | `python_network_traffic_during_package_build_filter` -how_to_implement: |- +how_to_implement: |- The detection is based on data that originates from Sysmon. To implement this search, you must ingest logs with process creation (EventID 1) and network connection (EventID 3) events, mapped via the appropriate Splunk Technology Add-on. Use the Splunk Common Information Model (CIM) to normalize the field names. diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml index a2d53176b5..b24140b8f8 100644 --- a/detections/endpoint/python_pth_file_creation_during_package_installation.yml +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -23,9 +23,9 @@ search: |- | search dc_event_id>1 | `python_pth_file_creation_during_package_installation_filter` how_to_implement: |- - This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) + This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) and file creation (EventID 11) events, ensuring that file creation events are collected for files with the .pth - extension. Ingest the data via the appropriate Splunk Technology Add-on and normalize field names using the + extension. Ingest the data via the appropriate Splunk Technology Add-on and normalize field names using the Splunk Common Information Model (CIM). known_false_positives: |- Legitimate packages, such as those managing namespace packages or editable installs, may create `.pth` diff --git a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml index fbbd6ae0f8..e97bed6df7 100644 --- a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml +++ b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml @@ -25,7 +25,7 @@ search: |- | search dc_event_id>1 | `python_pythonpath_modification_during_package_installation_filter` how_to_implement: |- - This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) + This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) and registry modification (EventID 13) events, ensuring that registry modification events are collected for the PYTHONPATH environment variable(\Environment\PYTHONPATH). Ingest the data via the appropriate Splunk Technology Add-on and normalize field names using the Splunk Common Information Model (CIM). diff --git a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml index c1b6451360..1f05a69410 100644 --- a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml +++ b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml @@ -24,9 +24,9 @@ search: |- | search dc_event_id>1 | `python_site_hooks_creation_during_package_installation_filter` how_to_implement: |- - This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) + This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) and file creation (EventID 11) events, ensuring that file creation events are collected for files with the .py - extension. Ingest the data via the appropriate Splunk Technology Add-on and normalize field names using the + extension. Ingest the data via the appropriate Splunk Technology Add-on and normalize field names using the Splunk Common Information Model (CIM). known_false_positives: |- Some legitimate tooling and environment managers create or modify `sitecustomize.py`/`usercustomize.py` From 915389e5ba4e6b28c56ac0b462927c2a469c39d7 Mon Sep 17 00:00:00 2001 From: oerdogan Date: Fri, 7 Aug 2026 14:30:48 +0200 Subject: [PATCH 03/10] updating attack data links --- .../endpoint/python_network_traffic_during_package_build.yml | 2 +- .../python_pth_file_creation_during_package_installation.yml | 2 +- ...thon_pythonpath_modification_during_package_installation.yml | 2 +- .../python_site_hooks_creation_during_package_installation.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/detections/endpoint/python_network_traffic_during_package_build.yml b/detections/endpoint/python_network_traffic_during_package_build.yml index 49f2164dfb..4764715371 100644 --- a/detections/endpoint/python_network_traffic_during_package_build.yml +++ b/detections/endpoint/python_network_traffic_during_package_build.yml @@ -61,7 +61,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1195.002/python_network_traffic/python_network_traffic.log + - data: https://raw.githubusercontent.com/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1195.002/python_network_traffic/python_network_traffic.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml index b24140b8f8..58c3d17876 100644 --- a/detections/endpoint/python_pth_file_creation_during_package_installation.yml +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -64,7 +64,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1546/python_pth_file_creation/python_pth_file_creation.log + - data: https://raw.githubusercontent.com/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546/python_pth_file_creation/python_pth_file_creation.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml index e97bed6df7..a54467e4cf 100644 --- a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml +++ b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml @@ -68,7 +68,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1574.007/python_pythonpath_modification/python_pythonpath_modification.log + - data: https://raw.githubusercontent.com/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1574.007/python_pythonpath_modification/python_pythonpath_modification.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml index 1f05a69410..b8b8bdd4c4 100644 --- a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml +++ b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml @@ -65,7 +65,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log + - data: https://raw.githubusercontent.com/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit From 2df9e7ad80900b780e71cde2c0890be8271c9bd0 Mon Sep 17 00:00:00 2001 From: oerdogan Date: Tue, 18 Aug 2026 16:22:38 +0200 Subject: [PATCH 04/10] incorporating feedback --- ...n_network_traffic_during_package_build.yml | 36 +++++++++++-------- ...e_creation_during_package_installation.yml | 35 ++++++++++-------- ...dification_during_package_installation.yml | 29 ++++++++------- ...s_creation_during_package_installation.yml | 31 +++++++++------- 4 files changed, 76 insertions(+), 55 deletions(-) diff --git a/detections/endpoint/python_network_traffic_during_package_build.yml b/detections/endpoint/python_network_traffic_during_package_build.yml index 4764715371..250c455e67 100644 --- a/detections/endpoint/python_network_traffic_during_package_build.yml +++ b/detections/endpoint/python_network_traffic_during_package_build.yml @@ -1,11 +1,11 @@ -name: Python Network Traffic during Package Build +name: Python Network Traffic During Package Build id: 03c9c504-2294-44da-8180-beefe1ca8ba8 version: 1 creation_date: '2026-07-23' -modification_date: '2026-07-23' +modification_date: '2026-08-18' author: Onur Mustafa Erdogan, Splunk status: production -type: TTP +type: Anomaly description: |- The following analytic detects a Python process making an outbound network connection during package installation. Adversaries can abuse `setup.py` build scripts by leveraging `distutils`/`setuptools` command classes to execute arbitrary code, @@ -13,13 +13,14 @@ description: |- because it allows adversaries to establish a foothold or exfiltrate data without any direct interaction from the victim beyond running `pip install`. If confirmed malicious, this could indicate a successful software supply chain compromise. data_source: - - Sysmon EventID 1 - - Sysmon EventID 3 + - Sysmon EventID 1 AND Sysmon EventID 3 search: |- - `sysmon` EventID IN (1,3) - | bin _time span=5m - | stats values(parent_process_id) as parent_process_id, values(dest_ip) as dest_ip, values(QueryName) as QueryName, values(CommandLine) as CommandLine, values(parent_process) as parent_process, dc(EventID) as EventID count by _time, host, source, process_id - | search CommandLine="*_in_process.py*" AND CommandLine="* build_wheel*" AND dest_ip!="" + `sysmon` EventID IN (1,3) AND (process="*_in_process.py*" OR process_name=python.exe) + | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(dest_ip) as dest_ip values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as EventID by host source process_id + | rename host as dest + | search process="* build_wheel*" dest_ip!="" + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `python_network_traffic_during_package_build_filter` how_to_implement: |- The detection is based on data that originates from Sysmon. To implement this search, you must ingest logs @@ -29,20 +30,25 @@ known_false_positives: Python packages may contact software repositories, mirror references: - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ drilldown_searches: - - name: View the detection results for - "$host$" - search: '%original_detection_search% | search host = "$host$"' + - 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 - "$host$" - search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$host$") | 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)`' + - name: View risk events for the last 7 days for - "$dest$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | 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: 7d latest_offset: "0" finding: - title: A Python process on $host$ made an outbound network connection to $dest$ during package installation + title: A Python process on $dest$ made an outbound network connection to $dest_ip$ during package installation entity: - field: host + field: dest type: system score: 30 +threat_objects: + - field: process + type: process + - field: dest_ip + type: dest_ip analytic_story: - Malicious Python Package Installation - Ingress Tool Transfer diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml index 58c3d17876..3f1f92e051 100644 --- a/detections/endpoint/python_pth_file_creation_during_package_installation.yml +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -1,11 +1,11 @@ -name: Python PTH File Creation during Package Installation +name: Python PTH File Creation During Package Installation id: bf581b86-39cd-48b7-9312-d9affb48a8bc version: 1 creation_date: '2026-07-23' -modification_date: '2026-07-23' +modification_date: '2026-08-18' author: Onur Mustafa Erdogan, Splunk status: production -type: TTP +type: Anomaly description: |- The following analytic detects the creation of a Python path configuration (`.pth`) file in conjunction with a package installation process. Path configuration files placed under `site-packages` or `dist-packages` @@ -14,13 +14,13 @@ description: |- threat actor group TeamPCP during the supply chain compromise of the `litellm` package. If confirmed malicious, this could result in arbitrary code execution every time Python is invoked on the compromised host. data_source: - - Sysmon EventID 1 - - Sysmon EventID 11 + - Sysmon EventID 1 AND Sysmon EventID 11 search: |- - `sysmon` EventID IN (1,11) AND (CommandLine="* install *" OR (TargetFilename="*.pth" AND action="created")) - | bin _time span=5m - | stats values(parent_process_id) as parent_process_id, values(TargetFilename) as TargetFilename, values(CommandLine) as CommandLine, values(parent_process) as parent_process, dc(EventID) as dc_event_id count by _time, host, source, process_id - | search dc_event_id>1 + `sysmon` EventID IN (1,11) process_name="python.exe" AND (process="* install *" OR (file_name="*.pth" AND action="created")) + | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(file_name) as file_name values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as dc_event_id by dest source process_id + | search dc_event_id>1 AND process!="*-- setuptools*" + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `python_pth_file_creation_during_package_installation_filter` how_to_implement: |- This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) @@ -33,20 +33,25 @@ known_false_positives: |- references: - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ drilldown_searches: - - name: View the detection results for - "$host$" - search: '%original_detection_search% | search host = "$host$"' + - 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 - "$host$" - search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$host$") | 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)`' + - name: View risk events for the last 7 days for - "$dest$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | 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: 7d latest_offset: "0" finding: - title: A Python `.pth` file called $TargetFilename$ was created on $host$ during package installation + title: A Python `.pth` file called $file_name$ was created on $dest$ during package installation using $process$ entity: - field: host + field: dest type: system score: 40 +threat_objects: + - field: process + type: process + - field: file_name + type: file_name analytic_story: - Malicious Python Package Installation - Compromised Windows Host diff --git a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml index a54467e4cf..74ce38ca16 100644 --- a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml +++ b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml @@ -2,7 +2,7 @@ name: Python PYTHONPATH Modification During Package Installation id: 00f01ba4-df01-4caa-90f6-187e4563a516 version: 1 creation_date: '2026-07-23' -modification_date: '2026-07-23' +modification_date: '2026-08-18' author: Onur Mustafa Erdogan, Splunk status: production type: TTP @@ -16,13 +16,13 @@ description: |- sessions. If confirmed malicious, this could result in arbitrary code execution every time Python is invoked by the affected user. data_source: - - Sysmon EventID 1 - - Sysmon EventID 13 + - Sysmon EventID 1 AND Sysmon EventID 13 search: |- - `sysmon` EventID IN (1,13) AND (CommandLine="* install *" OR (TargetObject="*PYTHONPATH" AND action="modified")) - | bin _time span=5m - | stats values(parent_process_id) as parent_process_id, values(TargetObject) as TargetObject, values(registry_value_data) as registry_value_data, values(CommandLine) as CommandLine, values(parent_process) as parent_process, dc(EventID) as dc_event_id count by _time, host, source, process_id + `sysmon` EventID IN (1,13) AND (parent_process="*\\site-packages\\pip\\*" OR (registry_path="*PYTHONPATH" AND action="modified")) + | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(registry_path) as registry_path values(registry_value_data) as registry_value_data values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as dc_event_id by dest source process_id | search dc_event_id>1 + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `python_pythonpath_modification_during_package_installation_filter` how_to_implement: |- This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) @@ -35,20 +35,25 @@ known_false_positives: |- references: - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ drilldown_searches: - - name: View the detection results for - "$host$" - search: '%original_detection_search% | search host = "$host$"' + - 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 - "$host$" - search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$host$") | 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)`' + - name: View risk events for the last 7 days for - "$dest$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | 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: 7d latest_offset: "0" finding: - title: The PYTHONPATH environment variable was modified on $host$ during package installation + title: The PYTHONPATH environment variable was modified to $registry_value_data$ on $dest$ during package installation using $process$ entity: - field: host + field: dest type: system score: 40 +threat_objects: + - field: process + type: process + - field: registry_value_data + type: registry_value_data analytic_story: - Malicious Python Package Installation - Compromised Windows Host diff --git a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml index b8b8bdd4c4..41aac3eda6 100644 --- a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml +++ b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml @@ -1,8 +1,8 @@ -name: Python Site Hooks Creation during Package Installation +name: Python Site Hooks Creation During Package Installation id: efaf40f5-779f-4b48-a941-b7d1a7c931ed version: 1 creation_date: '2026-07-23' -modification_date: '2026-07-23' +modification_date: '2026-08-18' author: Onur Mustafa Erdogan, Splunk status: production type: TTP @@ -15,13 +15,13 @@ description: |- in order to import and trigger DLL execution. If confirmed malicious, this could result in arbitrary code execution every time Python is invoked on the compromised host. data_source: - - Sysmon EventID 1 - - Sysmon EventID 11 + - Sysmon EventID 1 AND Sysmon EventID 11 search: |- - `sysmon` EventID IN (1,11) AND (CommandLine="* install *" OR (TargetFilename="*-packages\*" AND action="created" AND (TargetFilename="*sitecustomize.py" OR TargetFilename="*usercustomize.py"))) - | bin _time span=5m - | stats values(parent_process_id) as val_parent_process_id, values(TargetFilename) as val_target_filename, values(CommandLine) as val_cmd_line, values(parent_process) as val_parent_process, dc(EventID) as dc_event_id count by _time, host, source, process_id + `sysmon` EventID IN (1,11) AND (process="* install *" OR (file_path="*-packages\*" AND action="created" AND (file_path="*sitecustomize.py" OR file_path="*usercustomize.py"))) + | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(file_path) as file_path values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as dc_event_id by dest source process_id | search dc_event_id>1 + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `python_site_hooks_creation_during_package_installation_filter` how_to_implement: |- This detection requires Sysmon event logs. Configure your environment to ingest Sysmon process creation (EventID 1) @@ -34,20 +34,25 @@ known_false_positives: |- references: - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ drilldown_searches: - - name: View the detection results for - "$host$" - search: '%original_detection_search% | search host = "$host$"' + - 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 - "$host$" - search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$host$") | 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)`' + - name: View risk events for the last 7 days for - "$dest$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | 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: 7d latest_offset: "0" finding: - title: A Python site hook file was created on $host$ during package installation + title: A Python site hook file $file_path$ was created on $dest$ during package installation using $process$ entity: - field: host + field: dest type: system score: 40 +threat_objects: + - field: process + type: process + - field: file_path + type: file_path analytic_story: - Malicious Python Package Installation - Compromised Windows Host From a2b383be93a149dcf001e4b6decfeb02e7a1b8bd Mon Sep 17 00:00:00 2001 From: oerdogan Date: Tue, 18 Aug 2026 16:38:25 +0200 Subject: [PATCH 05/10] adding intermediate findings --- .../python_network_traffic_during_package_build.yml | 12 ++++++------ ...pth_file_creation_during_package_installation.yml | 12 ++++++------ ...te_hooks_creation_during_package_installation.yml | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/detections/endpoint/python_network_traffic_during_package_build.yml b/detections/endpoint/python_network_traffic_during_package_build.yml index 250c455e67..6a6137f1e0 100644 --- a/detections/endpoint/python_network_traffic_during_package_build.yml +++ b/detections/endpoint/python_network_traffic_during_package_build.yml @@ -38,12 +38,12 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | 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: 7d latest_offset: "0" -finding: - title: A Python process on $dest$ made an outbound network connection to $dest_ip$ during package installation - entity: - field: dest - type: system - score: 30 +intermediate_findings: + entities: + - field: dest + type: system + score: 30 + description: A Python process on $dest$ made an outbound network connection to $dest_ip$ during package installation threat_objects: - field: process type: process diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml index 3f1f92e051..979a421403 100644 --- a/detections/endpoint/python_pth_file_creation_during_package_installation.yml +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -41,12 +41,12 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | 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: 7d latest_offset: "0" -finding: - title: A Python `.pth` file called $file_name$ was created on $dest$ during package installation using $process$ - entity: - field: dest - type: system - score: 40 +intermediate_findings: + entities: + - field: dest + type: system + score: 30 + description: A Python `.pth` file called $file_name$ was created on $dest$ during package installation using $process$ threat_objects: - field: process type: process diff --git a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml index 41aac3eda6..fe1031e9fe 100644 --- a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml +++ b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml @@ -17,7 +17,7 @@ description: |- data_source: - Sysmon EventID 1 AND Sysmon EventID 11 search: |- - `sysmon` EventID IN (1,11) AND (process="* install *" OR (file_path="*-packages\*" AND action="created" AND (file_path="*sitecustomize.py" OR file_path="*usercustomize.py"))) + `sysmon` EventID IN (1,11) AND (process="* install *" OR (file_path="*-packages\\*" AND action="created" AND (file_path="*sitecustomize.py" OR file_path="*usercustomize.py"))) | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(file_path) as file_path values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as dc_event_id by dest source process_id | search dc_event_id>1 | `security_content_ctime(firstTime)` From 211cecd25370478ea772d12d2788d60d37208342 Mon Sep 17 00:00:00 2001 From: oerdogan Date: Tue, 18 Aug 2026 16:50:38 +0200 Subject: [PATCH 06/10] fixing contentctl errors --- .../python_pth_file_creation_during_package_installation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml index 979a421403..7d79233533 100644 --- a/detections/endpoint/python_pth_file_creation_during_package_installation.yml +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -46,7 +46,7 @@ intermediate_findings: - field: dest type: system score: 30 - description: A Python `.pth` file called $file_name$ was created on $dest$ during package installation using $process$ + description: A Python .pth file called $file_name$ was created on $dest$ during package installation using $process$ threat_objects: - field: process type: process From b8be45003084dd0f15f7a7b9322c0ef08d7976ab Mon Sep 17 00:00:00 2001 From: oerdogan Date: Tue, 18 Aug 2026 17:39:24 +0200 Subject: [PATCH 07/10] fixing threat object type --- .../endpoint/python_network_traffic_during_package_build.yml | 4 ++-- .../python_pth_file_creation_during_package_installation.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/detections/endpoint/python_network_traffic_during_package_build.yml b/detections/endpoint/python_network_traffic_during_package_build.yml index 6a6137f1e0..2401dcb72d 100644 --- a/detections/endpoint/python_network_traffic_during_package_build.yml +++ b/detections/endpoint/python_network_traffic_during_package_build.yml @@ -43,12 +43,12 @@ intermediate_findings: - field: dest type: system score: 30 - description: A Python process on $dest$ made an outbound network connection to $dest_ip$ during package installation + message: A Python process on $dest$ made an outbound network connection to $dest_ip$ during package installation threat_objects: - field: process type: process - field: dest_ip - type: dest_ip + type: ip_address analytic_story: - Malicious Python Package Installation - Ingress Tool Transfer diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml index 7d79233533..6b26893ac3 100644 --- a/detections/endpoint/python_pth_file_creation_during_package_installation.yml +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -46,7 +46,7 @@ intermediate_findings: - field: dest type: system score: 30 - description: A Python .pth file called $file_name$ was created on $dest$ during package installation using $process$ + message: A Python .pth file called $file_name$ was created on $dest$ during package installation using $process$ threat_objects: - field: process type: process From cae95ee43474ee6d3ea3779c2cf11594aa424aea Mon Sep 17 00:00:00 2001 From: oerdogan Date: Wed, 19 Aug 2026 00:17:19 +0200 Subject: [PATCH 08/10] update unit test files --- .../endpoint/python_network_traffic_during_package_build.yml | 2 +- .../python_pth_file_creation_during_package_installation.yml | 2 +- ...thon_pythonpath_modification_during_package_installation.yml | 2 +- .../python_site_hooks_creation_during_package_installation.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/detections/endpoint/python_network_traffic_during_package_build.yml b/detections/endpoint/python_network_traffic_during_package_build.yml index 2401dcb72d..4717f0a803 100644 --- a/detections/endpoint/python_network_traffic_during_package_build.yml +++ b/detections/endpoint/python_network_traffic_during_package_build.yml @@ -67,7 +67,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1195.002/python_network_traffic/python_network_traffic.log + - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1195.002/python_network_traffic/python_network_traffic.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml index 6b26893ac3..7babb16a74 100644 --- a/detections/endpoint/python_pth_file_creation_during_package_installation.yml +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -69,7 +69,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546/python_pth_file_creation/python_pth_file_creation.log + - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546/python_pth_file_creation/python_pth_file_creation.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml index 74ce38ca16..009f18d6b6 100644 --- a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml +++ b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml @@ -73,7 +73,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1574.007/python_pythonpath_modification/python_pythonpath_modification.log + - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1574.007/python_pythonpath_modification/python_pythonpath_modification.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml index fe1031e9fe..7467e940d4 100644 --- a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml +++ b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml @@ -70,7 +70,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://raw.githubusercontent.com/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log + - data: https://github.com/splunk/attack_data/blob/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit From 02a260aa0d732b178823f07b9a3070fce310fd98 Mon Sep 17 00:00:00 2001 From: oerdogan Date: Wed, 19 Aug 2026 11:17:19 +0200 Subject: [PATCH 09/10] fixing incorrect test file --- .../python_site_hooks_creation_during_package_installation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml index 7467e940d4..1888a7d043 100644 --- a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml +++ b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml @@ -70,7 +70,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://github.com/splunk/attack_data/blob/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log + - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit From e30426a9ae44aafa7a674c0efe0e644d5bb77869 Mon Sep 17 00:00:00 2001 From: nasbench <8741929+nasbench@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:46:41 +0200 Subject: [PATCH 10/10] update metadata and parts of the logic/rba message --- ...n_network_traffic_during_package_build.yml | 67 +++++++++++++++---- ...e_creation_during_package_installation.yml | 59 ++++++++++++---- ...dification_during_package_installation.yml | 57 +++++++++++----- ...s_creation_during_package_installation.yml | 57 ++++++++++++---- .../malicious_python_package_installation.yml | 26 +++---- 5 files changed, 193 insertions(+), 73 deletions(-) diff --git a/detections/endpoint/python_network_traffic_during_package_build.yml b/detections/endpoint/python_network_traffic_during_package_build.yml index 4717f0a803..eeb6f097b7 100644 --- a/detections/endpoint/python_network_traffic_during_package_build.yml +++ b/detections/endpoint/python_network_traffic_during_package_build.yml @@ -1,24 +1,59 @@ name: Python Network Traffic During Package Build id: 03c9c504-2294-44da-8180-beefe1ca8ba8 version: 1 -creation_date: '2026-07-23' -modification_date: '2026-08-18' +creation_date: '2026-08-21' +modification_date: '2026-08-21' author: Onur Mustafa Erdogan, Splunk status: production type: Anomaly description: |- The following analytic detects a Python process making an outbound network connection during package installation. - Adversaries can abuse `setup.py` build scripts by leveraging `distutils`/`setuptools` command classes to execute arbitrary code, - including network beacons to third-party domains, the moment a malicious Python package is installed. This activity is significant - because it allows adversaries to establish a foothold or exfiltrate data without any direct interaction from the victim beyond - running `pip install`. If confirmed malicious, this could indicate a successful software supply chain compromise. + Adversaries can abuse `setup.py` build scripts by leveraging `distutils`/`setuptools` command classes to execute arbitrary code, including network beacons to third-party domains, the moment a malicious Python package is installed. + This activity is significant because it allows adversaries to establish a foothold or exfiltrate data without any direct interaction from the victim beyond running `pip install`. + If confirmed malicious, this could indicate a successful software supply chain compromise. data_source: - Sysmon EventID 1 AND Sysmon EventID 3 search: |- - `sysmon` EventID IN (1,3) AND (process="*_in_process.py*" OR process_name=python.exe) - | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(dest_ip) as dest_ip values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as EventID by host source process_id - | rename host as dest - | search process="* build_wheel*" dest_ip!="" + `sysmon` + ( + EventID=1 + ( + process="*_in_process.py*" + OR + process_name=python.exe + ) + ) + OR + ( + EventID=3 + dest_ip!="" + process_name=python.exe + ) + + | eval dest=if(EventID=3, Computer, dest) + + | stats count min(_time) as firstTime + max(_time) as lastTime + values(parent_process_id) as parent_process_id + values(parent_process_path) as parent_process_path + values(parent_process_name) as parent_process_name + values(parent_process) as parent_process + values(process_path) as process_path + values(process_name) as process_name + values(process) as process + values(dest_ip) as dest_ip + values(dest_host) as dest_host + + by dest source process_id + + | search process="* build_wheel*" + + | table firstTime lastTime + parent_process_id parent_process_path parent_process_name parent_process + process_id process_path process_name process + dest_ip dest_host + dest source + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `python_network_traffic_during_package_build_filter` @@ -26,7 +61,9 @@ how_to_implement: |- The detection is based on data that originates from Sysmon. To implement this search, you must ingest logs with process creation (EventID 1) and network connection (EventID 3) events, mapped via the appropriate Splunk Technology Add-on. Use the Splunk Common Information Model (CIM) to normalize the field names. -known_false_positives: Python packages may contact software repositories, mirror sites during build time. Investigate the destination and package content to determine legitimacy. +known_false_positives: |- + Python packages may contact software repositories, mirror sites during build time. + Investigate the destination and package content to determine legitimacy. references: - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ drilldown_searches: @@ -42,13 +79,15 @@ intermediate_findings: entities: - field: dest type: system - score: 30 - message: A Python process on $dest$ made an outbound network connection to $dest_ip$ during package installation + score: 20 + message: A Python process [$process$] on [$dest$] made an outbound network connection to [$dest_ip$] with hostname [$dest_host$] during package installation. threat_objects: - field: process type: process - field: dest_ip type: ip_address + - field: dest_host + type: domain analytic_story: - Malicious Python Package Installation - Ingress Tool Transfer @@ -67,7 +106,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1195.002/python_network_traffic/python_network_traffic.log + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1195.002/python_network_traffic/python_network_traffic.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_pth_file_creation_during_package_installation.yml b/detections/endpoint/python_pth_file_creation_during_package_installation.yml index 7babb16a74..c7c514aee1 100644 --- a/detections/endpoint/python_pth_file_creation_during_package_installation.yml +++ b/detections/endpoint/python_pth_file_creation_during_package_installation.yml @@ -1,24 +1,53 @@ name: Python PTH File Creation During Package Installation id: bf581b86-39cd-48b7-9312-d9affb48a8bc version: 1 -creation_date: '2026-07-23' -modification_date: '2026-08-18' +creation_date: '2026-08-21' +modification_date: '2026-08-21' author: Onur Mustafa Erdogan, Splunk status: production type: Anomaly description: |- - The following analytic detects the creation of a Python path configuration (`.pth`) file in conjunction - with a package installation process. Path configuration files placed under `site-packages` or `dist-packages` - are executed with every subsequent invocation of Python, allowing adversaries to achieve persistence - on the victim endpoint regardless of build method or distribution type. This technique was used by the - threat actor group TeamPCP during the supply chain compromise of the `litellm` package. If confirmed - malicious, this could result in arbitrary code execution every time Python is invoked on the compromised host. + The following analytic detects the creation of a Python path configuration (`.pth`) file in conjunction with a package installation process. + Path configuration files placed under `site-packages` or `dist-packages` are executed with every subsequent invocation of Python, allowing adversaries to achieve persistence on the victim endpoint regardless of build method or distribution type. + This technique was used by the threat actor group TeamPCP during the supply chain compromise of the `litellm` package. + If confirmed malicious, this could result in arbitrary code execution every time Python is invoked on the compromised host. data_source: - Sysmon EventID 1 AND Sysmon EventID 11 search: |- - `sysmon` EventID IN (1,11) process_name="python.exe" AND (process="* install *" OR (file_name="*.pth" AND action="created")) - | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(file_name) as file_name values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as dc_event_id by dest source process_id + `sysmon` + EventID IN (1,11) + process_name="python.exe" + ( + process="* install *" + OR + ( + file_name="*.pth" + action="created" + ) + ) + | stats count min(_time) as firstTime + max(_time) as lastTime + values(parent_process_id) as parent_process_id + values(parent_process_path) as parent_process_path + values(parent_process_name) as parent_process_name + values(parent_process) as parent_process + values(process_path) as process_path + values(process_name) as process_name + values(process) as process + values(file_name) as file_name + values(file_path) as file_path + dc(EventID) as dc_event_id + + by dest source process_id + | search dc_event_id>1 AND process!="*-- setuptools*" + + | table firstTime lastTime + parent_process_id parent_process_path parent_process_name parent_process + process_id process_path process_name process + file_name file_path + dest source + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `python_pth_file_creation_during_package_installation_filter` @@ -28,8 +57,8 @@ how_to_implement: |- extension. Ingest the data via the appropriate Splunk Technology Add-on and normalize field names using the Splunk Common Information Model (CIM). known_false_positives: |- - Legitimate packages, such as those managing namespace packages or editable installs, may create `.pth` - files as part of normal installation. Investigate the file contents and parent process to determine legitimacy. + Legitimate packages, such as those managing namespace packages or editable installs, may create `.pth` files as part of normal installation. + Investigate the file contents and parent process to determine legitimacy. references: - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ drilldown_searches: @@ -46,12 +75,14 @@ intermediate_findings: - field: dest type: system score: 30 - message: A Python .pth file called $file_name$ was created on $dest$ during package installation using $process$ + message: A Python .pth file called [$file_name$] located at [$file_path$] was created on [$dest$] during package installation using [$process$]. threat_objects: - field: process type: process - field: file_name type: file_name + - field: file_path + type: file_path analytic_story: - Malicious Python Package Installation - Compromised Windows Host @@ -69,7 +100,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546/python_pth_file_creation/python_pth_file_creation.log + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1546/python_pth_file_creation/python_pth_file_creation.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml index 009f18d6b6..a314b6e63e 100644 --- a/detections/endpoint/python_pythonpath_modification_during_package_installation.yml +++ b/detections/endpoint/python_pythonpath_modification_during_package_installation.yml @@ -1,26 +1,53 @@ name: Python PYTHONPATH Modification During Package Installation id: 00f01ba4-df01-4caa-90f6-187e4563a516 version: 1 -creation_date: '2026-07-23' -modification_date: '2026-08-18' +creation_date: '2026-08-21' +modification_date: '2026-08-21' author: Onur Mustafa Erdogan, Splunk status: production type: TTP description: |- - The following analytic detects modification of the PYTHONPATH environment variable in conjunction - with a package installation process. Python looks up the `sys.path` variable, which is generated - by combining user and site folders with `.pth` files and the value of the PYTHONPATH environment - variable, to determine which directories to use for importing modules. If an adversary is able to - control the value of PYTHONPATH, they can point it to an attacker-controlled directory and hijack - imported packages, achieving user-level persistence across future Python invocations and new shell - sessions. If confirmed malicious, this could result in arbitrary code execution every time Python - is invoked by the affected user. + The following analytic detects modification of the PYTHONPATH environment variable in conjunction with a package installation process. + Python looks up the `sys.path` variable, which is generated by combining user and site folders with `.pth` files and the value of the PYTHONPATH environment variable, to determine which directories to use for importing modules. + If an adversary is able to control the value of PYTHONPATH, they can point it to an attacker-controlled directory and hijack imported packages, achieving user-level persistence across future Python invocations and new shell sessions. + If confirmed malicious, this could result in arbitrary code execution every time Python is invoked by the affected user. data_source: - Sysmon EventID 1 AND Sysmon EventID 13 search: |- - `sysmon` EventID IN (1,13) AND (parent_process="*\\site-packages\\pip\\*" OR (registry_path="*PYTHONPATH" AND action="modified")) - | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(registry_path) as registry_path values(registry_value_data) as registry_value_data values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as dc_event_id by dest source process_id + `sysmon` + EventID IN (1,13) + ( + parent_process="*\\site-packages\\pip\\*" + OR + ( + registry_path="*PYTHONPATH" + action="modified" + ) + ) + + | stats count min(_time) as firstTime + max(_time) as lastTime + values(parent_process_id) as parent_process_id + values(parent_process_name) as parent_process_name + values(parent_process_path) as parent_process_path + values(parent_process) as parent_process + values(process_path) as process_path + values(process_name) as process_name + values(process) as process + values(registry_path) as registry_path + values(registry_value_data) as registry_value_data + dc(EventID) as dc_event_id + + by dest source process_id + | search dc_event_id>1 + + | table firstTime lastTime + parent_process_id parent_process_path parent_process_name parent_process + process_id process_path process_name process + registry_path registry_value_data + dest source + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `python_pythonpath_modification_during_package_installation_filter` @@ -44,11 +71,11 @@ drilldown_searches: earliest_offset: 7d latest_offset: "0" finding: - title: The PYTHONPATH environment variable was modified to $registry_value_data$ on $dest$ during package installation using $process$ + title: The PYTHONPATH environment variable [$registry_path$] was modified to the value of [$registry_value_data$] on [$dest$] during package installation using [$process$]. entity: field: dest type: system - score: 40 + score: 50 threat_objects: - field: process type: process @@ -73,7 +100,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1574.007/python_pythonpath_modification/python_pythonpath_modification.log + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1574.007/python_pythonpath_modification/python_pythonpath_modification.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml index 1888a7d043..43b5a52eaf 100644 --- a/detections/endpoint/python_site_hooks_creation_during_package_installation.yml +++ b/detections/endpoint/python_site_hooks_creation_during_package_installation.yml @@ -1,25 +1,54 @@ name: Python Site Hooks Creation During Package Installation id: efaf40f5-779f-4b48-a941-b7d1a7c931ed version: 1 -creation_date: '2026-07-23' -modification_date: '2026-08-18' +creation_date: '2026-08-21' +modification_date: '2026-08-21' author: Onur Mustafa Erdogan, Splunk status: production type: TTP description: |- - The following analytic detects the creation of a Python site hook file (`sitecustomize.py` or `usercustomize.py`) - within a `site-packages`/`dist-packages` directory in conjunction with a package installation process. Python's - `site` module loads these hooks from directories on `sys.path` before Python is executed. If an adversary manipulates - or plants one of these files, they can hijack the Python environment and execute their payload with every Python - invocation, achieving persistence on the victim endpoint. The VIPERTUNNEL backdoor was reported to abuse site hooks - in order to import and trigger DLL execution. If confirmed malicious, this could result in arbitrary code execution - every time Python is invoked on the compromised host. + The following analytic detects the creation of a Python site hook file (`sitecustomize.py` or `usercustomize.py`) within a `site-packages`/`dist-packages` directory in conjunction with a package installation process. + Python's `site` module loads these hooks from directories on `sys.path` before Python is executed. + If an adversary manipulates or plants one of these files, they can hijack the Python environment and execute their payload with every Python invocation, achieving persistence on the victim endpoint. + The VIPERTUNNEL backdoor was reported to abuse site hooks in order to import and trigger DLL execution. + If confirmed malicious, this could result in arbitrary code execution every time Python is invoked on the compromised host. data_source: - Sysmon EventID 1 AND Sysmon EventID 11 search: |- - `sysmon` EventID IN (1,11) AND (process="* install *" OR (file_path="*-packages\\*" AND action="created" AND (file_path="*sitecustomize.py" OR file_path="*usercustomize.py"))) - | stats count min(_time) as firstTime max(_time) as lastTime values(parent_process_id) as parent_process_id values(file_path) as file_path values(process_name) as process_name values(process) as process values(parent_process_name) as parent_process_name values(parent_process) as parent_process dc(EventID) as dc_event_id by dest source process_id + `sysmon` + EventID IN (1,11) + ( + process="* install *" + OR + ( + action="created" + file_path="*-packages\\*" + file_path IN ("*sitecustomize.py", "*usercustomize.py") + ) + ) + + | stats count min(_time) as firstTime + max(_time) as lastTime + values(parent_process_id) as parent_process_id + values(parent_process_path) as parent_process_path + values(parent_process_name) as parent_process_name + values(parent_process) as parent_process + values(process_path) as process_path + values(process_name) as process_name + values(process) as process + values(file_path) as file_path + values(file_name) as file_name + dc(EventID) as dc_event_id + by dest source process_id + | search dc_event_id>1 + + | table firstTime lastTime + parent_process_id parent_process_path parent_process_name parent_process + process_id process_path process_name process + file_path file_name + dest source + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `python_site_hooks_creation_during_package_installation_filter` @@ -43,7 +72,7 @@ drilldown_searches: earliest_offset: 7d latest_offset: "0" finding: - title: A Python site hook file $file_path$ was created on $dest$ during package installation using $process$ + title: A Python site hook file [$file_path$] was created on [$dest$] during package installation using [$process$]. entity: field: dest type: system @@ -53,6 +82,8 @@ threat_objects: type: process - field: file_path type: file_path + - field: file_name + type: file_name analytic_story: - Malicious Python Package Installation - Compromised Windows Host @@ -70,7 +101,7 @@ security_domain: endpoint tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1546/python_site_hooks_creation/python_site_hooks_creation.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: XmlWinEventLog test_type: unit diff --git a/stories/malicious_python_package_installation.yml b/stories/malicious_python_package_installation.yml index b05343eef8..d7d6635781 100644 --- a/stories/malicious_python_package_installation.yml +++ b/stories/malicious_python_package_installation.yml @@ -1,28 +1,20 @@ name: Malicious Python Package Installation id: 12e51c50-6b66-4ce7-83b8-95125ffd31e9 version: 1 -creation_date: '2026-07-23' -modification_date: '2026-07-23' +creation_date: '2026-08-21' +modification_date: '2026-08-21' author: Onur Mustafa Erdogan, Splunk status: production description: |- - This analytic story provides detection coverage for abuse of the Python package installation lifecycle, - including install-time code execution, persistence via `.pth` path configuration files, Python site hooks, - and PYTHONPATH environment variable manipulation. + This analytic story provides detection coverage for abuse of the Python package installation lifecycle, including install-time code execution, persistence via `.pth` path configuration files, Python site hooks, and PYTHONPATH environment variable manipulation. narrative: |- - Python's popularity, readable syntax, and extensive third-party library ecosystem make it an attractive target - for threat actors seeking to compromise developer devices and infrastructure. Malicious packages and supply-chain - attacks exploit the trust built into Python's packaging ecosystem to execute payloads at the moment of installation, - without any direct interaction from the victim. Adversaries abuse several native Python features to achieve this. + Python's popularity, readable syntax, and extensive third-party library ecosystem make it an attractive target for threat actors seeking to compromise developer devices and infrastructure. + Malicious packages and supply-chain attacks exploit the trust built into Python's packaging ecosystem to execute payloads at the moment of installation, without any direct interaction from the victim. Adversaries abuse several native Python features to achieve this. `setup.py` build scripts can leverage `distutils`/`setuptools` command classes to execute arbitrary code, including - network beacons, during package installation. Path configuration files (`.pth`) placed in `site-packages`/`dist-packages` - are executed on every subsequent Python invocation, providing persistence; this technique was used by the threat actor - group TeamPCP during the supply-chain compromise of the `litellm` package. Python's `site` module also loads `sitecustomize.py` - and `usercustomize.py` hook files from directories on `sys.path`, which adversaries can plant or manipulate to hijack - the Python environment and achieve persistence, as seen with the VIPERTUNNEL backdoor. Finally, adversaries who can - modify a user's `PYTHONPATH` environment variable can redirect module imports to attacker-controlled directories,achieving - user-level persistence across new shell sessions. This story detects these behaviors by correlating process creation, - file creation, and registry modification telemetry around Python package installation activity. + network beacons, during package installation. + Path configuration files (`.pth`) placed in `site-packages`/`dist-packages` are executed on every subsequent Python invocation, providing persistence; this technique was used by the threat actor group TeamPCP during the supply-chain compromise of the `litellm` package. Python's `site` module also loads `sitecustomize.py` and `usercustomize.py` hook files from directories on `sys.path`, which adversaries can plant or manipulate to hijack the Python environment and achieve persistence, as seen with the VIPERTUNNEL backdoor. + Finally, adversaries who can modify a user's `PYTHONPATH` environment variable can redirect module imports to attacker-controlled directories,achieving user-level persistence across new shell sessions. + This story detects these behaviors by correlating process creation, file creation, and registry modification telemetry around Python package installation activity. references: - https://blog.talosintelligence.com/the-serpents-tongue-luring-the-python-out-of-its-den/ category: