SOAR
Security Orchestration, Automation and Response
보안 위협 탐지부터 대응까지 자동화하는 플랫폼. SIEM과 연동하여 알림 피로(Alert Fatigue)를 줄이고, 플레이북 기반의 자동화된 인시던트 대응으로 SOC 팀의 효율성을 높입니다.
Security Orchestration, Automation and Response
보안 위협 탐지부터 대응까지 자동화하는 플랫폼. SIEM과 연동하여 알림 피로(Alert Fatigue)를 줄이고, 플레이북 기반의 자동화된 인시던트 대응으로 SOC 팀의 효율성을 높입니다.
SOAR는 보안 운영 센터(SOC)의 업무를 자동화하고 효율화하는 플랫폼입니다. 기존 SOC는 SIEM에서 발생하는 수천 건의 알림을 분석가가 일일이 검토해야 했습니다. SOAR는 이러한 반복 작업을 플레이북(Playbook)으로 자동화하여 분석가가 실제 위협에 집중할 수 있게 합니다. Gartner가 2017년 처음 정의한 이후 주요 보안 솔루션으로 자리잡았습니다.
SOAR의 핵심 기능은 세 가지입니다. 오케스트레이션(Orchestration)은 SIEM, EDR, 방화벽, 위협 인텔리전스 등 다양한 보안 도구를 하나의 워크플로우로 연결합니다. 자동화(Automation)는 미리 정의된 플레이북에 따라 반복적인 대응 작업을 자동 실행합니다. 대응(Response)은 인시던트 케이스 관리, 협업, 문서화를 지원합니다.
대표적인 SOAR 솔루션으로는 Palo Alto의 Cortex XSOAR(구 Demisto), Splunk SOAR(구 Phantom), IBM Security SOAR(구 Resilient), Microsoft Sentinel(SIEM+SOAR 통합)이 있습니다. 오픈소스로는 TheHive, Shuffle 등이 있어 중소기업도 도입할 수 있습니다.
최근에는 AI/ML이 SOAR에 통합되고 있습니다. 알림의 중요도를 자동 분류하고, 유사 인시던트의 과거 대응 이력을 추천하며, 자연어로 플레이북을 생성하는 기능이 추가되고 있습니다. 이를 통해 Tier 1 분석가의 업무 부담을 크게 줄이고, 평균 대응 시간(MTTR)을 단축할 수 있습니다.
# SOAR 플레이북 자동화 예제 (Python)
import json
import requests
from datetime import datetime
from typing import Dict, List, Optional
from dataclasses import dataclass, asdict
from enum import Enum
class Severity(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
class IncidentStatus(Enum):
NEW = "new"
IN_PROGRESS = "in_progress"
RESOLVED = "resolved"
FALSE_POSITIVE = "false_positive"
@dataclass
class SecurityIncident:
"""보안 인시던트 데이터 모델"""
id: str
title: str
description: str
severity: Severity
source: str # SIEM, EDR, Firewall 등
source_ip: Optional[str]
dest_ip: Optional[str]
indicators: List[str] # IOCs
status: IncidentStatus
created_at: datetime
playbook_results: Dict = None
class SOARPlaybook:
"""SOAR 플레이북 기본 클래스"""
def __init__(self, name: str):
self.name = name
self.steps_executed = []
self.results = {}
def enrich_with_threat_intel(self, indicator: str) -> Dict:
"""위협 인텔리전스로 IOC 조회"""
# VirusTotal, AbuseIPDB, OTX 등 조회
enrichment = {
"indicator": indicator,
"virustotal_detections": 0,
"abuseipdb_score": 0,
"known_malicious": False,
"related_campaigns": []
}
# VirusTotal API 호출 예시
# vt_response = requests.get(
# f"https://www.virustotal.com/api/v3/ip_addresses/{indicator}",
# headers={"x-apikey": VT_API_KEY}
# )
self.steps_executed.append(f"Enriched {indicator}")
return enrichment
def block_ip_on_firewall(self, ip: str, duration_hours: int = 24) -> bool:
"""방화벽에서 IP 차단"""
# 실제로는 방화벽 API 호출
print(f"[FIREWALL] Blocking IP {ip} for {duration_hours} hours")
self.steps_executed.append(f"Blocked IP {ip}")
return True
def isolate_endpoint(self, hostname: str) -> bool:
"""EDR을 통해 엔드포인트 격리"""
# CrowdStrike, SentinelOne 등 API 호출
print(f"[EDR] Isolating endpoint {hostname}")
self.steps_executed.append(f"Isolated {hostname}")
return True
def create_ticket(self, incident: SecurityIncident) -> str:
"""ITSM 시스템에 티켓 생성"""
ticket_id = f"INC-{datetime.now().strftime('%Y%m%d%H%M%S')}"
print(f"[ITSM] Created ticket {ticket_id}")
self.steps_executed.append(f"Created ticket {ticket_id}")
return ticket_id
def notify_team(self, channel: str, message: str) -> bool:
"""Slack/Teams로 알림 전송"""
# Slack Webhook 예시
# requests.post(SLACK_WEBHOOK, json={"text": message})
print(f"[NOTIFY] Sent to {channel}: {message}")
self.steps_executed.append(f"Notified {channel}")
return True
class PhishingPlaybook(SOARPlaybook):
"""피싱 이메일 대응 플레이북"""
def execute(self, incident: SecurityIncident) -> Dict:
"""플레이북 실행"""
results = {"incident_id": incident.id, "actions": []}
# Step 1: 발신자 도메인/IP 조회
for indicator in incident.indicators:
enrichment = self.enrich_with_threat_intel(indicator)
results["actions"].append({
"step": "enrich",
"indicator": indicator,
"result": enrichment
})
# Step 2: 악성으로 확인되면 자동 차단
if enrichment.get("known_malicious"):
self.block_ip_on_firewall(indicator)
results["actions"].append({
"step": "block_ip",
"ip": indicator,
"result": "blocked"
})
# Step 3: 심각도 높으면 관련 사용자 계정 일시 잠금
if incident.severity in [Severity.HIGH, Severity.CRITICAL]:
# 실제로는 AD/IAM API 호출
results["actions"].append({
"step": "account_lockout",
"result": "pending_approval" # 수동 승인 필요
})
# Step 4: 티켓 생성 및 팀 알림
ticket_id = self.create_ticket(incident)
self.notify_team(
"security-alerts",
f"🚨 Phishing incident detected: {incident.title}\n"
f"Ticket: {ticket_id}\nSeverity: {incident.severity.value}"
)
results["ticket_id"] = ticket_id
results["playbook_completed"] = True
return results
class MalwarePlaybook(SOARPlaybook):
"""멀웨어 탐지 대응 플레이북"""
def execute(self, incident: SecurityIncident) -> Dict:
results = {"incident_id": incident.id, "actions": []}
# Step 1: 감염 엔드포인트 즉시 격리
if incident.dest_ip:
hostname = self._resolve_hostname(incident.dest_ip)
self.isolate_endpoint(hostname)
results["actions"].append({
"step": "isolate_endpoint",
"hostname": hostname,
"result": "isolated"
})
# Step 2: 파일 해시 조회
for indicator in incident.indicators:
if self._is_file_hash(indicator):
enrichment = self.enrich_with_threat_intel(indicator)
results["actions"].append({
"step": "hash_lookup",
"hash": indicator,
"result": enrichment
})
# Step 3: C2 서버 차단
if incident.source_ip:
self.block_ip_on_firewall(incident.source_ip, duration_hours=168) # 7일
# Step 4: 포렌식 데이터 수집 트리거
results["actions"].append({
"step": "forensics",
"result": "memory_dump_triggered"
})
ticket_id = self.create_ticket(incident)
self.notify_team(
"security-critical",
f"🔴 MALWARE ALERT: {incident.title}\n"
f"Affected: {incident.dest_ip}\nTicket: {ticket_id}"
)
return results
def _resolve_hostname(self, ip: str) -> str:
# DNS 역방향 조회 또는 CMDB 조회
return f"host-{ip.replace('.', '-')}"
def _is_file_hash(self, indicator: str) -> bool:
return len(indicator) in [32, 40, 64] # MD5, SHA1, SHA256
# 사용 예시: SIEM 알림 처리
def handle_siem_alert(alert_data: Dict):
"""SIEM에서 전달받은 알림 처리"""
# 인시던트 객체 생성
incident = SecurityIncident(
id=alert_data["alert_id"],
title=alert_data["rule_name"],
description=alert_data["description"],
severity=Severity(alert_data["severity"]),
source="Splunk",
source_ip=alert_data.get("src_ip"),
dest_ip=alert_data.get("dest_ip"),
indicators=alert_data.get("iocs", []),
status=IncidentStatus.NEW,
created_at=datetime.now()
)
# 알림 유형에 따른 플레이북 선택
playbook_map = {
"phishing": PhishingPlaybook("Phishing Response"),
"malware": MalwarePlaybook("Malware Response"),
}
alert_type = alert_data.get("category", "generic")
playbook = playbook_map.get(alert_type)
if playbook:
results = playbook.execute(incident)
incident.playbook_results = results
incident.status = IncidentStatus.IN_PROGRESS
print(json.dumps(results, indent=2, default=str))
return incident
# 테스트
sample_alert = {
"alert_id": "SIEM-2024-001234",
"rule_name": "Suspicious Outbound Connection to Known C2",
"description": "Endpoint communicated with known malware C2 server",
"severity": "critical",
"category": "malware",
"src_ip": "192.168.1.100",
"dest_ip": "10.0.0.50",
"iocs": ["185.220.101.1", "abc123def456789..."]
}
handle_siem_alert(sample_alert)
SOC 매니저: "SIEM 알림이 하루에 5천 건이 넘어요. Tier 1 분석가들이 다 처리를 못하고 있어요."
보안 엔지니어: "SOAR 도입하면 80%는 자동화할 수 있어요. 피싱, 무차별 대입 공격 같은 반복 패턴은 플레이북으로 자동 대응하고, 분석가는 고급 위협에만 집중하면 됩니다."
SOC 매니저: "MTTR은 얼마나 개선될까요?"
보안 엔지니어: "업계 평균으로 보면 수동 대응 4시간에서 SOAR 적용 후 15분으로 단축된 사례가 많아요."
면접관: "SIEM과 SOAR의 차이점을 설명해주세요."
지원자: "SIEM은 로그를 수집하고 분석해서 이상 징후를 탐지하는 역할이고, SOAR는 탐지된 알림에 대한 대응을 자동화합니다. SIEM이 '무엇이 발생했는지' 알려주면, SOAR가 '어떻게 대응할지' 실행합니다. 최근에는 Microsoft Sentinel처럼 둘을 통합한 플랫폼도 많습니다."
리뷰어: "이 플레이북에서 자동 IP 차단하는데, false positive면 정상 트래픽도 막힐 수 있어요. Human-in-the-loop 단계 추가해야 해요."
작성자: "Critical 알림에 대해서만 자동 차단하고, Medium 이하는 승인 대기 단계를 넣을게요. Slack 버튼으로 승인/거부할 수 있게 만들겠습니다."