Australian Federal Police have arrested and charged two young men alleged to be members of TeamPCP, a hacking collective tied to a string of far-reaching developer supply-chain attacks. While arrests make headlines, the operational reality for defenders is this: the infrastructure, tooling, and — most importantly — the compromised developer credentials and poisoned packages from campaigns like this do not disappear when handcuffs click. Every organization that pulls dependencies from npm, PyPI, or public Git repositories, and every team running CI/CD pipelines with long-lived tokens, should treat this as a forcing function to audit their software supply chain for compromise.
This post breaks down TeamPCP's known developer-focused tradecraft, provides production-ready detections for the behaviors this group relies on, and gives you a concrete remediation playbook for hardening your build pipeline.
Who Is TeamPCP and Why Should Defenders Care?
TeamPCP is a financially and ideologically motivated threat group that first gained notoriety for opportunistic attacks against misconfigured cloud-native infrastructure — exposed Docker APIs, Kubernetes dashboards, Redis and Jupyter instances — typically monetized through cryptomining and data theft. What elevated them from nuisance to strategic threat was their pivot into supply-chain operations targeting developers directly:
- Compromising developer accounts (GitHub, npm, PyPI) through credential phishing, token theft from infected workstations, and abuse of leaked secrets in public repositories.
- Publishing malicious packages or backdoored versions of legitimate packages to public registries, inheriting the trust of downstream consumers.
- Stealing CI/CD secrets — npm publish tokens, PyPI API tokens, GitHub PATs, SSH keys, and cloud credentials — from build agents and developer endpoints.
- Chaining compromises: one stolen maintainer token becomes a poisoned package, which becomes thousands of downstream workstation infections, which becomes more stolen tokens. This recursive amplification is precisely why supply-chain actors are prioritized by law enforcement.
The arrest of alleged members disrupts the humans, but the technique is now well-documented and copycat-ready. Your detection strategy must assume the next crew is already operating.
Technical Analysis: The Developer Supply-Chain Attack Chain
No CVE is associated with this campaign — this is tradecraft, not a patchable bug. The attack chain defenders should model:
Stage 1 — Initial Access to Developer Assets
- Phishing or infostealer malware targeting developers to harvest session cookies and tokens.
- Scanning public repos and CI logs for leaked
.npmrctokens, PyPI credentials, or GitHub PATs. - Compromising maintainer accounts lacking phishing-resistant 2FA.
Stage 2 — Package Poisoning / Registry Abuse
- Publishing a new malicious version of a hijacked package, or a typosquatted/dependency-confusion package.
- Malicious logic typically lives in lifecycle install scripts (
preinstall,install,postinstallinpackage.json, orsetup.pyexecution in Python), which execute with the developer's privileges at install time — before any code review of runtime behavior.
Stage 3 — Execution & Credential Harvesting on the Endpoint
- Install scripts spawn shells (
sh -c,bash -i), download second stages (curl | bash,wgetpiped to an interpreter), or decode obfuscated payloads (base64 -d). - Payloads read well-known credential locations:
~/.npmrc,~/.pypirc,~/.aws/credentials,~/.ssh/,~/.git-credentials, browser stores, and.envfiles.
Stage 4 — Exfiltration & Propagation
- Stolen tokens are exfiltrated over HTTPS to attacker infrastructure or webhook-style services.
- Fresh tokens enable publishing more malicious packages — the recursion continues.
Exploitation status: This is confirmed real-world, actively prosecuted criminal activity — not theoretical. Law enforcement action confirms operational maturity.
Detection & Response
The detections below target the behavioral choke points every developer supply-chain attack must traverse: package managers spawning shells, and processes reading developer credential stores. These are high-fidelity in most environments — developers legitimately run npm install, but npm spawning bash -i or reading ~/.aws/credentials is almost never legitimate.
Sigma Rules
---
title: Package Manager Spawning Shell or Downloader
tid: 3f9a1c7e-2b4d-4e8f-a6c1-9d0e5b7a2f31
status: experimental
description: Detects npm, node, pip, or yarn spawning shells, downloaders, or script interpreters — a hallmark of malicious package install scripts (TeamPCP-style supply-chain tradecraft).
references:
- https://www.bleepingcomputer.com/news/security/australia-arrests-alleged-teampcp-hackers-behind-supply-chain-attacks/
- https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1195.002
- attack.execution
- attack.t1059
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\node.exe'
- '\npm.cmd'
- '\npm.exe'
- '\yarn.exe'
- '\pnpm.exe'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\curl.exe'
- '\wget.exe'
- '\certutil.exe'
- '\bitsadmin.exe'
condition: selection_parent and selection_child
falsepositives:
- Rare legitimate native-module builds (node-gyp) invoking cmd.exe
level: high
---
title: Shell or Downloader Child of Package Manager (Linux)
id: 8c2e5d41-7a3b-4f69-9c12-5e6a8d0b1347
status: experimental
description: Detects Linux package managers (npm, pip, yarn, pip3) spawning interactive shells, base64 decoders, or curl/wget piping patterns consistent with malicious postinstall payloads.
references:
- https://www.bleepingcomputer.com/news/security/australia-arrests-alleged-teampcp-hackers-behind-supply-chain-attacks/
- https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1195.002
- attack.execution
- attack.t1059.004
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/npm'
- '/node'
- '/pip'
- '/pip3'
- '/yarn'
selection_child_img:
Image|endswith:
- '/bash'
- '/sh'
- '/dash'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/python'
- '/python3'
selection_suspicious_cli:
CommandLine|contains:
- 'base64 -d'
- 'base64 --decode'
- '/dev/tcp/'
- '| bash'
- '| sh'
- 'curl -s'
- 'wget -q'
condition: selection_parent and (selection_child_img or selection_suspicious_cli)
falsepositives:
- Build scripts that fetch assets during npm install in CI (tune with CI host allowlist)
level: high
---
title: Developer Credential Store Access by Non-Standard Process
id: 5b1d8f36-4c7a-4e21-bf83-2a9c6d4e7085
status: experimental
description: Detects processes reading developer credential files (.npmrc, .pypirc, AWS credentials, git-credentials, .env files) where the accessing process is not the expected toolchain — indicative of token harvesting after supply-chain compromise.
references:
- https://www.bleepingcomputer.com/news/security/australia-arrests-alleged-teampcp-hackers-behind-supply-chain-attacks/
- https://attack.mitre.org/techniques/T1552/001/
- https://attack.mitre.org/techniques/T1528/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.credential_access
- attack.t1552.001
- attack.t1528
logsource:
category: file_event
product: linux
detection:
selection_target:
TargetFilename|contains:
- '/.npmrc'
- '/.pypirc'
- '/.aws/credentials'
- '/.git-credentials'
- '/.ssh/id_rsa'
- '/.ssh/id_ed25519'
filter_legit:
Image|endswith:
- '/npm'
- '/node'
- '/git'
- '/ssh'
- '/aws'
- '/pip'
- '/pip3'
- '/python3'
condition: selection_target and not filter_legit
falsepositives:
- Backup agents and EDR scanners (allowlist by known binary hash)
level: high
KQL — Microsoft Sentinel / Defender Hunt
This query hunts across Windows and Linux endpoints (via MDE) for the two highest-fidelity behaviors: package managers spawning shells/downloaders, and unusual processes touching developer credential files. Run it over the last 30 days across all developer workstations and build agents.
// Hunt 1: Package managers spawning shells, downloaders, or decoders
let PackageManagers = dynamic(["node.exe","npm.cmd","npm.exe","yarn.exe","pnpm.exe","npm","pip","pip3","yarn","node"]);
let SuspiciousChildren = dynamic(["cmd.exe","powershell.exe","pwsh.exe","curl.exe","wget.exe","certutil.exe","bash","sh","dash","curl","wget","nc","ncat","python","python3"]);
DeviceProcessEvents
| where TimeGenerated > ago(30d)
| where InitiatingProcessFileName in~ (PackageManagers)
| where FileName in~ (SuspiciousChildren)
or ProcessCommandLine has_any ("base64 -d", "/dev/tcp/", "| bash", "| sh", "IEX", "DownloadString")
| project TimeGenerated, DeviceName, AccountName,
Parent = InitiatingProcessFileName,
ParentCmd = InitiatingProcessCommandLine,
Child = FileName, ChildCmd = ProcessCommandLine, SHA256
| order by TimeGenerated desc;
// Hunt 2: Non-toolchain processes accessing developer credential stores
let CredPaths = dynamic(["/.npmrc", "/.pypirc", "/.aws/credentials", "/.git-credentials", "/.ssh/id_rsa", "/.ssh/id_ed25519", "/.env"]);
let ExpectedReaders = dynamic(["npm","node","git","ssh","aws","pip","pip3","python3","code","code.exe","msedgedriver"]);
DeviceFileEvents
| where TimeGenerated > ago(30d)
| where FolderPath has_any (CredPaths)
| where ActionType in ("FileCreated", "FileModified")
or (ActionType == "FileAccessed" and not (InitiatingProcessFileName in~ (ExpectedReaders)))
| project TimeGenerated, DeviceName, AccountName, ActionType,
FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by TimeGenerated desc;
Tune Hunt 2 by allowlisting your EDR, backup, and DLP agents by SHA256 — credential-file reads from unknown binaries on developer endpoints are almost always worth a ticket.
Velociraptor VQL — Endpoint Hunt Artifact
Use this as a client hunt across developer workstations and build runners to catch live execution of malicious install payloads and staged credential theft:
-- Hunt: Package manager spawning shells/downloaders + credential file staging
-- TeamPCP-style developer supply-chain tradecraft
LET suspicious_children = '''(?i)(bash|sh|dash|cmd\.exe|powershell|pwsh|curl|wget|nc|ncat|certutil)'''
LET suspicious_cli = '''(?i)(base64\s+(-d|--decode)|/dev/tcp/|\|\s*(ba)?sh|curl\s+-s|wget\s+-q|DownloadString|IEX)'''
SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE (CommandLine =~ suspicious_cli OR Name =~ suspicious_children)
AND Ppid IN (
SELECT Pid FROM pslist()
WHERE Name =~ '(?i)^(node|npm|npm\.cmd|yarn|pnpm|pip|pip3)(\.exe)?$'
OR Exe =~ '(?i)/(node|npm|pip3?|yarn)$'
)
Pair with a follow-up artifact that globs for recently modified credential files — a useful tripwire for token access during a suspicious install window:
-- Hunt: Recently modified developer credential files (potential theft staging)
SELECT FullPath, Size, Mtime, Atime
FROM glob(globs=[
'/home/*/.npmrc',
'/home/*/.pypirc',
'/home/*/.aws/credentials',
'/home/*/.git-credentials',
'/root/.npmrc',
'/root/.aws/credentials'
])
WHERE Mtime > now() - 86400 * 7
ORDER BY Mtime DESC
Audit Script — Developer Workstation / Build Agent (Bash)
Run this on developer endpoints and CI runners to enumerate the highest-risk exposure surface: globally installed packages with install scripts, exposed tokens in config files, and recently installed packages that warrant review.
#!/usr/bin/env bash
# supply_chain_audit.sh — Audit dev host for supply-chain exposure (TeamPCP-style TTPs)
set -uo pipefail
echo "=== [1] Global npm packages (review for anything unexpected) ==="
command -v npm >/dev/null && npm ls -g --depth=0 2>/dev/null || echo "npm not installed"
echo -e "\n=== [2] Local packages with install lifecycle scripts (highest risk) ==="
if [ -d node_modules ]; then
grep -rl '"preinstall"\|"postinstall"\|"install"' node_modules/*/package.json 2>/dev/null \
| head -50
else
echo "No node_modules in cwd — run from project root"
fi
echo -e "\n=== [3] Pip packages installed in last 30 days (user site) ==="
find ~/.local/lib -maxdepth 4 -name "*.dist-info" -mtime -30 2>/dev/null | head -30
echo -e "\n=== [4] Exposed plaintext tokens in developer config files ==="
for f in ~/.npmrc ~/.pypirc ~/.git-credentials ~/.netrc ~/.aws/credentials; do
if [ -f "$f" ]; then
perms=$(stat -c '%a' "$f" 2>/dev/null || stat -f '%Lp' "$f")
echo "FOUND: $f (perms: $perms) — $(grep -c 'token\|password\|_auth' "$f" 2>/dev/null) secret-looking entries"
[ "$perms" != "600" ] && echo " [!] WARNING: permissions should be 600"
fi
done
echo -e "\n=== [5] .env files with world/group-readable permissions ==="
find ~ -maxdepth 4 -name ".env*" -perm /044 2>/dev/null | head -20
echo -e "\n=== [6] Recent suspicious shell history (pipe-to-shell patterns) ==="
grep -hE 'curl.*\| *(ba)?sh|wget.*\| *(ba)?sh|base64 -d' ~/.bash_history ~/.zsh_history 2>/dev/null | tail -20
echo -e "\n=== Audit complete. Rotate any tokens found in [4] if compromise is suspected. ==="
Remediation & Hardening Playbook
Supply-chain defense is layered. Prioritize in this order:
Immediate (24–72 hours)
- Rotate developer credentials if any compromise indicators appear: npm tokens (
npm token revoke), PyPI API tokens, GitHub PATs and SSH keys, AWS keys. TeamPCP-style operations monetize token theft — assume any token on an infected endpoint is burned. - Audit recently installed dependencies using the script above; cross-reference package versions against registry publish timestamps. A version published hours before your install, by a maintainer with a long dormancy, is a red flag.
- Hunt with the Sigma/KQL/VQL above across all developer workstations and build agents, not just servers.
Short-term (1–2 weeks)
- Enforce phishing-resistant 2FA (hardware keys/WebAuthn) on all npm, PyPI, and GitHub maintainer accounts. npm requires 2FA for high-impact packages — extend that bar internally.
- Kill long-lived publish tokens. Move CI publishing to short-lived, scoped credentials: npm granular access tokens, PyPI trusted publishing (OIDC), and GitHub Actions OIDC instead of static secrets.
- Install with script execution disabled by default: set
ignore-scripts=truein project and CI.npmrc, and explicitly allowlist packages that legitimately need native builds.
Strategic (30–90 days)
- Proxy all registry traffic through a private artifact repository (Artifactory, Nexus, GitHub Packages) with malware/typosquat scanning and quarantine — never let build agents pull directly from public registries.
- Pin and verify: commit lockfiles (
package-lock.json,poetry.lock), enforcenpm ciin pipelines, and adopt package provenance (Sigstore/npm provenance, SLSA attestations) where available. - Guard against dependency confusion: reserve your internal package names on public registries and configure registry scoping (
@yourorg:scope → private registry only). - Monitor your own blast radius: track packages your organization maintains and downstream-consumes; subscribe to GitHub Advisory Database and set alerting on your dependency tree.
The Bottom Line
The TeamPCP arrests are a win for law enforcement, but they change nothing about the structural weakness they exploited: developer tooling runs with enormous implicit trust and almost no monitoring. The package install event — a moment when arbitrary code from the internet executes with developer credentials in memory — remains one of the least-instrumented attack surfaces in most SOCs. Close that gap now with behavioral detection on package-manager child processes and credential-file access, and shrink the blast radius with short-lived tokens and script-disabled installs. The next TeamPCP is already publishing.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.