Supply chain attacks are now becoming more common as a vector for compromise. And can be one of the hardest to investigate. It is like an insider threat but the insider is software or code in the supply chain.
Does it leave an artifact trail? Yes, lets look at package managers, cache, and logs. This post covers the artifact locations related to supply chain attacks, what forensic data they contain, and how to recover.
Package Manager Attacks
Package Manager Compromise — malicious code injected into PyPI, npm, RubyGems, NuGet, kefile rules, or compiler pluginsPackage Manager Artifacts
Python / pip
Malicious PyPI packages typically execute at install time via setup.py, __init__.py, or setup.cfg hooks. The code runs with the installing user's permissions before the developer has reviewed a single line.
Key artifact locations:
| Artifact | Path | Forensic Value |
|---|---|---|
| Installed package files | ~/.local/lib/python3.x/site-packages/<pkg>/ |
Recover malicious source — often still on disk post-install |
| System-wide packages | /usr/local/lib/python3.x/dist-packages/ |
Confirms system-level install vs. virtualenv |
| pip install log | Explicit: pip install --log /tmp/pip.log <pkg> |
Install timestamp, version resolved, stdout from setup.py |
| pip cache | ~/.cache/pip/ |
Wheel/sdist files cached at install time — source recovery even if package was yanked from PyPI |
| virtualenv metadata | .venv/lib/python3.x/site-packages/<pkg>-*.dist-info/RECORD |
Cryptographic record of all files installed by the package |
| METADATA file | <site-packages>/<pkg>-*.dist-info/METADATA |
Declared maintainer, homepage, version — compare against known-good |
pip cache: The pip cache at ~/.cache/pip/ often retains the original wheel or source distribution even after a package has been removed from PyPI by the maintainer or registry. This is a good path to look for looking at malicious code after a takedown. Always image ~/.cache/pip/
What to examine in setup.py:
Look for encoded payloads, subprocess, os.system, socket, urllib, or requests calls at module import or install time. Legitimate packages do not make outbound network connections during installation.
Node.js / npm and yarn
npm's postinstall lifecycle hook is the primary execution vector. Any package can declare a postinstall script in package.json that runs automatically during npm install — with no user prompt.
Key artifact locations:
| Artifact | Path | Forensic Value |
|---|---|---|
| npm debug log | ~/.npm/_logs/<timestamp>-debug-*.log |
Verbose install log: resolved versions, script execution, outbound requests |
| Installed package source | node_modules/<pkg>/ |
Recover malicious JS — postinstall script often base64-encoded |
| Package lock | package-lock.json or yarn.lock |
Records exact resolved version + integrity hash at time of install |
| npm cache | ~/.npm/_cacache/ |
Cached tarballs — recoverable after package takedown |
.npmrc |
Project root or ~/ |
May reveal custom registry redirects (dependency confusion indicator) |
NPM package-lock: package-lock.json records the integrity field — a SHA-512 hash of the exact tarball that was downloaded. If a threat actor compromised a package after a prior clean install, the integrity hash in the lockfile will mismatch the hash of the malicious version. Comparing lockfile hashes against npm's public registry metadata is a fast triage step that doesn't require executing any code.
# Quick integrity check against current installed version
npm audit --json | python3 -m json.tool | grep -A2 "severity"
Other Package Ecosystems
| Ecosystem | Install Log / Cache Location | Execution Vector |
|---|---|---|
| RubyGems (gem) | ~/.gem/specs/, /var/lib/gems/ |
extconf.rb, gem extensions compiled at install |
| NuGet (.NET) | %APPDATA%\NuGet\, ~/.nuget/packages/ |
MSBuild .targets files executed at build time |
| Maven (Java) | ~/.m2/repository/ |
Plugin execution via pom.xml lifecycle phases |
| Go modules | $GOPATH/pkg/mod/ |
init() functions; go:generate directives |
| Cargo (Rust) | ~/.cargo/registry/, ~/.cargo/git/ |
build.rs scripts executed at compile time |
Supply chain forensics is an evidence collection problem more than a malware analysis problem. The malicious code often runs once, quickly, and leaves minimal trace. But cache, logs, and package files can be our friend.
No comments:
Post a Comment