Skip to content

[New Rules] New Terms rules for malicious Python/Pickle model activity on macOS#5780

Open
DefSecSentinel wants to merge 9 commits intomainfrom
pickle-python-new-terms
Open

[New Rules] New Terms rules for malicious Python/Pickle model activity on macOS#5780
DefSecSentinel wants to merge 9 commits intomainfrom
pickle-python-new-terms

Conversation

@DefSecSentinel
Copy link
Contributor

@DefSecSentinel DefSecSentinel commented Feb 25, 2026

Summary

Adds three new_terms SIEM detection rules for macOS to close the detection gap identified in ia-trade-team#666 where malicious pickle/PyTorch model files execute arbitrary commands via Python's __reduce__ deserialization without triggering existing GenAI-parent-gated endpoint rules.

  • First Time Python Spawned a Shell on Host — Detects when a Python process spawns a shell with -c for the first time on a host (7-day lookback). Covers reverse shells, reconnaissance, and post-exploitation commands triggered by malicious model loading.
  • First Time Python Accessed Sensitive Credential Files — Detects when a Python process opens sensitive credential files (SSH keys, AWS creds, keychain, browser cookies) for the first time on a host. Uses Elastic Defend's open event action which is pre-filtered to sensitive file paths.
  • First Time Python Created a LaunchAgent or LaunchDaemon — Detects when a Python process creates a persistence mechanism via LaunchAgent/LaunchDaemon for the first time on a host. Uses the logs-endpoint.events.persistence-* index to capture plist metadata (program arguments, run-at-load, keep-alive).

Background

PyTorch's .pt/.pth model format uses pickle serialization, which allows arbitrary code execution via __reduce__ on deserialization. This is a permanent, architectural flaw — not a patchable bug. Research confirmed that when python3 directly loads a malicious model (the most realistic data scientist scenario), none of the existing cross-platform GenAI endpoint rules fire because they gate on a GenAI parent process (ollama, cursor, lmstudio, etc.).

The new_terms rule type is ideal here because the individual behaviors (shell spawn, credential access, plist creation) are individually high false-positive for pattern matching, but a first occurrence on a host is a strong signal of compromise.

Related

Made with Cursor

…y on macOS

Adds three new_terms SIEM detection rules to close the detection gap identified in ia-trade-team#666 where malicious pickle/PyTorch model files execute arbitrary commands via Python deserialization without triggering existing GenAI-parent-gated endpoint rules.

Co-authored-by: Cursor <cursoragent@cursor.com>
@tradebot-elastic
Copy link

tradebot-elastic commented Feb 25, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@github-actions
Copy link
Contributor

Rule: New - Guidelines

These guidelines serve as a reminder set of considerations when proposing a new rule.

Documentation and Context

  • Detailed description of the rule.
  • List any new fields required in ECS/data sources.
  • Link related issues or PRs.
  • Include references.

Rule Metadata Checks

  • creation_date matches the date of creation PR initially merged.
  • min_stack_version should support the widest stack versions.
  • name and description should be descriptive and not include typos.
  • query should be inclusive, not overly exclusive, considering performance for diverse environments. Non ecs fields should be added to non-ecs-schema.json if not available in an integration.
  • min_stack_comments and min_stack_version should be included if the rule is only compatible starting from a specific stack version.
  • index pattern should be neither too specific nor too vague, ensuring it accurately matches the relevant data stream (e.g., use logs-endpoint.process-* for process data).
  • integration should align with the index. If the integration is newly introduced, ensure the manifest, schemas, and new_rule.yaml template are updated.
  • setup should include the necessary steps to configure the integration.
  • note should include any additional information (e.g. Triage and analysis investigation guides, timeline templates).
  • tags should be relevant to the threat and align/added to the EXPECTED_RULE_TAGS in the definitions.py file.
  • threat, techniques, and subtechniques should map to ATT&CK always if possible.

New BBR Rules

  • building_block_type should be included if the rule is a building block and the rule should be located in the rules_building_block folder.
  • bypass_bbr_timing should be included if adding custom lookback timing to the rule.

Testing and Validation

  • Provide evidence of testing and detecting the expected threat.
  • Check for existence of coverage to prevent duplication.

@tradebot-elastic
Copy link

tradebot-elastic commented Feb 25, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Feb 26, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Feb 26, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Feb 26, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

- Update descriptions across all three rules to not over-attribute to
  pickle/PyTorch — these rules detect any malicious Python activity
  (scripts, compromised dependencies, model deserialization, etc.)
- Simplify process.name from explicit enumeration to python* wildcard
  since KQL matching is case-insensitive
- Update investigation guides to reflect broader scope of potential
  attack vectors

Made-with: Cursor
@tradebot-elastic
Copy link

tradebot-elastic commented Feb 27, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Feb 27, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Mar 2, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

@tradebot-elastic
Copy link

tradebot-elastic commented Mar 4, 2026

⛔️ Test failed

Results
  • ❌ First Time Python Accessed Sensitive Credential Files (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Created a LaunchAgent or LaunchDaemon (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta
  • ❌ First Time Python Spawned a Shell on Host (kuery)
    • coverage_issue: no_rta
    • stack_validation_failed: no_rta

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants