<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: analyzing-campaign-attribution
description: >-
  Perform threat campaign attribution using convergent evidence analysis,
  Analysis of Competing Hypotheses (ACH), and multi-source correlation.
domain: cybersecurity
subdomain: threat-intelligence
tags:
  - attribution
  - campaign-analysis
  - ach
  - threat-actors
  - mitre-attack
  - convergent-evidence
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: []
---
# Analyzing Campaign Attribution

## Overview

Campaign attribution determines which threat actor is responsible for observed
intrusion activity by analyzing convergent evidence across TTPs, infrastructure,
malware, victimology, and operational patterns. This skill covers structured
attribution methodology including Analysis of Competing Hypotheses (ACH),
evidence weighting, false flag identification, and confidence-calibrated
attribution statements.

## Prerequisites

- Understanding of major APT group profiles and their TTPs
- Access to ATT&CK Navigator for TTP comparison
- MISP/OpenCTI for evidence management
- Knowledge of structured analytic techniques (ACH, Key Assumptions Check)
- Python 3.10+ with `attackcti`, `stix2`

```bash
pip install attackcti stix2 pandas
```

## Key Concepts

### Attribution Evidence Categories

| Category | Weight | Examples |
|----------|--------|---------|
| Code Overlap | HIGH | Shared malware codebase, unique encryption routines |
| Infrastructure Reuse | HIGH | Same C2 domains/IPs, registrant patterns |
| TTP Consistency | MEDIUM | ATT&CK technique overlap with known actor |
| Victimology Pattern | MEDIUM | Same sector/geography targeting |
| Operational Timing | LOW-MEDIUM | Timezone-aligned activity windows |
| Language Artifacts | LOW | Compiler strings, comments, keyboard layout |
| False Flags | NEGATIVE | Deliberate deception indicators |

### Analysis of Competing Hypotheses (ACH)

ACH is a structured analytic technique that evaluates multiple hypotheses
simultaneously rather than confirming a preferred one:

1. **Identify hypotheses:** List all plausible actors (minimum 3)
2. **List evidence:** Enumerate all diagnostic evidence items
3. **Build matrix:** Evidence × Hypothesis — mark C (consistent), I (inconsistent), N (neutral)
4. **Score:** Count inconsistencies per hypothesis — fewest inconsistencies = most likely
5. **Sensitivity analysis:** Remove each piece of evidence and check if ranking changes
6. **Report:** Include rejected hypotheses and reasoning

### Confidence Framework

```
HIGH:     3+ independent evidence categories converge; no significant contradictions
MODERATE: 2 evidence categories; some contradictions or analytical assumptions
LOW:      Single evidence category; significant uncertainty; speculative
```

### False Flag Indicators

- Language strings inconsistent with known actor's origin
- Tool overlaps that are too perfect (deliberate mimicry)
- Infrastructure registered with competitor nation's services
- Operational timing deliberately shifted from expected timezone
- Malware with embedded attribution breadcrumbs

## Workflow

### Step 1: Evidence Collection

```python
import json
from datetime import datetime

def create_evidence_item(
    category: str,
    description: str,
    value: str,
    source: str,
    confidence: str,
) -> dict:
    """Create structured evidence item for attribution analysis."""
    valid_categories = [
        "code_overlap", "infrastructure_reuse", "ttp_consistency",
        "victimology", "operational_timing", "language_artifacts",
    ]
    return {
        "id": f"EV-{datetime.now().strftime('%Y%m%d%H%M%S')}",
        "category": category if category in valid_categories else "other",
        "description": description,
        "value": value,
        "source": source,
        "confidence": confidence,
        "timestamp": datetime.now().isoformat(),
    }
```

### Step 2: ACH Matrix Construction

