Chapter 225

Threat Intelligence and Attribution

Threat intelligence transforms raw IOCs and TTPs into actionable defensive context. The intelligence lifecycle — collection, processing, analysis, dissemination, feedback — drives detection rule priority, threat hunting hypotheses, and security roadmap decisions. Attribution is an analytical process with probabilistic confidence, not binary certainty; the same evidence supports multiple plausible actors.

Scenario

After containing an incident, your IR team has a PCAP, memory dump, and malware sample. Your task: extract IOCs, map them to ATT&CK techniques, assess actor confidence (is this APT28 or a copycat using leaked tools?), and convert the analysis into detection rules and a structured intelligence report for the security team.

Intelligence Lifecycle

INTELLIGENCE LIFECYCLE ═══════════════════════════════════════════════════════════════════════ 1. PLANNING / DIRECTION Intelligence requirements (IRs): "Are we targeted by VOLT TYPHOON?" Priority Intelligence Requirements (PIRs): which questions drive action 2. COLLECTION ┌─────────────────────────────────────────────────────────┐ │ OSINT HUMINT SIGINT TECHINT │ │ VirusTotal Vendor reports Network flows Malware RE │ │ Shodan/Censys ISAC sharing EDR telemetry Sandbox │ │ GitHub, blogs Government advisories SIEM logs │ └─────────────────────────────────────────────────────────┘ 3. PROCESSING Raw IOC enrichment: IP → ASN/geo/hosting, domain → WHOIS/DNS history Hash → sandbox report, YARA classification, imphash cluster 4. ANALYSIS TTP extraction → ATT&CK mapping → actor overlap → confidence scoring 5. DISSEMINATION STIX 2.1 / TAXII for machine-readable sharing Analyst report for leadership (strategic) Detection rule package for SOC (tactical) 6. FEEDBACK Did the detection rules fire? Were the IOCs accurate? Update confidence ratings; retire stale indicators ═══════════════════════════════════════════════════════════════════════

IOC Types and Confidence Decay

IOC typePyramid of Pain levelTTLConfidence decay
File hash (MD5/SHA256)TrivialHours–daysImmediately stale after recompile/packer
IP addressEasyDays–weeksBullet-proof hosting rotates weekly; shared infra causes FP
Domain nameSimpleWeeksDGA or fast-flux; TLD change; free subdomain abuse
Network artefact (JA3, User-Agent)AnnoyingWeeks–monthsTrivially changed by configuring C2 profile
Host artefact (mutex, registry key, file path)AnnoyingMonthsHarder to change; often left in by developers
TTP (ATT&CK technique)ChallengingMonths–yearsCore attack methods rarely change; most durable indicator

ATT&CK Mapping Workflow

# Python: auto-map technique IDs from IOC report to ATT&CK descriptions
import requests, json

ATT_ENTERPRISE = "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json"

def load_attack():
    data = requests.get(ATT_ENTERPRISE).json()
    techniques = {}
    for obj in data['objects']:
        if obj['type'] == 'attack-pattern':
            for ref in obj.get('external_references', []):
                if ref.get('source_name') == 'mitre-attack':
                    tid = ref['external_id']
                    techniques[tid] = {
                        'name': obj['name'],
                        'tactic': [p['phase_name'] for p in obj.get('kill_chain_phases',[])],
                        'description': obj.get('description','')[:200]
                    }
    return techniques

techniques = load_attack()
observed_ttps = ['T1003.001', 'T1055.001', 'T1071.001', 'T1021.002']
for tid in observed_ttps:
    t = techniques.get(tid, {})
    print(f"{tid}: {t.get('name')} — tactics: {', '.join(t.get('tactic',[]))}")
# STIX 2.1 bundle — machine-readable intelligence sharing:
from stix2 import Indicator, Malware, Relationship, Bundle, IPv4Address

# Create threat actor indicator
c2_ip = IPv4Address(value="185.220.101.55")
indicator = Indicator(
    name="APT29 C2 IP",
    description="Observed C2 IP from SUNBURST campaign",
    pattern_type="stix",
    pattern="[ipv4-addr:value = '185.220.101.55']",
    valid_from="2024-01-01T00:00:00Z",
    labels=["malicious-activity"]
)
malware_obj = Malware(name="SUNBURST", is_family=False)
rel = Relationship(relationship_type="indicates",
                   source_ref=indicator.id,
                   target_ref=malware_obj.id)
bundle = Bundle(objects=[indicator, malware_obj, rel])
print(bundle.serialize(pretty=True))

Attribution Methodology

