Detect Malicious Library in Splunk
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/
SPL Detection Query
(index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
(ParentImage="*\\pip.exe" OR ParentImage="*\\pip3.exe" OR ParentImage="*\\python.exe" OR ParentImage="*\\python3.exe" OR ParentImage="*\\node.exe" OR ParentImage="*\\npm.cmd"
OR ParentCommandLine="*pip install*" OR ParentCommandLine="*pip3 install*" OR ParentCommandLine="*npm install*" OR ParentCommandLine="*npm ci*" OR ParentCommandLine="*yarn add*" OR ParentCommandLine="*setup.py*")
(Image="*\\cmd.exe" OR Image="*\\powershell.exe" OR Image="*\\pwsh.exe" OR Image="*\\mshta.exe" OR Image="*\\rundll32.exe"
OR Image="*\\certutil.exe" OR Image="*\\bitsadmin.exe" OR Image="*\\wscript.exe" OR Image="*\\cscript.exe" OR Image="*\\regsvr32.exe"
OR Image="*\\msiexec.exe" OR Image="*\\schtasks.exe" OR Image="*\\sc.exe" OR Image="*\\reg.exe")
| eval DetectionBranch="PackageInstallSpawnedSuspiciousProcess"
| eval NetworkDest="", DroppedFile="")
| append [
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
(Image="*\\python.exe" OR Image="*\\python3.exe" OR Image="*\\node.exe")
NOT (DestinationPort=80 OR DestinationPort=443 OR DestinationPort=8080 OR DestinationPort=8443)
NOT (cidrmatch("10.0.0.0/8", DestinationIp) OR cidrmatch("172.16.0.0/12", DestinationIp) OR cidrmatch("192.168.0.0/16", DestinationIp) OR cidrmatch("127.0.0.0/8", DestinationIp))
NOT (DestinationHostname="*pypi.org" OR DestinationHostname="*pythonhosted.org" OR DestinationHostname="*npmjs.com" OR DestinationHostname="*github.com" OR DestinationHostname="*githubusercontent.com" OR DestinationHostname="*anaconda.com")
| eval DetectionBranch="MaliciousLibraryC2Callback"
| eval NetworkDest=DestinationIp . ":" . DestinationPort, DroppedFile="", ParentImage="", ParentCommandLine=""]
| append [
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=11
(Image="*\\python.exe" OR Image="*\\python3.exe" OR Image="*\\node.exe" OR Image="*\\pip.exe" OR Image="*\\pip3.exe")
(TargetFilename="*.exe" OR TargetFilename="*.dll" OR TargetFilename="*.bat" OR TargetFilename="*.ps1" OR TargetFilename="*.vbs" OR TargetFilename="*.scr")
(TargetFilename="*\\Startup\\*" OR TargetFilename="*AppData\\Local\\Temp\\*" OR TargetFilename="*Windows\\Temp\\*" OR TargetFilename="*System32\\*" OR TargetFilename="*SysWOW64\\*" OR TargetFilename="*ProgramData\\*")
| eval DetectionBranch="PackageInstallerDroppedExecutable"
| eval DroppedFile=TargetFilename, NetworkDest="", ParentImage="", ParentCommandLine=""]
| eval SubjectProcess=coalesce(Image, TargetFilename)
| table _time, host, User, SubjectProcess, CommandLine, ParentImage, ParentCommandLine, NetworkDest, DroppedFile, DetectionBranch
| sort - _time Detects malicious library execution using Sysmon events across three branches via append: EventCode=1 (process create) for package managers spawning LOLBins via setup.py or postinstall hooks; EventCode=3 (network connect) for Python/Node runtimes making outbound connections to non-registry hosts on non-web ports; EventCode=11 (file create) for package installers writing executables or scripts to persistence-relevant paths. The cidrmatch function filters RFC-1918 internal destinations accurately. All branches union into a single result set with a DetectionBranch label for triage.
Data Sources
Required Sourcetypes
False Positives & Tuning
- Native extension builds (numpy, cryptography, lxml) spawn MSVC or GCC toolchain binaries — typically from a build environment parent; baseline known build hosts
- node-gyp compiles native addons during npm install and spawns Python and cmd.exe — filter by node-gyp in ParentCommandLine or DroppedFile paths in node_modules build directories
- Legitimate Python scripts making API calls to internal microservices on non-standard ports — apply host-based allowlists for known developer workstations or service accounts
- CI/CD runner hosts executing pip/npm installs as part of build pipelines — apply host-based suppression for known build agent hostnames
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.