-
Notifications
You must be signed in to change notification settings - Fork 82
/
WELA.ps1
executable file
·407 lines (328 loc) · 14.8 KB
/
WELA.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
<#
.SYNOPSIS
WELA (Windows Event Log Analyzer) is the Swiss Army knife for Windows event logs fast forensics.
WELA (Windows Event Log Analyzer)はWindowsイベントログのファストフォレンジック調査のための多目的な解析ツールです。
.DESCRIPTION
Yamato Security's WELA(Windows Event Log Analyzer) is the Swiss Army knife for Windows event logs fast forensics.
WELA's main goal is to create easy-to-analyze and as noise-free as possible event timelines and statistics to order to aid in quicker and higher quality forensic analysis.
Currently it only supports analyzing the security event log but will soon support other logs as well as detect attacks with custom rules as well as SIGMA rules.
By combining multiple log entries into single events of interest and ignoring data not relevant to forensic analysis, WELA usually performs data reducution
of noise of around 90%. WELA also will convert any hard to read data (such as hex status codes) into human readable format.
Tested on Windows Powershell 5.1 with future plans to support Powershell Core on Windows, Linux and MacOS.
大和セキュリティのWELA (Windows Event Log Analyzer)はWindowsイベントログのファストフォレンジック調査のための多目的な解析ツールです。
WELAの主なゴールはフォレンジック調査をより迅速、より高い精度でできるようになるべくノイズが少ない解析しやすいフォレンジックタイムラインを作ることです。
現在は主に「セキュリティ」ログを解析していますが、その他のログ、独自ルールによる攻撃検知、SIGMAルールによる攻撃検知等々に対応する予定です。
WELAは複数のログから情報を簡潔にまとめて、フォレンジック調査に役立つデータのみを抽出し、16進数のステータスコードなどユーザが理解しやすい形に変換して、
フォレンジック調査に役立つデータのみを抽出することができます。
Windows Powershell 5.1で検証済。Windows、Linux、MacOSでのPowershell Coreに対応する予定です。
.Example
Get the help menu(ヘルプメニューの表示):
.\WELA.ps1
Output Security Log Event ID Statistics (イベントIDの集計):
.\WELA.ps1 -SecurityEventID_Statistics
Live Analysis Timeline Generation (ライブ調査のタイムライン作成):
.\WELA.ps1 -SecurityLogonTimeline -LiveAnalysis
Offline Analysis Timeline Generation (オフライン調査のタイムライン作成):
.\WELA.ps1 -SecurityLogonTimeline -LogFile .\Cobalt-Strike-Security.evtx
Output Authentication events summary (ログオンイベントの集計):
.\WELA.ps1 -SecurityAuthenticationSummary
Analyze with a GUI(GUIでの解析):
-OutputGUI
日本語出力:
-Japanese
Save Output(結果の保存):
-SaveOutput file.txt
Display in UTC time (by default, it displays in local time) (UTC時間での表示。デフォルトはローカル時間):
-UTC
Security Logon Timeline Option: Show Logon IDs(Default: false)(ログオンIDの表示):
-ShowLogonID
.LINK
https://github.com/Yamato-Security/WELA
#>
# Tool: Windows Event Log Analyzer (WELA)
# Author: Zach Mathis, Yamatosecurity founder
# Other Core Developers: DustInDark, Chihiro (Ogino)
# Twitter: @yamatosecurity
# https://yamatosecurity.connpass.com/
#
# ツール名: Windows Event Log Analyzer (WELA・ゑ羅・ウェラ)
# 作者: 田中ザック
# その他のコア開発者: DustInDark, Chihiro (Ogino)
# Twitter: @yamatosecurity
# https://yamatosecurity.connpass.com/
#
#
# Inspired by Eric Conrad's DeepBlueCLI (https://github.com/sans-blue-team/DeepBlueCLI)
# Much help and inspiration from the Windows Event Log Analysis Cheatsheets by Steve Anson (https://www.forwarddefense.com/media/attachments/2021/05/15/windows-event-log-analyst-reference.pdf)
# and event log info from www.ultimatewindowssecurity.com.
# Many thanks to SIGMA: https://github.com/SigmaHQ/sigma
# as well as sbousseaden for providing sample attack event logs at https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES
#
# Eric Conrad氏のDeepBlueCLIからインスピレーションを受けました。 (https://github.com/sans-blue-team/DeepBlueCLI)
# Steve Anson氏のWindows Event Log Analysis Cheatsheet (https://www.forwarddefense.com/en/article/references-pdf)と
# www.ultimatewindowssecurity.comのイベントログ情報も参考にしています。
# 他に参考にしているプロジェクト:
# SIGMA: https://github.com/SigmaHQ/sigma
# sbousseaden氏の攻撃のサンプルイベントログ: https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES
param (
[switch]$Japanese,
[switch]$English,
[switch]$USDateFormat,
[switch]$EuropeDateFormat,
[string]$SaveOutput = "",
[string]$StartTimeline = "",
[string]$EndTimeline = "",
[switch]$IsDC,
[switch]$ShowLogonID,
[switch]$LiveAnalysis,
[switch]$RemoteLiveAnalysis,
[string]$LogFile = "",
[string]$LogDirectory = "",
[switch]$ShowContributors,
[switch]$SecurityEventID_Statistics,
[switch]$SecurityLogonTimeline,
[switch]$EasyToReadSecurityLogonTimeline,
[switch]$SecurityAuthenticationSummary,
[switch]$AccountInformation,
[switch]$OutputGUI,
[switch]$OutputCSV,
[switch]$UTC,
[switch]$HideTimezone,
[switch]$QuietLogo,
[string]$UseDetectRules = "0",
[switch]$AnalyzeNTLM_UsageBasic,
[switch]$AnalyzeNTLM_UsageDetailed
)
$ruleStack = @{};
#Global variables
$YEAVersion = "1.0"
$AnalyzersPath = $PSScriptRoot + "\Analyzers\"
$HostLanguage = Get-WinSystemLocale | Select-Object Name # en-US, ja-JP, etc..
$ProgramStartTime = Get-Date
$DisplayTimezone = !($HideTimezone);
#Startup stuff:
if (!$QuietLogo) {
Invoke-Expression './Config/splashlogos.ps1'
}
$ProgramStartTime = Get-Date
Import-Module './Config/util.ps1' -Force ;
$exectionpolicy = Get-ExecutionPolicy
# Read Rules
switch ($UseDetectRules.toupper()) {
"0" { break; }
"1" {
Get-ChildItem -Path './Rules/WELA-Rules' -Recurse -Filter *.ps1 | Foreach-Object { Import-Module $_.FullName -Force; . Add-Rule }
break;
}
"2" {
Write-Host $Confirm_DefConfirm_ExecutionPolicy_Bypassed -ForegroundColor Black -BackgroundColor Yellow
if ($exectionpolicy.ToString().ToUpper() -ne "BYPASS") {
Write-Host $Error_ExecutionPolicy_Bypassed -ForegroundColor White -BackgroundColor Red
}
Get-ChildItem -Path './Rules/SIGMA' -Recurse -Filter *.ps1 | Foreach-Object { Import-Module $_.FullName -Force; . Add-Rule }
break;
}
"ALL" {
Get-ChildItem -Path './Rules' -Recurse -Filter *.ps1 | Foreach-Object { Import-Module $_.FullName -Force; . Add-Rule }
break;
}
Default {}
}
#Functions:
#Set the language: English or Japanese
if ( $HostLanguage.Name -eq "ja-JP" -and $English -eq $true ) {
Import-Module './Config/Language/en.ps1' -Force;
}
elseif ( $HostLanguage.Name -eq "ja-JP" -or $Japanese -eq $true ) {
Import-Module './Config/Language/ja.ps1' -Force;
}
else {
Import-Module './Config/Language/en.ps1' -Force;
}
#Set the date format
$DateFormat = "yyyy-MM-dd HH:mm:ss.ff"
if ( $USDateFormat -eq $true ) {
$DateFormat = "MM/dd/yyyy HH:mm:ss.ff"
}
if ( $EuropeDateFormat -eq $true ) {
$DateFormat = "dd.MM.yyyy HH:mm:ss.ff"
}
#Set timezone
$Timezone = Get-TimeZone
$TimezoneName = $Timezone.DisplayName #例:(UTC+09:00 Osaka, Sapporo, Tokyo)
$StartParen = $TimezoneName.IndexOf('(') #get position of (
$EndParen = $TimezoneName.IndexOf(')') #position of )
$UTCOffset = $TimezoneName.SubString( $StartParen + 1 , $EndParen - $StartParen - 1 ) # UTC+09:00
if ( $UTC -eq $true ) {
$UTCOffset = "UTC"
}
#Check $StartTimeline and $EndTimeline
if ( $StartTimeline -ne "" ) {
$StartTimeline = Check-DateString -DateString $StartTimeline -DateFormat $DateFormat
if ( $StartTimeline -eq "" ) {
Write-Host
Write-Host $Error_Incorrect_StartTimeline -ForegroundColor White -BackgroundColor Red # Error: Failed to parse Starttimeline. Please check the format of the input value.
Write-Host
exit
}
}
if ( $EndTimeline -ne "" ) {
$EndTimeline = Check-DateString -DateString $EndTimeline -DateFormat $DateFormat
if ( $EndTimeline -eq "" ) {
Write-Host
Write-Host $Error_Incorrect_EndTimeline -ForegroundColor White -BackgroundColor Red # Error: Failed to parse Endtimeline. Please check the format of the input value.
Write-Host
exit
}
}
#Functions:
function Show-Contributors {
Write-Host
Write-Host $Show_Contributors1 -ForegroundColor Red
Write-Host $Show_Contributors2 -ForegroundColor Cyan
Write-Host
}
function Check-Administrator {
$user = [Security.Principal.WindowsIdentity]::GetCurrent();
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
function Perform-LiveAnalysisChecks {
if ( $IsWindows -eq $true -or $env:OS -eq "Windows_NT" ) {
#Check if running as an admin
$isAdmin = Check-Administrator
if ( $isAdmin -eq $false ) {
Write-Host
Write-Host $Error_NeedAdministratorPriv -ForegroundColor White -BackgroundColor Red
Write-Host
Exit
}
}
else {
#Trying to run live analysis on Mac or Linux
Write-Host
Write-Host $Error_NotSupport_LiveAnalysys -ForegroundColor White -BackgroundColor Red
Write-Host
Exit
}
}
#Main
# -ShowContributors
if ( $ShowContributors -eq $true ) {
Show-Contributors
exit
}
if ( ($LiveAnalysis -eq $true -or $RemoteLiveAnalysis -eq $true ) -and $IsDC -eq $true ) {
Write-Host
Write-Host $Warn_DC_LiveAnalysis -ForegroundColor Black -BackgroundColor Yellow #Warning: You probably should not be doing live analysis on a Domain Controller. Please copy log files offline for analysis.
Write-Host
exit
}
#Error: You cannot specify -LiveAnalysis and -LogFile (or -LogDirectory) at the same time
if ( $LiveAnalysis -eq $true -and ($LogFile -ne "" -or $LogDirectory -ne "")) {
Write-Host
Write-Host $Error_InCompatible_LiveAnalysisAndLogFile -ForegroundColor White -BackgroundColor Red # Error: You cannot specify -LiveAnalysis and -LogFile (or -LogDirectory) at the same time
Write-Host
exit
}
# Show-Helpは各言語のModuleに移動したためShow-Help関数は既に指定済みの言語の内容となっているため言語設定等の参照は行わない
if ( $LiveAnalysis -eq $false -and $RemoteLiveAnalysis -eq $false -and $LogFile -eq "" -and $LogDirectory -eq "" -and $SecurityEventID_Statistics -eq $false -and $SecurityLogonTimeline -eq $false -and $AccountInformation -eq $false -and $AnalyzeNTLM_UsageBasic -eq $false -and $AnalyzeNTLM_UsageDetailed -eq $false -and $SecurityAuthenticationSummary -eq $false) {
Show-Help
exit
}
#No analysis source was specified
if ( $SecurityEventID_Statistics -eq $true -or
$SecurityLogonTimeline -eq $true -or
$AnalyzeNTLM_UsageBasic -eq $true -or
$AnalyzeNTLM_UsageDetailed -eq $true ) {
if ( $LiveAnalysis -ne $true -and $LogFile -eq "" -and $LogDirectory -eq "") {
Write-Host
Write-Host $Error_InCompatible_NoLiveAnalysisOrLogFileSpecified -ForegroundColor White -BackgroundColor Red # Error: You need to specify -LiveAnalysis or -LogFile
Write-Host
exit
}
}
# -LogFile
$evtxFiles = [System.Collections.ArrayList] @()
if ($LogFile -ne "") {
[void]$evtxFiles.Add($LogFile)
}
if ( $LiveAnalysis -eq $true -or $RemoteLiveAnalysis -eq $true ) {
Perform-LiveAnalysisChecks
if ($AnalyzeNTLM -eq $true) {
$evtxFiles = @(
"C:\Windows\System32\Winevt\Logs\Microsoft-Windows-NTLM%4Operational.evtx"
)
}
elseif ($SecurityLogonTimeline -eq $true -or $SecurityEventID_Statistics -eq $true) {
$evtxFiles = @(
"C:\Windows\System32\winevt\Logs\Security.evtx"
)
}
else {
$evtxFiles = @(
"C:\Windows\System32\winevt\Logs\Security.evtx",
"C:\Windows\System32\winevt\Logs\Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx"
)
}
if ( $RemoteLiveAnalysis -eq $true ) {
$RemoteComputerInfo = Get-RemoteComputerInfo #Get credential and computername
}
}
# -LogDirectory
elseif ( $LogDirectory -ne "" ) {
if ($LogFile -ne "") {
Write-Host
Write-Host $Error_InCompatible_LogDirAndFile -ForegroundColor White -BackgroundColor Red
Write-Host
exit
}
Get-ChildItem -Filter *.evtx -Recurse -Path $LogDirectory | ForEach-Object { [void]$evtxFiles.Add($_.FullName) }
}
# Run analysis
foreach ( $LogFile in $evtxFiles ) {
if ( $SecurityEventID_Statistics -eq $true ) {
. ($AnalyzersPath + "Security-EventID_Statistics.ps1")
Create-SecurityEventIDStatistics -filePath $LogFile
}
if ( $SecurityLogonTimeline -eq $true ) {
. ($AnalyzersPath + "Security-LogonTimeline.ps1")
Create-SecurityLogonTimeline $UTCOffset -filePath $LogFile
}
if ( $EasyToReadSecurityLogonTimeline -eq $true ) {
. ($AnalyzersPath + "Security-LogonTimeline.ps1")
Create-EasyToReadSecurityLogonTimeline $UTCOffset -filePath $LogFile
}
if ( $AnalyzeNTLM_UsageBasic -eq $true) {
. ($AnalyzersPath + "NTLM-Operational-Usage.ps1")
Analyze-NTLMOperationalBasic
}
if ( $AnalyzeNTLM_UsageDetailed -eq $true) {
. ($AnalyzersPath + "NTLM-Operational-Usage.ps1")
Analyze-NTLMOperationalDetailed
}
if ( $SecurityAuthenticationSummary -eq $true ) {
. ($AnalyzersPath + "Security-AuthenticationSummary.ps1")
Create-SecurityAuthenticationSummary -filePath $LogFile
}
}
$progcnt = 0;
$maxprogcnt = $evtxFiles.Count * $ruleStack.Count
$interval = $maxprogcnt * 0.1
if ($ruleStack.Count -ne 0) {
foreach ($LogFile in $evtxFiles) {
$WineventFilter = @{}
$WineventFilter.Add( "Path", $LogFile )
# write-host "execute rule to $LogFile"
$logs = Get-WinEventWithFilter -WinEventFilter $WineventFilter -RemoteComputerInfo $RemoteComputerInfo -ErrorAction SilentlyContinue
foreach ($rule in $ruleStack.keys) {
#write-host "execute rule:$rule"
Invoke-Command -scriptblock $ruleStack[$rule] -ArgumentList @($logs)
}
$progcnt += 1;
if ($progcnt % $interval -eq 0) {
Write-Host "Check Detect Rule... Checked File($progcnt of $maxprogcnt)" -ForegroundColor Black -BackgroundColor Green
}
}
}
Remove-Variable ruleStack
Set-ExecutionPolicy $exectionpolicy -scope Process