Detection rules › Splunk

Python Site Hooks Creation During Package Installation

Status
production
Severity
medium
Group by
channel, dest, process_id
Author
Onur Mustafa Erdogan, Splunk
Source
github.com/splunk/security_content

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.

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.

MITRE ATT&CK coverage

Telemetry coverage

Rule body

name: Python Site Hooks Creation During Package Installation
id: efaf40f5-779f-4b48-a941-b7d1a7c931ed
version: 1
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.
data_source:
    - Sysmon EventID 1 AND Sysmon EventID 11
search: |-
    `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`
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/
finding:
    title: A Python site hook file [$file_path$] was created on [$dest$] during package installation using [$process$].
    entity:
        field: dest
        type: system
        score: 40
threat_objects:
    - field: process
      type: process
    - field: file_path
      type: file_path
    - field: file_name
      type: file_name
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

Stages and Predicates

Stage 1: search

`sysmon`
EventID IN (1,11)
(
    process="* install *"
    OR
    (
        action="created"
        file_path="*-packages\\*"
        file_path IN ("*sitecustomize.py", "*usercustomize.py")
    )
)

Stage 2: stats

| 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

Stage 3: search

| search dc_event_id>1

Stage 4: table

| 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

Stage 5: search

| `security_content_ctime(firstTime)`

Stage 6: search

| `security_content_ctime(lastTime)`

Stage 7: search

| `python_site_hooks_creation_during_package_installation_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventIDin
  • 1 corpus 242 (splunk 226, kusto 15, elastic 1)
  • 11 corpus 27 (splunk 25, kusto 2)
field:"EventID" kind:in
actioneq
  • "created" corpus 4 (splunk 3, panther 1)
field:"action" kind:eq
dc_event_idgt
  • 1 corpus 3 (splunk 3)
field:"dc_event_id" kind:gt value:"1"
file_patheq
  • "*-packages\\*"
field:"TargetFilename" kind:eq
file_pathin
  • "*sitecustomize.py"
  • "*usercustomize.py"
field:"TargetFilename" kind:in
processeq
  • "* install *" corpus 2 (splunk 2)
field:"CommandLine" kind:eq