Splunk에서 Windows 이벤트 로그 분석하기
사용 시기
이 스킬은 다음과 같은 경우에 사용합니다:
- SOC 분석가가 Windows 인증, 프로세스 실행, AD 변경 관련 알림을 조사할 때
- 탐지 엔지니어가 Windows 기반 위협 탐지를 위한 SPL 쿼리를 구축할 때
- 침해 대응 담당자가 Windows 엔드포인트 또는 도메인 컨트롤러의 포렌식 타임라인이 필요할 때
- 주기적인 위협 헌팅이 Windows 특화 ATT&CK 기술을 대상으로 할 때
Linux/macOS 엔드포인트 분석 또는 네트워크 전용 조사에는 사용하지 마십시오.
필수 조건
- Windows 이벤트 로그 데이터가 수집된 Splunk (소스 유형:
WinEventLog:Security,WinEventLog:System,XmlWinEventLog:Microsoft-Windows-Sysmon/Operational) - SwiftOnSecurity 또는 Olaf Hartong 구성으로 엔드포인트에 배포된 Sysmon
- 엔드포인트 및 인증 데이터 모델에 대한 CIM 데이터 모델 가속화
- Windows 보안 이벤트 ID 및 Sysmon 이벤트 유형에 대한 지식
워크플로우
1단계: 인증 공격 탐지
무차별 대입 공격 탐지 (EventCode 4625 — 로그온 실패):
index=wineventlog sourcetype="WinEventLog:Security" EventCode=4625
| stats count, dc(TargetUserName) AS unique_users, values(TargetUserName) AS targeted_users
by src_ip, Logon_Type, Status
| where count > 20
| eval attack_type = case(
Logon_Type=3, "네트워크 무차별 대입",
Logon_Type=10, "RDP 무차별 대입",
Logon_Type=2, "대화형 무차별 대입",
1=1, "기타"
)
| eval status_meaning = case(
Status="0xc000006d", "잘못된 사용자 이름 또는 암호",
Status="0xc000006a", "잘못된 암호 (유효한 사용자)",
Status="0xc0000234", "계정 잠김",
Status="0xc0000072", "계정 사용 안 함",
1=1, Status
)
| sort - count
| table src_ip, attack_type, status_meaning, count, unique_users, targeted_users
패스워드 스프레이 탐지:
index=wineventlog sourcetype="WinEventLog:Security" EventCode=4625 Logon_Type=3
| bin _time span=10m
| stats dc(TargetUserName) AS unique_users, count AS total_attempts,
values(TargetUserName) AS users_targeted by src_ip, _time
| where unique_users > 10 AND total_attempts < unique_users * 3
| eval spray_confidence = if(unique_users > 25, "높음", "중간")
실패 후 성공 로그온 (침해 지표):
index=wineventlog sourcetype="WinEventLog:Security"
(EventCode=4625 OR EventCode=4624) src_ip!="127.0.0.1"
| sort _time
| stats earliest(_time) AS first_seen, latest(_time) AS last_seen,
sum(eval(if(EventCode=4625,1,0))) AS failures,
sum(eval(if(EventCode=4624,1,0))) AS successes
by src_ip, TargetUserName, ComputerName
| where failures > 10 AND successes > 0
| eval time_to_success = round((last_seen - first_seen)/60, 1)
| sort - failures
2단계: 권한 상승 탐지
새 관리자 계정 생성 (T1136.001):
index=wineventlog sourcetype="WinEventLog:Security" EventCode=4720
| join TargetUserName type=left [
search index=wineventlog EventCode=4732 TargetUserName="Administrators"
| rename MemberName AS TargetUserName
]
| table _time, SubjectUserName, TargetUserName, ComputerName
| eval alert = "새 계정이 생성되어 Administrators 그룹에 추가됨"
특수 권한 할당 (EventCode 4672):
index=wineventlog sourcetype="WinEventLog:Security" EventCode=4672
SubjectUserName!="SYSTEM" SubjectUserName!="LOCAL SERVICE" SubjectUserName!="NETWORK SERVICE"
| stats count, values(PrivilegeList) AS privileges by SubjectUserName, ComputerName
| where count > 0
| search privileges IN ("SeDebugPrivilege", "SeTcbPrivilege", "SeBackupPrivilege",
"SeRestorePrivilege", "SeAssignPrimaryTokenPrivilege")
토큰 조작 탐지 (T1134):
index=sysmon EventCode=10 TargetImage="*\\lsass.exe"
GrantedAccess IN ("0x1010", "0x1038", "0x1fffff", "0x40")
| stats count by SourceImage, SourceUser, Computer, GrantedAccess
| where NOT match(SourceImage, "(svchost|csrss|wininit|MsMpEng|CrowdStrike)")
| sort - count
3단계: 지속성 메커니즘 탐지
예약 작업 생성 (T1053.005):
index=wineventlog (sourcetype="WinEventLog:Security" EventCode=4698)
OR (sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
Image="*\\schtasks.exe")
| eval task_info = coalesce(TaskContent, CommandLine)
| search task_info="*powershell*" OR task_info="*cmd*" OR task_info="*http*" OR task_info="*\\Temp\\*"
| table _time, Computer, SubjectUserName, TaskName, task_info
레지스트리 Run 키 수정 (T1547.001):
index=sysmon EventCode=13
TargetObject IN (
"*\\CurrentVersion\\Run\\*",
"*\\CurrentVersion\\RunOnce\\*",
"*\\CurrentVersion\\RunServices\\*",
"*\\Explorer\\Shell Folders\\*"
)
| stats count by Computer, Image, TargetObject, Details
| where NOT match(Image, "(explorer\\.exe|msiexec\\.exe|setup\\.exe)")
| sort - count
WMI 이벤트 구독 (T1546.003):
index=sysmon EventCode=20 OR EventCode=21
| stats count by Computer, Operation, Consumer, EventNamespace
| where count > 0
4단계: 측면 이동 탐지
원격 서비스 악용 (T1021.002 — SMB/Windows 관리 공유):
index=wineventlog sourcetype="WinEventLog:Security" EventCode=4624 Logon_Type=3
| stats dc(ComputerName) AS unique_destinations, values(ComputerName) AS targets
by src_ip, TargetUserName
| where unique_destinations > 3
| sort - unique_destinations
| table src_ip, TargetUserName, unique_destinations, targets
PsExec 탐지 (T1021.002):
index=sysmon EventCode=1
(Image="*\\psexec.exe" OR Image="*\\psexesvc.exe"
OR ParentImage="*\\psexesvc.exe"
OR OriginalFileName="psexec.c")
| table _time, Computer, User, ParentImage, Image, CommandLine
RDP 측면 이동 (T1021.001):
index=wineventlog sourcetype="WinEventLog:Security" EventCode=4624 Logon_Type=10
| stats count, dc(ComputerName) AS rdp_targets, values(ComputerName) AS destinations
by src_ip, TargetUserName
| where rdp_targets > 2
| sort - rdp_targets
5단계: 포렌식 타임라인 구축
손상된 호스트에 대한 포괄적인 타임라인 생성:
(index=wineventlog OR index=sysmon) Computer="WORKSTATION-042"
earliest="2024-03-14T00:00:00" latest="2024-03-16T00:00:00"
| eval event_description = case(
EventCode=4624, "로그온: ".TargetUserName." (유형 ".Logon_Type.")",
EventCode=4625, "로그온 실패: ".TargetUserName,
EventCode=4688 OR (sourcetype="XmlWinEventLog:*Sysmon*" AND EventCode=1),
"프로세스: ".Image." CMD: ".CommandLine,
EventCode=4698, "예약 작업: ".TaskName,
EventCode=3, "네트워크: ".DestinationIp.":".DestinationPort,
EventCode=11, "파일 생성됨: ".TargetFilename,
EventCode=13, "레지스트리: ".TargetObject,
1=1, "이벤트 ".EventCode
)
| sort _time
| table _time, EventCode, event_description, User, src_ip
6단계: 조회 테이블 생성 (정보 보강)
Windows 이벤트 ID 컨텍스트를 위한 참조 조회 테이블 구축:
| inputlookup windows_eventcode_lookup.csv
| table EventCode, Description, ATT_CK_Technique, Severity
조회 테이블이 없으면 생성:
EventCode,Description,ATT_CK_Technique,Severity
4624,성공적인 로그온,T1078,정보
4625,로그온 실패,T1110,낮음
4648,명시적 자격 증명 로그온,T1078,중간
4672,특수 권한 할당됨,T1134,중간
4688,새 프로세스 생성됨,T1059,정보
4698,예약 작업 생성됨,T1053.005,중간
4720,사용자 계정 생성됨,T1136.001,높음
4732,구성원이 보안 그룹에 추가됨,T1098,높음
4768,Kerberos TGT 요청됨,T1558,정보
4769,Kerberos 서비스 티켓,T1558.003,낮음
4771,Kerberos 사전 인증 실패,T1110,낮음
주요 개념
| 용어 | 정의 |
|---|---|
| EventCode 4624 | 성공적인 로그온 이벤트 — Logon_Type 2(대화형), 3(네트워크), 10(RDP), 7(잠금 해제) |
| EventCode 4625 | 로그온 실패 이벤트 — 상태 코드는 실패 원인 표시 (잘못된 암호, 계정 잠김, 사용 안 함) |
| Sysmon EventCode 1 | 전체 명령줄, 부모 프로세스 및 해시 정보가 포함된 프로세스 생성 |
| Sysmon EventCode 3 | 프로세스에 의해 시작된 네트워크 연결 — 소스/대상 IP, 포트 및 프로세스 컨텍스트 |
| Logon Type 3 | 네트워크 로그온 (SMB, WMI, PowerShell 원격) — 측면 이동의 주요 지표 |
| Logon Type 10 | RDP/터미널 서비스를 통한 원격 대화형 로그온 |
도구 및 시스템
- Splunk Enterprise: Windows 이벤트 로그 분석 및 상관 관계를 위한 SPL 쿼리 엔진을 갖춘 SIEM 플랫폼
- Sysmon (시스템 모니터): Microsoft Sysinternals 도구로, 상세한 프로세스, 네트워크 및 파일 활동 로깅 제공
- Splunk CIM: Windows 이벤트를 정규화된 필드에 매핑하여 여러 소스 간 쿼리를 가능하게 하는 공통 정보 모델
- WEF (Windows 이벤트 전달): 이벤트 로그를 수집기 서버로 중앙 집중화하는 기본 Windows 메커니즘
일반적인 시나리오
- Kerberoasting (T1558.003): 비표준 서비스 계정에 대해 암호화 유형 0x17(RC4)의 EventCode 4769 탐지
- DCSync (T1003.006): 도메인 컨트롤러가 아닌 소스에서 DS-Replication-Get-Changes와 함께 EventCode 4662 탐지
- 골든 티켓 (T1558.001): 비정상적인 티켓 속성(긴 수명, 비표준 암호화)의 EventCode 4769 탐지
- Pass-the-Hash (T1550.002): 예상치 못한 소스의 NTLM 인증과 함께 EventCode 4624 Logon_Type 3 탐지
- DLL 사이드 로딩 (T1574.002): 합법적인 프로세스에 의해 로드된 서명되지 않은 DLL을 보여주는 Sysmon EventCode 7
출력 형식
WINDOWS 이벤트 로그 분석 — 호스트: WORKSTATION-042
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
기간: 2024-03-14 ~ 2024-03-15
이벤트: 12,847개 총합 (보안: 9,231 | Sysmon: 3,616)
인증 요약:
성공적인 로그온 (4624): 487개 (유형 3: 312, 유형 10: 45, 유형 2: 130)
로그온 실패 (4625): 847개 (192.168.1.105에서 — 무차별 대입 공격)
명시적 자격 증명 (4648): 12개
의심스러운 발견:
[높음] 847회 로그온 실패 후 14:35에 192.168.1.105에서 성공
[높음] 14:38에 새 사용자 "backdoor_admin" 생성됨 (4720)
[높음] 14:38에 Administrators 그룹에 사용자 추가됨 (4732)
[중간] 14:42에 지속성 작업을 생성하는 schtasks.exe
[중간] 14:45에 PowerShell 인코딩된 명령 실행
ATT&CK 매핑:
T1110.001 — 암호 추측 (847회 로그온 실패)
T1136.001 — 로컬 계정 생성 (backdoor_admin)
T1053.005 — 예약 작업 (지속성)
T1059.001 — PowerShell (인코딩된 실행)