diff --git a/Config/Language/en.ps1 b/Config/Language/en.ps1 index 7a35a52e..c16ac4b9 100644 --- a/Config/Language/en.ps1 +++ b/Config/Language/en.ps1 @@ -336,6 +336,14 @@ $Error_NeedAdministratorPriv = "Error: You need to be running Powershell as Admi $Error_NoSaveOutputWithCSV = "Error: you need to specify -SaveOutput" $Error_NoNeedSaveOutputWithGUI = "Error: you cannot output to GUI with the -SaveOutput parameter" +#Remote live analysis +$remoteAnalysis_getComputername = "Please enter a remote machine name (IP address or Hostname) " +$remoteAnalysis_getCredential = "Please enter the remote computer credential." +$Error_remoteAnalysis_InvalidExecutionPolicy = "Error: ExecutionPolicy must be ""RemoteSigned""." +$Error_remoteAnalysis_UnregisteredComputername = "Error: you need to registered this remote computer in trustedhosts." +$Error_remoteAnalysis_FailedTestWSMan = "Error: Failed to run Test-WSMan." +$Warn_remoteAnalysis_Stopped_WinRMservice = "Warning: WinRM service on the remote computer may be stopped." +$Warn_remoteAnalysis_wrongRemoteComputerInfo = "Warning: Either ComputerName or Credentials, or both, are wrong." #function Show-Contributors $Show_Contributors = @@ -366,6 +374,9 @@ function Show-Help { Write-Host " -LogFile " -NoNewline -ForegroundColor Green Write-Host " : Creates a timelime from an offline .evtx file" + Write-Host " -RemoteLiveAnalysis" -NoNewline -ForegroundColor Green + Write-Host " : Creates a timeline based on the remote host's log" + Write-Host Write-Host "Analysis Type (Specify one):" diff --git a/Config/Language/ja.ps1 b/Config/Language/ja.ps1 index fad6e91d..d9ec6e8c 100644 --- a/Config/Language/ja.ps1 +++ b/Config/Language/ja.ps1 @@ -339,6 +339,15 @@ $Error_NeedAdministratorPriv = "エラー: Powershellを管理者として実 $Error_NoSaveOutputWithCSV = "エラー: 「-SaveOutput」を指定してください" $Error_NoNeedSaveOutputWithGUI = "エラー: 「-OutputGUI」と「-SaveOutput」を同時に指定できません。" +#Remote live analysis +$remoteAnalysis_getComputername = "リモートコンピュータのマシン名(IPアドレス or ホスト名)を入力してください " +$remoteAnalysis_getCredential = "リモートコンピュータの認証情報を入力してください。" +$Error_remoteAnalysis_InvalidExecutionPolicy = "エラー: ExecutionPolicyは「RemoteSigned」である必要があります。" +$Error_remoteAnalysis_UnregisteredComputername = "エラー: リモートコンピュータのマシン名をtrustedhostsに登録する必要があります。" +$Error_remoteAnalysis_FailedTestWSMan = "エラー: Test-WSManの実行が失敗しました。リモートコンピュータへの接続ができません。" +$Warn_remoteAnalysis_Stopped_WinRMservice = "注意: リモートコンピュータ上のWinRMサービスが停止している可能性があります。" +$Warn_remoteAnalysis_wrongRemoteComputerInfo = "注意: 間違ったマシン名または認証情報が入力された可能性があります。" + #function Show-Contributors $Show_Contributors = "コントリビューター: @@ -365,6 +374,9 @@ function Show-Help { Write-Host " -LogFile " -NoNewline -ForegroundColor Green Write-Host " : オフラインの.evtxファイルでタイムラインを作成する" + Write-Host " -RemoteLiveAnalysis" -NoNewline -ForegroundColor Green + Write-Host " : リモートマシンのログでタイムラインを作成する" + Write-Host Write-Host "解析タイプを一つ指定して下さい:" diff --git a/Config/splashlogos.ps1 b/Config/splashlogos.ps1 index 574b2f81..26235164 100644 --- a/Config/splashlogos.ps1 +++ b/Config/splashlogos.ps1 @@ -8,6 +8,7 @@ $logo = @" ╚══╝╚══╝ ╚══════╝╚══════╝╚═╝ ╚═╝ "@ function output-splash() { + Write-Host "" foreach ($line in $logo -split "`n") { foreach ($char in $line.tochararray()) { if ($([int]$char) -le 9580 -and $([int]$char) -ge 9552) { @@ -19,7 +20,7 @@ function output-splash() { } Write-Host "" } - Write-host "New Era of Windows Event Log Analyzer!" + Write-host "The Swiss Army Knife for Windows Event Logs!" write-host " by " -NoNewline write-host "Yamato Security" -ForegroundColor Yellow } diff --git a/Config/util.ps1 b/Config/util.ps1 index e12a58cd..29af8549 100644 --- a/Config/util.ps1 +++ b/Config/util.ps1 @@ -20,9 +20,19 @@ https://github.com/yamatosecurity #Functions: function Get-WinEventWithFilter { - param($WinEventFilter) + param( + $WinEventFilter, + $RemoteComputerInfo + ) $logs = $null - $logs = Get-WinEvent -FilterHashtable $WinEventFilter -Oldest -ErrorAction SilentlyContinue + + if ( $RemoteComputerInfo.RemoteLiveAnalysis -eq $true ){ + $logs = Get-WinEvent -ComputerName $RemoteComputerInfo.Computername -Credential $RemoteComputerInfo.Credential -FilterHashtable $WinEventFilter -Oldest -ErrorAction SilentlyContinue + } + else { + $logs = Get-WinEvent -FilterHashtable $WinEventFilter -Oldest -ErrorAction SilentlyContinue + } + if ($LASTEXITCODE -ne 0) { if ($logs) { Write-Host $Warn_GetEvent -ForegroundColor Black -BackgroundColor Yellow @@ -228,3 +238,36 @@ function Remove-Spaces($string) { $string = $string.trim() -Replace "\s+:", ":" return $string } + +function Get-RemoteComputerInfo { + $Computername = Read-Host $remoteAnalysis_getComputername + $trustedhosts = Get-Item WSMan:\localhost\client\trustedhosts + + If ($Computername -contains $trustedhosts.Value -or $trustedhosts.Value -eq "*"){ + $creds = Get-Credential -Message $remoteAnalysis_getCredential + $Test = Test-WSMan -ComputerName $Computername -Credential $creds -Authentication Negotiate + + If ( $Test -eq $NULL ) { + Write-Host "" + write-host $Error_remoteAnalysis_FailedTestWSMan -ForegroundColor White -BackgroundColor Red + write-host $Warn_remoteAnalysis_Stopped_WinRMservice -ForegroundColor Black -BackgroundColor Yellow + write-host $Warn_remoteAnalysis_wrongRemoteComputerInfo -ForegroundColor Black -BackgroundColor Yellow + Write-Host "" + Exit + } + + $RemoteComputerInfo = @{ + "RemoteLiveAnalysis" = $True; + "Computername" = $Computername; + "Credential" = $creds + } + return $RemoteComputerInfo + } + + else { + Write-Host "" + Write-Host $Error_remoteAnalysis_UnregisteredComputername -ForegroundColor White -BackgroundColor Red + Write-Host "" + Exit + } +} \ No newline at end of file diff --git a/WELA.ps1 b/WELA.ps1 index eee8fcc3..d48fa6cb 100755 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -90,6 +90,7 @@ param ( [switch]$IsDC, [switch]$ShowLogonID, [switch]$LiveAnalysis, + [switch]$RemoteLiveAnalysis, [string]$LogFile = "", [string]$LogDirectory = "", [switch]$ShowContributors, @@ -233,6 +234,12 @@ $AlertedEvents = 0 $SkippedLogs = 0 $TotalLogs = 0 +$RemoteComputerInfo = @{ + "RemoteLiveAnalysis" = $False; + "Computername" = ""; + "Credential" = "" +} + $HostLanguage = Get-WinSystemLocale | Select-Object Name # en-US, ja-JP, etc.. if ( $HostLanguage.Name -eq "ja-JP" -or $Japanese -eq $true ) { @@ -359,7 +366,7 @@ function Create-EventIDStatistics { $filesize = Format-FileSize( (get-item $LogFile).length ) Write-Host ( $Create_LogonTimeline_Filename -f $LogFile ) # "File Name: {0}" - $logs = Get-WinEventWithFilter -WinEventFilter $WineventFilter + $logs = Get-WinEventWithFilter -WinEventFilter $WineventFilter -RemoteComputerInfo $RemoteComputerInfo $eventlist = @{} $TotalNumberOfLogs = $logs.Count @@ -482,7 +489,7 @@ function Create-LogonTimeline { Write-Host ( $Create_LogonTimeline_Filesize -f $filesize ) # "File Size: {0}" Write-Host ( $Create_LogonTimeline_Estimated_Processing_Time -f $RuntimeHours, $RuntimeMinutes, $RuntimeSeconds ) # "Estimated processing time: {0} hours {1} minutes {2} seconds" - $logs = Get-WinEventWithFilter -WinEventFilter $WineventFilter + $logs = Get-WinEventWithFilter -WinEventFilter $WineventFilter -RemoteComputerInfo $RemoteComputerInfo $eventlist = @{} $TotalNumberOfLogs = 0 @@ -990,7 +997,7 @@ function Create-Timeline { Write-Host - $logs = Get-WinEventWithFilter $filter + $logs = Get-WinEventWithFilter -WinEventFilter $WineventFilter -RemoteComputerInfo $RemoteComputerInfo #Start reading in the logs. foreach ($event in $logs) { @@ -1749,14 +1756,14 @@ if ( $ShowContributors -eq $true ) { } -if ( $LiveAnalysis -eq $true -and $IsDC -eq $true ) { +if ( ($LiveAnalysis -eq $true -or $RemoteLiveAnalysis -eq $true ) -and $IsDC -eq $true ) { Write-Host Write-Host $Warn_DC_LiveAnalysis -ForegroundColor Black -BackgroundColor Yellow Write-Host exit } -if ( $LiveAnalysis -eq $true -and $LogFile -ne "" ) { +if ( ($LiveAnalysis -eq $true -or $RemoteLiveAnalysis -eq $true ) -and $LogFile -ne "" ) { Write-Host Write-Host $Error_InCompatible_LiveAnalysisAndLogFile -ForegroundColor White -BackgroundColor Red Write-Host @@ -1764,7 +1771,7 @@ if ( $LiveAnalysis -eq $true -and $LogFile -ne "" ) { } # Show-Helpは各言語のModuleに移動したためShow-Help関数は既に指定済みの言語の内容となっているため言語設定等の参照は行わない -if ( $LiveAnalysis -eq $false -and $LogFile -eq "" -and $EventIDStatistics -eq $false -and $LogonTimeline -eq $false -and $AccountInformation -eq $false ) { +if ( $LiveAnalysis -eq $false -and $RemoteLiveAnalysis -eq $false -and $LogFile -eq "" -and $EventIDStatistics -eq $false -and $LogonTimeline -eq $false -and $AccountInformation -eq $false ) { Show-Help exit @@ -1775,14 +1782,23 @@ if ( $LiveAnalysis -eq $false -and $LogFile -eq "" -and $EventIDStatistics -eq $ $evtxFiles = @($LogFile) -if ( $LiveAnalysis -eq $true ) { +if ( $LiveAnalysis -eq $true -or $RemoteLiveAnalysis -eq $true ) { Perform-LiveAnalysisChecks + $evtxFiles = @( "C:\Windows\System32\winevt\Logs\Security.evtx", "C:\Windows\System32\winevt\Logs\Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx" ) + if ( $LiveAnalysis -eq $true -or $RemoteLiveAnalysis -eq $true ) { + Perform-LiveAnalysisChecks + + if ( $RemoteLiveAnalysis -eq $true ) { + $RemoteComputerInfo = Get-RemoteComputerInfo #Get credential and computername + } + } + } elseif ( $LogDirectory -ne "" ) { @@ -1829,7 +1845,7 @@ if ($ruleStack.Count -ne 0) { $WineventFilter = @{} $WineventFilter.Add( "Path", $LogFile ) write-host "execute rule to $LogFile" - $logs = Get-WinEventWithFilter -WinEventFilter $WineventFilter + $logs = Get-WinEventWithFilter -WinEventFilter $WineventFilter -RemoteComputerInfo $RemoteComputerInfo foreach ($rule in $ruleStack.keys) { # write-host "execute rule:$rule" Invoke-Command -scriptblock $ruleStack[$rule] -ArgumentList @($logs)