Detection rules › Splunk

Python Network Traffic During Package Build

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

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.

Known false positives

  • Python packages may contact software repositories, mirror sites during build time. Investigate the destination and package content to determine legitimacy.

MITRE ATT&CK coverage

Telemetry coverage

Rule body

name: Python Network Traffic During Package Build
id: 03c9c504-2294-44da-8180-beefe1ca8ba8
version: 1
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.
data_source:
    - Sysmon EventID 1 AND Sysmon EventID 3
search: |-
    `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*" dest_ip=*
    
    | 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`
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/
intermediate_findings:
    entities:
        - field: dest
          type: system
          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
    - 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

Stages and Predicates

Stage 1: search

`sysmon`
(
    EventID=1
    (
        process="*_in_process.py*"
        OR
        process_name=python.exe
    )
)
OR
(
    EventID=3
    dest_ip!=""
    process_name=python.exe
)

Stage 2: eval

| eval dest=if(EventID=3, Computer, dest)
dest =
ifEventID = 3Computer
elsedest

Stage 3: 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(dest_ip) as dest_ip
              values(dest_host) as dest_host

  by dest source process_id

Stage 4: search

| search process="* build_wheel*" dest_ip=*

Stage 5: table

| 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

Stage 6: search

| `security_content_ctime(firstTime)`

Stage 7: search

| `security_content_ctime(lastTime)`

Stage 8: search

| `python_network_traffic_during_package_build_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventIDeq
  • 1 corpus 242 (splunk 226, kusto 15, elastic 1)
  • 3 corpus 25 (splunk 15, kusto 8, chronicle 2)
field:"EventID" kind:eq
dest_ipeq
  • * corpus 2 (splunk 2)
field:"dest_ip" kind:eq value:"*"
dest_ipne
  • ""
field:"dest_ip" kind:ne
processeq
  • "* build_wheel*"
  • "*_in_process.py*"
field:"CommandLine" kind:eq
process_nameeq
  • python.exe corpus 2 (splunk 2)
field:"process_name" kind:eq value:"python.exe"