Splunk SPL 기반 탐지 규칙 구축은(는) 무엇을 하나요?
개요
Splunk Search Processing Language(SPL)는 Splunk Enterprise Security에서 상관 검색을 구축하여 의심스러운 이벤트와 패턴을 탐지하는 주요 쿼리 언어입니다. 잘 설계된 탐지 규칙은 보안 이벤트를 집계, 상관 분석 및 강화하여 SOC 분석가가 조치를 취할 수 있는 주요 이벤트를 생성합니다. 기업 SIEM은 평균적으로 MITRE ATT&CK 기술의 21%만을 다루므로, 숙련된 SPL 규칙 작성이 탐지 공백을 메우는 데 필수적입니다.
사용 시기
- 환경에서 Splunk SPL 기반 탐지 규칙 기능을 배포하거나 구성할 때
- 규정 준수 요구 사항에 맞춰 보안 제어를 수립할 때
- 이 도메인에 대한 보안 아키텍처를 구축하거나 개선할 때
- 이 구현이 필요한 보안 평가를 수행할 때
사전 요구 사항
- Splunk Enterprise Security(ES)가 배포 및 구성되어 있어야 함
- 적절한 역할이 있는 Splunk Search & Reporting 앱에 접근 가능해야 함
- CIM(Common Information Model) 데이터 모델에 대한 이해
- MITRE ATT&CK 프레임워크 기술에 대한 숙련도
- 조직의 로그 소스 및 데이터 흐름에 대한 지식
핵심 SPL 탐지 규칙 패턴
1. 임계값 기반 탐지
시간 창 내에서 정의된 횟수를 초과하는 이벤트를 탐지합니다.
index=wineventlog sourcetype=WinEventLog:Security EventCode=4625
| stats count as failed_logins dc(TargetUserName) as unique_users by src_ip
| where failed_logins > 10 AND unique_users > 3
| eval severity="high"
| eval description="Brute force attack detected from ".src_ip." with ".failed_logins." failed logins across ".unique_users." accounts"
2. 시퀀스 기반 탐지 (실패 로그인 후 성공)
성공적인 무차별 대입 공격을 나타내는 이벤트 시퀀스를 상관 분석합니다.
index=wineventlog sourcetype=WinEventLog:Security (EventCode=4625 OR EventCode=4624)
| eval login_status=case(EventCode=4625, "failure", EventCode=4624, "success")
| stats count(eval(login_status="failure")) as failures count(eval(login_status="success")) as successes latest(_time) as last_event by src_ip, TargetUserName
| where failures > 5 AND successes > 0
| eval description="Account ".TargetUserName." compromised via brute force from ".src_ip
| eval urgency="critical"
3. 기준선 비교를 통한 이상 징후 탐지
현재 활동을 기준 기간과 비교하여 급증을 탐지합니다.
index=proxy sourcetype=squid
| bin _time span=1h
| stats count as current_count by src_ip, _time
| join src_ip type=left [
search index=proxy sourcetype=squid earliest=-7d@d latest=-1d@d
| stats avg(count) as avg_count stdev(count) as stdev_count by src_ip
]
| eval threshold=avg_count + (3 * stdev_count)
| where current_count > threshold
| eval deviation=round((current_count - avg_count) / stdev_count, 2)
| eval description="Anomalous web traffic from ".src_ip." - ".deviation." standard deviations above baseline"
4. 측면 이동 탐지
Windows 로그온 이벤트를 사용하여 잠재적인 측면 이동을 식별합니다.
index=wineventlog sourcetype=WinEventLog:Security EventCode=4624 Logon_Type=3
| where NOT match(TargetUserName, ".*\$$")
| stats dc(dest) as unique_hosts values(dest) as hosts by src_ip, TargetUserName
| where unique_hosts > 5
| eval severity=case(unique_hosts > 20, "critical", unique_hosts > 10, "high", true(), "medium")
| eval description=TargetUserName." accessed ".unique_hosts." unique hosts from ".src_ip." via network logon"
5. 데이터 유출 탐지
대규모 아웃바운드 데이터 전송을 모니터링합니다.
index=firewall sourcetype=pan:traffic action=allowed direction=outbound
| stats sum(bytes_out) as total_bytes_out dc(dest_ip) as unique_destinations by src_ip, user
| eval total_mb=round(total_bytes_out/1048576, 2)
| where total_mb > 500 OR unique_destinations > 50
| lookup asset_lookup ip as src_ip OUTPUT asset_category, asset_owner
| eval severity=case(total_mb > 2000, "critical", total_mb > 1000, "high", true(), "medium")
| eval description=user." transferred ".total_mb."MB to ".unique_destinations." unique destinations"
6. PowerShell 의심 실행 탐지
인코딩되거나 난독화된 PowerShell 명령을 탐지합니다.
index=wineventlog sourcetype=WinEventLog:Security EventCode=4104
| where match(ScriptBlockText, "(?i)(encodedcommand|invoke-expression|iex|downloadstring|frombase64string|net\.webclient|invoke-webrequest|bitstransfer|invoke-mimikatz|invoke-shellcode)")
| eval decoded_length=len(ScriptBlockText)
| stats count values(ScriptBlockText) as commands by Computer, UserName
| where count > 0
| eval severity="high"
| eval mitre_technique="T1059.001"
| eval description="Suspicious PowerShell execution on ".Computer." by ".UserName
Splunk ES에서 상관 검색 구축
단계별 프로세스
- 사용 사례 정의: MITRE ATT&CK 기술에 매핑하고 탐지할 동작을 정의합니다.
- 데이터 소스 식별: 관련 이벤트가 포함된 인덱스와 소스 유형을 결정합니다.
- 기본 검색 작성: 관련 이벤트를 추출하는 SPL을 빌드합니다.
- 집계 추가:
stats,eventstats또는streamstats를 사용하여 요약합니다. - 임계값 적용: 정상과 비정상을 구분하는
where절로 조건을 설정합니다. - 컨텍스트 강화: 에셋 정보, ID 데이터, 위협 인텔리전스에 대한 조회를 추가합니다.
- 주요 이벤트 구성: 심각도, 긴급도, 설명 필드를 설정합니다.
- 일정 및 테스트: 과거 데이터에 대해 실행하고 탐지 정확도를 검증합니다.
상관 검색 구성 템플릿
| tstats summariesonly=true count from datamodel=Authentication
where Authentication.action=failure
by Authentication.src, Authentication.user, _time span=5m
| rename "Authentication.*" as *
| stats count as total_failures dc(user) as unique_users values(user) as targeted_users by src
| where total_failures > 20 AND unique_users > 5
| lookup dnslookup clientip as src OUTPUT clienthost as src_dns
| lookup asset_lookup ip as src OUTPUT priority as asset_priority, category as asset_category
| eval urgency=case(asset_priority=="critical", "critical", asset_priority=="high", "high", true(), "medium")
| eval rule_name="Brute Force Against Multiple Accounts"
| eval rule_description="Multiple authentication failures from ".src." targeting ".unique_users." unique accounts"
| eval mitre_attack="T1110.001 - Password Guessing"
강화 모범 사례
| lookup identity_lookup identity as user OUTPUT department, manager, risk_score as user_risk
| lookup asset_lookup ip as src_ip OUTPUT asset_name, asset_category, asset_priority, asset_owner
| lookup threatintel_lookup ip as src_ip OUTPUT threat_type, threat_confidence, threat_source
| eval context=case(
isnotnull(threat_type), "Known threat: ".threat_type,
user_risk > 80, "High-risk user: risk score ".user_risk,
asset_priority=="critical", "Critical asset: ".asset_name,
true(), "Standard context"
)
성능 최적화
tstats와 함께 데이터 모델 사용
| tstats summariesonly=true count from datamodel=Network_Traffic
where All_Traffic.action=allowed
by All_Traffic.src_ip, All_Traffic.dest_ip, All_Traffic.dest_port, _time span=1h
| rename "All_Traffic.*" as *
시간 범위 제한 및 인덱스 필드 사용
index=wineventlog source="WinEventLog:Security" EventCode=4688
earliest=-15m latest=now()
| where NOT match(New_Process_Name, "(?i)(svchost|csrss|lsass|services)")
과거 기준선을 위한 요약 인덱싱 사용
| tstats count from datamodel=Authentication where Authentication.action=failure by Authentication.src, _time span=1h
| collect index=summary source="auth_failure_baseline" marker="report_name=auth_failure_hourly"
테스트 및 검증
알려진 공격 패턴에 대한 테스트
| makeresults count=1
| eval src_ip="10.0.0.50", failed_logins=25, unique_users=8, severity="high"
| eval description="Test brute force detection"
| append [
search index=wineventlog sourcetype=WinEventLog:Security EventCode=4625
earliest=-24h latest=now()
| stats count as failed_logins dc(TargetUserName) as unique_users by src_ip
| where failed_logins > 10 AND unique_users > 3
| eval severity="high"
]
탐지 메트릭 계산
index=notable
| search rule_name="Brute Force*"
| stats count as total_alerts count(eval(status_label="Closed - True Positive")) as true_positives count(eval(status_label="Closed - False Positive")) as false_positives by rule_name
| eval precision=round(true_positives / (true_positives + false_positives) * 100, 2)
| eval fpr=round(false_positives / total_alerts * 100, 2)
MITRE ATT&CK 매핑
| 기술 ID | 기술 이름 | SPL 탐지 접근 방식 |
|---|---|---|
| T1110.001 | 비밀번호 추측 | src_ip별 EventCode 4625 임계값 |
| T1059.001 | PowerShell | EventCode 4104 ScriptBlockText 패턴 매칭 |
| T1021.002 | SMB/Windows 관리 공유 | 로그온 유형 3과 dc(dest) 임계값 |
| T1048 | C2를 통한 유출 | 시간 창에 대한 bytes_out 집계 |
| T1053.005 | 예약된 작업 | 의심스러운 명령 패턴이 포함된 EventCode 4698 |
| T1003.001 | LSASS 메모리 | Sysmon EventCode 10을 통한 lsass.exe 프로세스 액세스 |