Detect Compromise Software Dependencies and Development Tools in Google Chronicle
Adversaries manipulate software dependencies and development tools prior to receipt by a final consumer to compromise data or systems. This includes injecting malicious code into popular open source packages (npm, PyPI, RubyGems), registering typosquatted or abandoned package names, and poisoning CI/CD pipeline components such as GitHub Actions. Malicious packages commonly use preinstall/postinstall lifecycle hooks to execute arbitrary OS commands at install time, enabling immediate credential theft, reverse shell establishment, or persistent implant deployment. Detection focuses on package manager processes spawning unexpected child processes, outbound network connections from package manager child processes, CI/CD workflow file modifications, and installation from non-standard or suspicious registries.
MITRE ATT&CK
- Tactic
- Initial Access
- Technique
- T1195 Supply Chain Compromise
- Sub-technique
- T1195.001 Compromise Software Dependencies and Development Tools
- Canonical reference
- https://attack.mitre.org/techniques/T1195/001/
YARA-L Detection Query
rule t1195_001_supply_chain_compromise {
meta:
author = "Argus Detection Engineering"
description = "Detects T1195.001 supply chain compromise: package manager hook abuse spawning suspicious processes, unexpected external registry connections, and CI/CD pipeline file modifications"
mitre_attack_tactic = "Initial Access"
mitre_attack_technique = "T1195.001"
mitre_attack_technique_name = "Compromise Software Dependencies and Development Tools"
severity = "HIGH"
confidence = "MEDIUM"
platform = "Windows, Linux, macOS"
data_sources = "EDR, Process Telemetry, File Monitoring, Network Telemetry"
version = "1.0"
events:
(
// Arm 1a: Package manager process spawning suspicious OS-level child process
$e1.metadata.event_type = "PROCESS_LAUNCH"
and (
re.regex($e1.principal.process.file.full_path,
`(?i)(npm\.cmd|npm\.exe|node\.exe|pip\.exe|pip3\.exe|python\.exe|python3\.exe|pipx\.exe|yarn\.exe|pnpm\.exe|gem\.exe|bundle\.exe|cargo\.exe|go\.exe|nuget\.exe|dotnet\.exe)$`)
or re.regex($e1.principal.process.command_line,
`(?i)(postinstall|preinstall|install\.js|setup\.py|node-pre-gyp)`)
)
and (
re.regex($e1.target.process.file.full_path,
`(?i)(powershell\.exe|pwsh\.exe|cmd\.exe|wscript\.exe|cscript\.exe|mshta\.exe|rundll32\.exe|regsvr32\.exe|certutil\.exe|bitsadmin\.exe|curl\.exe|wget\.exe)$`)
or re.regex($e1.target.process.command_line,
`(?i)(/dev/tcp|base64 -d|base64 --decode|bash -i|sh -i|nc -e|ncat -e|python -c|perl -e|ruby -e|DownloadString|DownloadFile|Invoke-Expression|IEX\(|curl http|wget http|--registry http)`)
)
)
or
(
// Arm 2: Package manager process making unexpected external network connection
$e1.metadata.event_type = "NETWORK_CONNECTION"
and re.regex($e1.principal.process.file.full_path,
`(?i)(npm\.cmd|npm\.exe|node\.exe|pip\.exe|pip3\.exe|python\.exe|python3\.exe|yarn\.exe|pnpm\.exe|gem\.exe|bundle\.exe|cargo\.exe|go\.exe)$`)
and $e1.network.direction = "OUTBOUND"
and not re.regex($e1.target.hostname,
`(?i)(registry\.npmjs\.org|pypi\.org|files\.pythonhosted\.org|rubygems\.org|crates\.io|nuget\.org|pkg\.go\.dev|proxy\.golang\.org|yarnpkg\.com|registry\.yarnpkg\.com)`)
)
or
(
// Arm 3: CI/CD pipeline configuration file creation or modification
$e1.metadata.event_type = "FILE_CREATION"
and (
re.regex($e1.target.file.full_path,
`(?i)(\.github/workflows|\.gitlab-ci|Jenkinsfile|\.circleci|\.travis|azure-pipelines)`)
or re.regex($e1.target.file.full_path,
`(?i)(Makefile|CMakeLists\.txt|build\.gradle|pom\.xml)$`)
)
)
condition:
$e1
} Google Chronicle YARA-L 2.0 rule detecting T1195.001 supply chain compromise across three detection arms using UDM normalized events: (1) package manager processes (npm, pip, yarn, gem, cargo, dotnet, go) or lifecycle hook command patterns spawning suspicious OS-level child processes (PowerShell, cmd, LOLBins) or executing commands with reverse shell/download indicators; (2) package manager processes making outbound NETWORK_CONNECTION events to destinations outside the known-good registry allowlist, covering both typosquatted package registry hijacking and malicious postinstall C2 beaconing; (3) FILE_CREATION events targeting GitHub Actions workflow directories, GitLab CI, Jenkinsfile, Azure Pipelines, and common build configuration files indicating CI/CD pipeline poisoning. Maps to MITRE ATT&CK Initial Access tactic.
Data Sources
Required Tables
False Positives & Tuning
- Native npm package compilation via node-gyp will trigger Arm 1 when node.exe spawns cmd.exe or sh to invoke C/C++ compilers during postinstall — add known developer workstation hostnames or build agent principals to an exception list, or filter on process.command_line patterns matching known compiler invocations (cl.exe, gcc, make)
- Trusted dependency management automation (Dependabot, Renovate Bot, GitHub Actions bot) regularly creates and modifies workflow YAML files and build configurations as part of automated dependency update PRs — correlate Arm 3 hits against known automation service account principal.user.userid values
- Corporate package proxy servers (Artifactory, Nexus, Verdaccio) used as internal npm/pip/gem mirrors will generate Arm 2 hits when package manager processes connect to internal proxy hostnames not included in the external registry allowlist — extend the negative regex in Arm 2 with known internal proxy domain patterns
Other platforms for T1195.001
Testing Methodology
Validate this detection against 4 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 1Simulated Malicious npm postinstall Hook
Expected signal: Sysmon Event ID 1: npm.cmd spawning cmd.exe with CommandLine containing 'whoami'. Sysmon Event ID 11: file creation at %TEMP%\argus-npm-test.txt. DeviceProcessEvents: InitiatingProcessFileName=npm.cmd, FileName=cmd.exe.
- Test 2Malicious pip setup.py Simulating Credential Exfiltration Pattern
Expected signal: Sysmon for Linux (or auditd): process creation with ParentProcess=python3/pip, ChildProcess=id or sh. Auditd syscall execve with ppid of pip process. Syslog: process accounting entry for 'id' with parent pip.
- Test 3Simulated GitHub Actions Workflow Poisoning
Expected signal: Sysmon Event ID 11 (FileCreated): TargetFilename ending in .github\workflows\ci.yml, InitiatingProcessFileName=cmd.exe. DeviceFileEvents: FileName=ci.yml, FolderPath contains .github/workflows, ActionType=FileCreated.
- Test 4npm Package Install from Non-Standard Registry (Registry Confusion)
Expected signal: Sysmon EventCode=3 (Network Connection): Image=node, DestinationIp=127.0.0.1, DestinationPort=4873, DestinationHostname not in standard registry allowlist. DeviceNetworkEvents: InitiatingProcessFileName=node, RemotePort=4873.
References (12)
- https://attack.mitre.org/techniques/T1195/001/
- https://www.paloaltonetworks.com/blog/cloud-security/github-actions-worm-dependencies/
- https://unit42.paloaltonetworks.com/github-actions-supply-chain-attack
- https://checkmarx.com/zero-post/python-pypi-supply-chain-attack-colorama/
- https://thehackernews.com/2024/09/hackers-hijack-22000-removed-pypi.html
- https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-04-Poisoned-Pipeline-Execution
- https://hackread.com/backdoors-python-npm-packages-windows-linux/
- https://www.bitdefender.com/en-gb/blog/hotforsecurity/popular-npm-repositories-compromised-in-man-in-the-middle-attack
- https://www.trendmicro.com/vinfo/dk/security/news/cybercrime-and-digital-threats/hacker-infects-node-js-package-to-steal-from-bitcoin-wallets
- https://checkmarx.com/blog/new-technique-to-trick-developers-detected-in-an-open-source-supply-chain-attack/
- https://cyberpress.org/malicious-npm-and-pypi-packages-disguised-as-dev-tools
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1195.001/T1195.001.md
Unlock Pro Content
Get the full detection package for T1195.001 including response playbook, investigation guide, and atomic red team tests.