ATTRIBUTION CONFIDENCE MODEL ═══════════════════════════════════════════════════════════════════════ Evidence cluster → actor hypothesis → confidence score (0-100) Cluster A — Technical overlap: + TTP match (T1071.001, T1003.001, T1021.002) → APT28 profile: +20 + Imphash cluster matches known APT28 tools: +15 + C2 infrastructure WHOIS: Reg date / hosting ASN matches known pattern: +10 Cluster B — Circumstantial: + Targeting profile (defense contractor) matches APT28 interest: +10 + Intrusion timeline aligns with Russian business hours (UTC+3): +5 + Error messages contain Cyrillic characters in debug strings: +10 Cluster C — Alternative hypothesis: - Tools are publicly available (leaked Equation Group toolset): -15 - TTP overlap with Chinese APT41 due to shared tooling: -10 Confidence: 55/100 (MODERATE — APT28 likely but not confirmed) IMPORTANT: Attribution is intelligence, not evidence. "Likely APT28" means "best fit given available data" — not admissible for indictment. False-flag operations deliberately plant artifacts of other groups. ═══════════════════════════════════════════════════════════════════════

TI-Ops Integration — Feeds, MISP, and Detection

# MISP API: query for all C2 IPs from a specific threat actor tag:
from pymisp import PyMISP

misp = PyMISP('https://misp.internal', 'YOUR_API_KEY', ssl=False)

# Search for attributes tagged APT28 of type ip-dst:
results = misp.search(
    controller='attributes',
    type_attribute='ip-dst',
    tags=['misp-galaxy:threat-actor="APT28"'],
    to_ids=True
)

ips = [a['value'] for a in results['Attribute']]
print(f"Found {len(ips)} APT28 C2 IPs")

# Export to Sigma detection rule dynamically:
print("detection:")
print("  selection:")
print("    dst_ip|contains:")
for ip in ips[:20]:
    print(f"      - '{ip}'")

Detection Engineering

title: Known Threat Actor C2 Domain — TI Feed Match
logsource:
  product: windows
  service: dns-client
detection:
  selection:
    QueryName|contains:
      - 'avsvmcloud.com'     # SUNBURST
      - 'stage.lostserver.com'  # example APT28 domain
  condition: selection
level: critical
tags: [attack.command_and_control, T1071.004]

-- MDE KQL: Threat intel IOC matching against DNS logs (STIX feed import)
let ti_domains = dynamic([
    "avsvmcloud.com",
    "megatoolkit.com",
    "panhardware.com"
]);
DeviceNetworkEvents
| where RemoteUrl has_any (ti_domains)
   or DnsQueryAnswerIpAddress has_any (ti_domains)
| project Timestamp, DeviceName, RemoteUrl, RemoteIP, InitiatingProcessFileName

-- MDE KQL: Detect imphash matches from known malware families
DeviceFileCertificateInfo
| where Timestamp > ago(7d)
| join kind=inner (
    ExternalData(["imphash"],["string"])  // custom watchlist of known-bad imphashes
    with (h@'https://...watchlist.csv', format="csv")
  ) on $left.SHA256 == $right.hash
| project Timestamp, DeviceName, FileName, FolderPath

Q&A

IOC-based detection (IP, domain, hash) degrades rapidly as threat actors rotate infrastructure. What is the MITRE ATT&CK-aligned approach to writing detections that remain valid even as specific IOCs change, and what is the practical tradeoff with this approach?

The ATT&CK-aligned approach is to write behavioral detections against techniques rather than specific artifacts. A technique-level detection asks "did this process load LSASS memory?" rather than "is this the specific mimikatz.exe hash?". The Pyramid of Pain formalizes why this works: attackers must change their fundamental TTPs to evade technique-based detection, whereas rotating an IP or recompiling a binary takes minutes. Technique-based Sigma/KQL rules focus on behaviors — a process opening LSASS with PROCESS_VM_READ access (T1003.001), a service created and started within 60 seconds (PsExec pattern), DNS queries with high-entropy subdomains (T1071.004 DNS tunneling) — none of which require any knowledge of what the specific malware family is.

The practical tradeoff is false-positive rate and analytical workload. An IOC-based detection (block this specific IP) is highly precise — every hit is a likely true positive, and almost no investigation is needed. A technique-based detection (alert on any process that reads LSASS memory) is much broader — legitimate security tools, crash reporters, and AV products do this too, requiring baseline suppression, process allowlists, and analyst triage. The operational model for mature SOCs is layered: IOC matches at the perimeter for immediate block/alert, technique-based behavioral rules in the SIEM/EDR for deeper investigation, and ATT&CK coverage mapping via DeTT&CT to identify gaps. Neither alone is sufficient — IOCs provide speed (no analysis needed on known-bad indicators) while TTPs provide resilience (detects novel tools using known tradecraft).