```python
def build_ach_matrix(
    hypotheses: list[str],
    evidence: list[dict],
    assessments: dict[str, dict[str, str]],
) -> dict:
    """Build ACH matrix and score hypotheses.

    assessments: {evidence_id: {hypothesis: "C"|"I"|"N"}}
    """
    scores = {h: {"consistent": 0, "inconsistent": 0, "neutral": 0} for h in hypotheses}

    for ev in evidence:
        ev_id = ev["id"]
        if ev_id in assessments:
            for hyp in hypotheses:
                rating = assessments[ev_id].get(hyp, "N")
                if rating == "C":
                    scores[hyp]["consistent"] += 1
                elif rating == "I":
                    scores[hyp]["inconsistent"] += 1
                else:
                    scores[hyp]["neutral"] += 1

    ranking = sorted(hypotheses, key=lambda h: scores[h]["inconsistent"])

    return {
        "hypotheses": hypotheses,
        "evidence_count": len(evidence),
        "scores": scores,
        "ranking": ranking,
        "most_likely": ranking[0],
        "least_inconsistencies": scores[ranking[0]]["inconsistent"],
    }
```

### Step 3: TTP Comparison

```python
def compare_ttps(observed: set[str], known_actors: dict[str, set[str]]) -> dict:
    """Compare observed TTPs against known actor profiles."""
    results = {}
    for actor, actor_ttps in known_actors.items():
        overlap = observed & actor_ttps
        unique_to_incident = observed - actor_ttps
        results[actor] = {
            "overlap_count": len(overlap),
            "overlap_pct": round(len(overlap) / max(len(observed), 1) * 100, 1),
            "overlapping_techniques": sorted(overlap),
            "unique_to_incident": sorted(unique_to_incident),
            "actor_total_techniques": len(actor_ttps),
        }
    return dict(sorted(results.items(), key=lambda x: -x[1]["overlap_pct"]))
```

### Step 4: Infrastructure Correlation

```python
def correlate_infrastructure(
    observed_infra: list[dict],
    known_infra: dict[str, list[dict]],
) -> dict:
    """Correlate observed infrastructure against known actor infrastructure."""
    matches = {}
    observed_values = {i["value"] for i in observed_infra}

    for actor, infra_list in known_infra.items():
        actor_values = {i["value"] for i in infra_list}
        overlap = observed_values & actor_values
        if overlap:
            matches[actor] = {
                "matching_indicators": sorted(overlap),
                "match_count": len(overlap),
            }
    return matches
```

### Step 5: Attribution Report Generation

```python
def generate_attribution_report(
    ach_result: dict,
    ttp_comparison: dict,
    infra_correlation: dict,
    confidence: str,
) -> dict:
    """Generate structured attribution report."""
    return {
        "report_type": "campaign_attribution",
        "timestamp": datetime.now().isoformat(),
        "attribution": {
            "primary_hypothesis": ach_result["most_likely"],
            "confidence": confidence,
            "competing_hypotheses": ach_result["ranking"][1:],
        },
        "evidence_summary": {
            "ach_ranking": ach_result["ranking"],
            "ttp_overlap": {
                actor: data["overlap_pct"]
                for actor, data in ttp_comparison.items()
            },
            "infrastructure_matches": infra_correlation,
        },
        "caveats": [
            "Attribution assessed with available evidence at time of analysis",
            "False flag operations cannot be fully excluded",
            "Additional evidence may change assessment",
        ],
    }
```

## Verification

- [ ] Minimum 3 competing hypotheses evaluated in ACH matrix
- [ ] Evidence items tagged with category, source, and confidence
- [ ] TTP comparison shows overlap percentages for all candidate actors
- [ ] Infrastructure correlation checks passive DNS and WHOIS pivots
- [ ] Attribution statement includes confidence level and caveats
- [ ] False flag indicators explicitly assessed and documented

## References

- [Analysis of Competing Hypotheses](https://www.cia.gov/static/9a5f1162fd0932c29e985f0159f56ec1/Tradecraft-Primer-apr09.pdf)
- [MITRE ATT&CK Groups](https://attack.mitre.org/groups/)
- [Intrusion Analysis Diamond Model](https://www.threatintel.academy/diamond/)
- [NIST SP 800-150: Guide to CTI Sharing](https://csrc.nist.gov/publications/detail/sp/800-150/final)
