<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
<!-- NERF is a trademark of defconxt. -->
# API Reference — Correlating Threat Campaigns

## Event Schema for Correlation

```json
{
  "id": "event-001",
  "timestamp": "2026-01-15T14:30:00Z",
  "infrastructure": {
    "domains": ["evil.com", "c2.evil.com"],
    "ips": ["1.2.3.4", "5.6.7.8"]
  },
  "capability": {
    "malware": "CobaltStrike",
    "techniques": ["T1566.001", "T1059.001", "T1071.001"]
  },
  "victim": {
    "org": "Target Corp",
    "sector": "finance",
    "geo": "US"
  }
}
```

## MISP Event Correlation

### Search Correlated Events
```bash
curl -X POST "$MISP_URL/events/restSearch" \
  -H "Authorization: $MISP_KEY" \
  -d '{"value":"evil.com","type":"domain","includeCorrelations":true}'
```

### Get Event Correlations
```bash
curl "$MISP_URL/events/view/EVENT_ID" \
  -H "Authorization: $MISP_KEY" \
  -H "Accept: application/json"
```

## OpenCTI Campaign Queries

### List Campaigns
```graphql
query {
  campaigns(first: 20, orderBy: created_at, orderMode: desc) {
    edges {
      node {
        name
        first_seen
        last_seen
        description
        objectLabel { value }
      }
    }
  }
}
```

### Get Campaign Indicators
```graphql
query($id: String!) {
  campaign(id: $id) {
    name
    indicators { edges { node { name pattern valid_from } } }
    attackPatterns { edges { node { name x_mitre_id } } }
  }
}
```

## Jaccard Similarity Reference

```
J(A, B) = |A ∩ B| / |A ∪ B|

J > 0.7:  Strong TTP match — likely same campaign
J 0.4-0.7: Moderate overlap — possible related activity
J 0.2-0.4: Weak signal — shared commodity techniques
J < 0.2:  Minimal overlap — likely unrelated
```

## NetworkX Campaign Graph Operations

```python
import networkx as nx

G = nx.Graph()
# Add events as nodes, shared indicators as edges
G.add_edge("event-1", "event-2", shared=["evil.com"])

# Find campaigns (connected components)
campaigns = list(nx.connected_components(G))

# Centrality analysis (most connected event)
centrality = nx.degree_centrality(G)
hub_event = max(centrality, key=centrality.get)
```

## Temporal Analysis

### Operational Tempo Calculation
```python
from datetime import datetime
import statistics

timestamps = [datetime.fromisoformat(e["timestamp"]) for e in events]
gaps = [(timestamps[i+1] - timestamps[i]).total_seconds() / 3600
        for i in range(len(timestamps)-1)]

avg_gap = statistics.mean(gaps)  # Average hours between events
std_gap = statistics.stdev(gaps)  # Consistency of timing
```
