Detect Malicious Library in Elastic Security
Adversaries may rely on a user installing a malicious library to facilitate execution. Threat actors upload malware to package managers such as NPM and PyPI, or backdoor existing popular libraries through supply chain compromise. Users install these libraries without realizing they are malicious, bypassing initial access controls. Execution occurs via setup.py install-time scripts (Python), postinstall/preinstall lifecycle hooks (NPM/yarn), or malicious code embedded in library modules that executes on import. Common delivery vectors include typosquatting (e.g., 'reqeusts' vs 'requests'), dependency confusion attacks, compromised maintainer accounts, and first-use namespace squatting. Threat actors including Contagious Interview have leveraged malicious NPM and Python packages published to public registries to deliver infostealers, remote access tools, and BeaverTail/InvisibleFerret malware targeting software developers.
MITRE ATT&CK
- Tactic
- Execution
- Technique
- T1204 User Execution
- Sub-technique
- T1204.005 Malicious Library
- Canonical reference
- https://attack.mitre.org/techniques/T1204/005/
Elastic Detection Query
sequence by host.id with maxspan=5m
[
process where event.type == "start" and
(
process.parent.name in ("python.exe", "python3.exe", "python3", "node", "node.exe", "pip", "pip.exe", "pip3", "pip3.exe") or
process.parent.command_line like~ "*pip install*" or
process.parent.command_line like~ "*pip3 install*" or
process.parent.command_line like~ "*npm install*" or
process.parent.command_line like~ "*npm ci*" or
process.parent.command_line like~ "*yarn add*" or
process.parent.command_line like~ "*setup.py*"
) and
process.name in (
"cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe", "rundll32.exe",
"certutil.exe", "bitsadmin.exe", "wscript.exe", "cscript.exe", "regsvr32.exe",
"msiexec.exe", "schtasks.exe", "at.exe", "sc.exe", "reg.exe", "net.exe", "netsh.exe"
)
] by process.entity_id
union
sequence by host.id with maxspan=10m
[
network where event.type == "connection" and
process.name in ("python.exe", "python3.exe", "python3", "node", "node.exe") and
not destination.ip in ("127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16") and
not (
destination.domain like~ "*pypi.org" or
destination.domain like~ "*pythonhosted.org" or
destination.domain like~ "*npmjs.com" or
destination.domain like~ "*github.com" or
destination.domain like~ "*githubusercontent.com" or
destination.domain like~ "*anaconda.com" or
destination.domain like~ "*yarnpkg.com"
) and
destination.port not in (80, 443, 8080, 8443)
] by process.entity_id
union
sequence by host.id with maxspan=5m
[
file where event.type == "creation" and
process.name in ("python.exe", "python3.exe", "python3", "node", "node.exe", "pip", "pip.exe", "pip3", "pip3.exe") and
(
file.name like~ "*.exe" or file.name like~ "*.dll" or
file.name like~ "*.bat" or file.name like~ "*.ps1" or
file.name like~ "*.vbs" or file.name like~ "*.scr"
) and
(
file.path like~ "*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup*" or
file.path like~ "*\\AppData\\Local\\Temp\\*" or
file.path like~ "*\\Windows\\Temp\\*" or
file.path like~ "*\\Windows\\System32\\*" or
file.path like~ "*\\Windows\\SysWOW64\\*" or
file.path like~ "*\\ProgramData\\*"
)
] by process.entity_id Detects malicious library execution via three branches: (1) package managers or Python/Node spawning suspicious child processes indicative of setup.py install-time scripts or NPM postinstall hook abuse; (2) Python or Node making non-standard port external connections from code executed during or after library import (C2 callback); (3) package installers dropping executable or script artifacts into persistence-relevant filesystem locations. Covers supply chain compromise, typosquatting, dependency confusion, and Contagious Interview-style NPM/PyPI attacks.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate developer build tools or CI/CD pipelines that invoke shell scripts via setup.py or postinstall hooks (e.g., compiling native extensions with CFFI, running pytest, building C extensions with cmake). Tune by adding known-good build pipeline hostnames or process hashes.
- Data science environments (Jupyter, Anaconda) where Python spawns cmd.exe or PowerShell as part of legitimate environment management, conda package hooks, or notebook operations. Whitelist by user identity and machine context.
- Python or Node applications with intentional non-standard port outbound connections for legitimate services (IRC bots, game servers, IoT device management APIs). Suppress by destination IP/domain allowlist per environment.
- Legitimate test automation frameworks that install packages and subsequently run PowerShell or cmd scripts as part of the test harness (e.g., tox, nox, Makefile integration tests on Windows).
Other platforms for T1204.005
Testing Methodology
Validate this detection against 5 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Malicious Python Package via Local pip install (setup.py subprocess spawn)
Expected signal: Sysmon Event ID 1: Process Create with ParentImage=python.exe (pip runner), Image=cmd.exe, CommandLine containing 'whoami'. DeviceProcessEvents: InitiatingProcessFileName=python.exe with CommandLine containing 'setup.py', FileName=cmd.exe. The process tree root will be pip.exe -> python.exe -> cmd.exe.
- Test 2Malicious NPM Package with Postinstall Hook (Linux/macOS)
Expected signal: Sysmon for Linux or auditd: process creation with parent=node (npm runner), child=sh, CommandLine containing 'id > /tmp/npm_postinstall_test.txt'. If Sysmon for Linux is deployed: EventID=1, ParentImage path contains node, Image=/bin/sh. Linux audit log: execve syscall with parent node process.
- Test 3Python Library C2 Callback Simulation (Non-Standard Port)
Expected signal: Sysmon Event ID 3: Network Connection with Image=python.exe, DestinationIp=127.0.0.1, DestinationPort=4444. DeviceNetworkEvents: InitiatingProcessFileName=python.exe, RemotePort=4444. The connection will fail with ECONNREFUSED but the outbound attempt is still logged.
- Test 4Malicious Python Library Dropping Persistence Script to Startup Folder
Expected signal: Sysmon Event ID 11: File Create with Image=python.exe, TargetFilename=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\df00tech_test_persistence.vbs. DeviceFileEvents: InitiatingProcessFileName=python.exe, FileName=df00tech_test_persistence.vbs, FolderPath contains Startup.
- Test 5Simulated Typosquat Package Python Credential Harvester
Expected signal: Sysmon Event ID 15 (FileCreateStreamHash) or Event ID 11 if file is created. DeviceFileEvents: InitiatingProcessFileName=python.exe accessing FolderPath containing 'Google\Chrome\User Data'. This also fires the hunting query for credential store access.
References (10)
- https://attack.mitre.org/techniques/T1204/005/
- https://securitylabs.datadoghq.com/articles/malicious-pypi-package-targeting-highly-specific-macos-machines/
- https://www.fortinet.com/blog/threat-research/malicious-packages-hiddin-in-npm
- https://www.sentinelone.com/labs/contagious-interview-north-korean-threat-actors-use-clickfix-to-deliver-updated-eavesdropper-malware/
- https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/advanced-hunting-devicenetworkevents-table
- https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/advanced-hunting-devicefileevents-table
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1204.005/T1204.005.md
- https://osv.dev
- https://pypi.org/project/pip-audit/
- https://docs.npmjs.com/cli/v10/commands/npm-audit
Unlock Pro Content
Get the full detection package for T1204.005 including response playbook, investigation guide, and atomic red team tests.