| name | supply-chain-ioc-investigate |
| description | Investigate potential supply chain compromise indicators. Demonstrates Tier 2 investigation with multi-finding triage, timeline construction across systems, and evidence hierarchy in practice. |
| metadata | {"author":"TGPSKI","version":"2.0"} |
| compatibility | Requires access to DNS logs (Splunk/CloudWatch), CI build logs, npm/pip audit tools, git history |
Supply Chain IOC Investigation
Investigate indicators of compromise (IOC) from a supply chain attack affecting CI/CD infrastructure. This example demonstrates the full two-tier methodology applied to a multi-finding investigation.
Key Methodology Concepts Demonstrated
- Tier 1 fast-pass: Coordinates are verified quickly (the IOC data is from the correct network, correct time, correct systems) — proceed to Tier 2
- Multi-finding investigation: A single sweep can produce multiple independent findings
- Timeline construction across systems: DNS logs, build logs, git history, and package registries all contribute events
- Evidence hierarchy in action: DNS query counts are HEURISTIC (consistent with beaconing, not definitive proof of compromise)
- Exposure window calculation: Start = first compromised build, End = last compromised build or remediation
Tier 1: Intake & Coordinate Resolution
Step 1: Intake
| Fact | Source | Tag |
|------|--------|-----|
| Compromised package versions published to registry | Threat intel advisory | STATED |
| Package: {name}, versions: {versions} | Advisory | STATED |
| Compromise window: {start} to {end} | Advisory | STATED |
| CI systems that could have installed these | Reporter | STATED/INFERRED |
| Which CI workers were affected | DNS/build logs | MISSING |
Step 2: Adversarial Review
| Inference | Simplest Alternative |
|---|
| Our CI installed the compromised version | We may use pinned versions or lockfiles that prevented it |
| DNS queries to C2 = active RAT | Could be resolver cache propagation (single query, not beaconing) |
Evidence hierarchy note: DNS query frequency determines confidence:
- 1 query, synchronized with other IPs → HEURISTIC (resolver cache)
- 100+ queries over hours → HEURISTIC (consistent with beaconing)
- Neither is DEFINITIVE without process-level forensics
Step 3: Coordinate Resolution
| Coordinate | Verification |
|---|
| Network segment | DNS logs from CI workers, not office/VPN? |
| Time zone | Log timestamps aligned with advisory window? |
| Package registry | Correct registry (public npm vs internal mirror)? |
| CI system | Correct CI platform (not a different team's system)? |
Verdict: COORDINATES VERIFIED — DNS logs are from the CI network segment,
timestamps align with the advisory window, package registry matches.
→ Proceed to Tier 2.
Tier 2: Investigation
Step 4: Timeline
Build from multiple sources:
| Source | What to Extract |
|---|
| CI build logs | Which builds ran during the compromise window, what they installed |
| DNS logs | Queries to known C2 domains from CI worker IPs |
| Package registry | Exact publish and unpublish timestamps of malicious versions |
| Git history | PRs that updated lockfiles during the window (Renovate/Dependabot) |
| Time (UTC) | Event | Source | Confidence |
|------------|-------|--------|------------|
| T+0:00 | Malicious package published | Registry advisory | DEFINITIVE |
| T+0:20 | Lockfile maintenance PR created | Git log | DEFINITIVE |
| T+0:23 | CI build starts on PR | Build log | DEFINITIVE |
| T+0:25 | Worker resolves C2 domain | DNS log | DEFINITIVE |
| T+3:00 | Malicious package unpublished | Registry advisory | DEFINITIVE |
| T+15:00 | Last C2 query from worker | DNS log | DEFINITIVE |
Step 5: Hypothesize
| Hypothesis | Prior | Supporting Evidence | Contradicting Evidence | Discriminating Check |
|---|
| Build installed compromised package, RAT active | High | DNS hit + build in window | | Correlate worker IP to build job |
| DNS queries are resolver cache, not RAT | Medium | Some IPs had single query | 966 queries from one IP over 15h | Query frequency analysis |
| Build used pinned/locked safe version | Low | Lockfile exists | PR updated lockfile during window | Check lockfile at build's commit SHA |
Step 6: Discriminate
Cheapest discriminating check: DNS query frequency per worker IP.
| Query Pattern | Interpretation | Confidence |
|---|
| 1 query, synchronized with other IPs | Resolver cache event | HEURISTIC |
| 10-50 queries over 30 minutes | Possible infection, short-lived | HEURISTIC |
| 100+ queries over hours | Active RAT beaconing | HEURISTIC |
Coordinate system verification:
- Correct VPC / network view?
- Timestamps in same timezone as build logs?
- Worker IPs belong to the CI pool (not shared infra)?
Step 7: Narrow + Contain
For each confirmed compromised build:
- Identify exposed secrets: What credentials were accessible during the build?
- Calculate exposure window: First compromised build → remediation
- Contain: Rotate all credentials accessible during the exposure window
| Finding Type | Containment |
|---|
| Credential exposed to compromised worker | Rotate immediately |
| C2 domain resolved from CI network | Block at network perimeter |
| Compromised lockfile PR still open | Close the PR |
| Malicious package in dependency tree | Pin to safe version, audit lockfile |
Artifact Checkpoint
File: sessions/{date}-supply-chain-ioc.md
Structure:
- Executive Summary: number of findings, affected systems, exposure window
- Finding per compromised package: affected builds, exposed secrets, evidence tables
- Finding per C2 indicator: DNS evidence with confidence labels, worker-to-job correlation
- Timeline: merged from all sources, chronological
- Open Actions: credential rotations (Critical), network blocks (High), lockfile audits (Medium)
What This Example Teaches
- Tier 1 is quick for verified threats: When a credible advisory provides the coordinates (package, version, time window), verification is fast and proceeds to Tier 2.
- Evidence hierarchy prevents over-reaction: DNS queries are HEURISTIC, not DEFINITIVE. A single query might be resolver cache. 966 queries over 15 hours is consistent with beaconing but still not process-level proof.
- Multi-finding investigations share a timeline: Two independent compromises discovered in one sweep share a unified timeline but have separate findings with separate evidence tables and exposure windows.
- Containment is per-finding: Each finding has its own blast radius and containment action.