Day 2 of 5
⏱ ~60 minutes
SOC Operations in 5 Days — Day 2

Alert Triage & Investigation

A SOC analyst's core skill is triage: determining whether an alert represents a real attack or a false positive, and escalating appropriately. Today covers the triage workflow, investigation techniques, and the tools analysts use every day.

The Triage Process

Tier 1 analysts review every alert using a structured process: (1) Read the alert — what rule fired? (2) Pull context — what is the source IP, user, hostname? (3) Search for related events — what else was this host doing? (4) Classify — true positive, false positive, or inconclusive? (5) Escalate to Tier 2 if suspicious. The goal is making this decision in 5-10 minutes per alert. Playbooks standardize the process.

Threat Intelligence Enrichment

Raw alerts gain meaning from threat intelligence. Enrich IP addresses with VirusTotal, AbuseIPDB, Shodan, and MISP. Enrich file hashes with VirusTotal and MalwareBazaar. Enrich domains with passive DNS (Farsight DNSDB, VirusTotal). MISP (Malware Information Sharing Platform) and OpenCTI are open-source TI platforms for managing and correlating IOCs across your organization.

MITRE ATT&CK Framework

MITRE ATT&CK is a knowledge base of adversary tactics, techniques, and sub-techniques observed in real attacks. It is organized by tactics (the 'why': Initial Access, Execution, Persistence, Privilege Escalation...) and techniques (the 'how': Spearphishing Link, PowerShell, Scheduled Task...). Mapping your detections to ATT&CK identifies coverage gaps and helps communicate threat context to management.

python
import requests

VT_API_KEY = 'your_virustotal_api_key'
ABUSE_API_KEY = 'your_abuseipdb_api_key'

def enrich_ip(ip: str) -> dict:
    results = {}
    
    # VirusTotal
    vt_url = f'https://www.virustotal.com/api/v3/ip_addresses/{ip}'
    r = requests.get(vt_url, headers={'x-apikey': VT_API_KEY})
    if r.status_code == 200:
        data = r.json()['data']['attributes']
        results['vt_malicious'] = data['last_analysis_stats']['malicious']
        results['vt_country'] = data.get('country', 'unknown')
    
    # AbuseIPDB
    abuse_url = 'https://api.abuseipdb.com/api/v2/check'
    r = requests.get(abuse_url,
        headers={'Key': ABUSE_API_KEY, 'Accept': 'application/json'},
        params={'ipAddress': ip, 'maxAgeInDays': 90})
    if r.status_code == 200:
        data = r.json()['data']
        results['abuse_score'] = data['abuseConfidenceScore']
        results['abuse_reports'] = data['totalReports']
    
    return results

# Example enrichment
result = enrich_ip('8.8.8.8')
print(result)
💡
Build an enrichment script that auto-runs against every new alert's IOCs. Manual lookup of 50 IPs per alert quickly becomes unsustainable. Automate what is repetitive so analysts focus on judgment calls.
📝 Day 2 Exercise
Build an Alert Triage Playbook
  1. Get a free VirusTotal API key from virustotal.com
  2. Write the enrich_ip() function from the code example above
  3. Add a file hash lookup using the VirusTotal /files/{hash} endpoint
  4. Test it against 5 known-malicious IPs from AbuseIPDB's public threat feed
  5. Write a triage playbook document for SSH brute force alerts: detection steps, enrichment steps, escalation criteria

Day 2 Summary

  • Triage determines real attack vs. false positive in 5-10 minutes per alert
  • VirusTotal, AbuseIPDB, and MISP enrich IOCs with threat context
  • MITRE ATT&CK maps techniques to tactics for comprehensive coverage analysis
  • Automate IOC enrichment so analysts focus on investigation judgment
  • Playbooks standardize triage and ensure consistent analyst quality
Challenge

Map your Wazuh/ELK SIEM's detection rules to MITRE ATT&CK tactics and techniques using the ATT&CK Navigator. Identify 3 tactic areas with no detection coverage and write rules to fill the gaps.

Finished this lesson?