From b41b1b4e5323d102d5895924d2a1e459ddefe179 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 00:41:55 +0900 Subject: [PATCH 01/27] chg: Output horizontally --- WELA.ps1 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index 4ca020c3..1d0044f7 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -95,10 +95,15 @@ function ShowRulesCountsByLevel { "low" = "Green" "informational" = "White" # Assuming a default color for informational } - + $i = 0 $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] - Write-Host "$($_.Level) rules: $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color + Write-Host -NoNewline "$($_.Level) rules: $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color + if ($i -lt $levelColorMap.Count - 1) + { + Write-Host -NoNewline ", " + } + $i++ } Write-Output "" Write-Output "" From 7448d54c82241037b0816b055199b94407dfb012 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 00:45:18 +0900 Subject: [PATCH 02/27] chg: Output horizontally --- WELA.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index 1d0044f7..fba8e22f 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -99,7 +99,7 @@ function ShowRulesCountsByLevel { $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] Write-Host -NoNewline "$($_.Level) rules: $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color - if ($i -lt $levelColorMap.Count - 1) + if ($i -lt $usableRate.Count - 1) { Write-Host -NoNewline ", " } From 6f716312fcdfe915e27eb6f54bb783db603b9a71 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 00:46:38 +0900 Subject: [PATCH 03/27] chg: Output horizontally --- WELA.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index fba8e22f..7169ea84 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -98,7 +98,7 @@ function ShowRulesCountsByLevel { $i = 0 $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] - Write-Host -NoNewline "$($_.Level) rules: $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color + Write-Host -NoNewline " - $($_.Level) rules: $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color if ($i -lt $usableRate.Count - 1) { Write-Host -NoNewline ", " From 5233533ee5ec34e99447ba5d00e324b05b0de27b Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 00:48:07 +0900 Subject: [PATCH 04/27] chg: Output horizontally --- WELA.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index 7169ea84..6800f1e4 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -96,9 +96,10 @@ function ShowRulesCountsByLevel { "informational" = "White" # Assuming a default color for informational } $i = 0 + Write-Host -NoNewline " - " $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] - Write-Host -NoNewline " - $($_.Level) rules: $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color + Write-Host -NoNewline "$($_.Level) rules: $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color if ($i -lt $usableRate.Count - 1) { Write-Host -NoNewline ", " From f541c87a44c052fd41545f4030ed31a33b1d3805 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 00:57:22 +0900 Subject: [PATCH 05/27] chg: Output horizontally --- WELA.ps1 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index 6800f1e4..7a5d0019 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -179,10 +179,15 @@ $usablePwsModRate = CalculateUsableRate -counts $usablePwsModCounts -totalCounts $usablePwsScrRate = CalculateUsableRate -counts $usablePwsScrCounts -totalCounts $totalPwsScrCounts # Step 6: Show the number of usable and unusable rules for each level -ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules:" -ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules:" -ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules:" -ShowRulesCountsByLevel -usableRate $usablePwsScrRate -msg "PowerShell script block logging detection rules:" +$pwsModEnabled = CheckRegistryValue -registryPath "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -valueName "EnableModuleLogging" -expectedValue 1 +$pwsScrEnabled = CheckRegistryValue -registryPath "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -valueName "EnableScriptBlockLogging" -expectedValue 1 +$pwsModStatus = if ($pwsModEnabled) { "Enabled" } else { "Disabled" } +$pwsSrcStatus = if ($pwsScrEnabled) { "Enabled" } else { "Disabled" } + +ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules: (Partially Enabled)" +ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules: (Enabled)" +ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules: ($pwsModStatus)" +ShowRulesCountsByLevel -usableRate $usablePwsScrRate -msg "PowerShell script block logging detection rules: ($pwsSrcStatus)" Write-Output "Usable detection rules list saved to: UsableRules.csv" Write-Output "Unusable detection rules list saved to: UnusableRules.csv" From 855d1df32fef5c8855e61050d53c6840d0dd0436 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 01:04:35 +0900 Subject: [PATCH 06/27] chg: Output horizontally --- WELA.ps1 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index 7a5d0019..376431cb 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -58,12 +58,24 @@ function Set-Applicable { function Get-RuleCounts { param ($rules) - $rules | Group-Object -Property level | ForEach-Object { + $levels = @("critical", "high", "medium", "low", "informational") + $counts = $rules | Group-Object -Property level | ForEach-Object { [PSCustomObject]@{ Level = $_.Name Count = $_.Count } } + + foreach ($level in $levels) { + if (-not ($counts | Where-Object { $_.Level -eq $level })) { + $counts += [PSCustomObject]@{ + Level = $level + Count = 0 + } + } + } + + return $counts } function CalculateUsableRate { From fc249547264aafd04d23394f27d19c943d1601ff Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 01:11:14 +0900 Subject: [PATCH 07/27] chg: Output horizontally --- WELA.ps1 | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index 376431cb..84a4c998 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -59,23 +59,24 @@ function Set-Applicable { function Get-RuleCounts { param ($rules) $levels = @("critical", "high", "medium", "low", "informational") - $counts = $rules | Group-Object -Property level | ForEach-Object { - [PSCustomObject]@{ - Level = $_.Name - Count = $_.Count - } + $counts = @{} + + $rules | Group-Object -Property level | ForEach-Object { + $counts[$_.Name] = $_.Count } foreach ($level in $levels) { - if (-not ($counts | Where-Object { $_.Level -eq $level })) { - $counts += [PSCustomObject]@{ - Level = $level - Count = 0 - } + if (-not $counts.ContainsKey($level)) { + $counts[$level] = 0 } } - return $counts + return $counts.GetEnumerator() | ForEach-Object { + [PSCustomObject]@{ + Level = $_.Key + Count = $_.Value + } + } } function CalculateUsableRate { From 85de4172ac3a5136b36cf471a7afa938c4b74c0d Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 07:59:11 +0900 Subject: [PATCH 08/27] chg: Output horizontally --- WELA.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index 84a4c998..7c757dd0 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -164,7 +164,7 @@ $allPwsScrRules = $rules | Where-Object { $_.channel -eq "pwsh" -and $_.event $usableSecRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "sec" } $usablePwsRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" } -$usablePwsClaRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" -and $_.event_ids -contains "400" } +$usablePwsClaRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" -and ($_.event_ids -contains "400" -or $_.event_ids -contains "600" -or $_.event_ids.Count -eq 0) } $usablePwsModRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" -and $_.event_ids -contains "4103" } $usablePwsScrRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" -and $_.event_ids -contains "4104" } @@ -197,6 +197,9 @@ $pwsScrEnabled = CheckRegistryValue -registryPath "HKLM:\SOFTWARE\Wow6432Node\Po $pwsModStatus = if ($pwsModEnabled) { "Enabled" } else { "Disabled" } $pwsSrcStatus = if ($pwsScrEnabled) { "Enabled" } else { "Disabled" } +# 123 / 1860 (6%) + + ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules: (Partially Enabled)" ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules: (Enabled)" ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules: ($pwsModStatus)" From 5dcc297d7a496a726d978e700e1da9a4e86b1f2d Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 08:08:12 +0900 Subject: [PATCH 09/27] chg: Output horizontally --- WELA.ps1 | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index 7c757dd0..40641121 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -98,6 +98,13 @@ function CalculateUsableRate { return $result } +function CalculateTotalUsableRate { + param ($usableRate) + $totalUsable = ($usableRate | Measure-Object -Property UsableCount -Sum).Sum + $totalRulesCount = ($usableRate | Measure-Object -Property TotalCount -Sum).Sum + return "{0:N2}" -f ($totalUsable / $totalRulesCount * 100) +} + function ShowRulesCountsByLevel { param ($usableRate, $msg) Write-Output $msg @@ -198,12 +205,15 @@ $pwsModStatus = if ($pwsModEnabled) { "Enabled" } else { "Disabled" } $pwsSrcStatus = if ($pwsScrEnabled) { "Enabled" } else { "Disabled" } # 123 / 1860 (6%) +$totalUsableSecRate = CalculateTotalUsableRate -usableRate $usableSecRate +$totalUsablePwsClaRate = CalculateTotalUsableRate -usableRate $usablePwsClaRate +$totalUsablePwsModRate = CalculateTotalUsableRate -usableRate $usablePwsModRate +$totalUsablePwsScrRate = CalculateTotalUsableRate -usableRate $usablePwsScrRate - -ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules: (Partially Enabled)" -ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules: (Enabled)" -ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules: ($pwsModStatus)" -ShowRulesCountsByLevel -usableRate $usablePwsScrRate -msg "PowerShell script block logging detection rules: ($pwsSrcStatus)" +ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules: $totalUsableSecRate (Partially Enabled)" +ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules: $totalUsablePwsClaRate (Enabled)" +ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules: $totalUsablePwsModRate ($pwsModStatus)" +ShowRulesCountsByLevel -usableRate $usablePwsScrRate -msg "PowerShell script block logging detection rules: $totalUsablePwsScrRate ($pwsSrcStatus)" Write-Output "Usable detection rules list saved to: UsableRules.csv" Write-Output "Unusable detection rules list saved to: UnusableRules.csv" From 649ca143fea900afe60775be568879b93c8fb898 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 08:12:48 +0900 Subject: [PATCH 10/27] chg: Output horizontally --- WELA.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index 40641121..0ac15ad3 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -102,7 +102,7 @@ function CalculateTotalUsableRate { param ($usableRate) $totalUsable = ($usableRate | Measure-Object -Property UsableCount -Sum).Sum $totalRulesCount = ($usableRate | Measure-Object -Property TotalCount -Sum).Sum - return "{0:N2}" -f ($totalUsable / $totalRulesCount * 100) + return "{0:N2}%" -f ($totalUsable / $totalRulesCount * 100) } function ShowRulesCountsByLevel { From 2704b25bc44b4fe201fdd086cc1722d0fde6f144 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 08:14:50 +0900 Subject: [PATCH 11/27] chg: Output horizontally --- .github/workflows/check-audit.yml | 2 +- .github/workflows/create-rule-meta.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-audit.yml b/.github/workflows/check-audit.yml index 6903233b..88234fc9 100644 --- a/.github/workflows/check-audit.yml +++ b/.github/workflows/check-audit.yml @@ -2,7 +2,7 @@ name: Check audit setting on: push: - branches: [ "main" ] + branches: [ "*" ] workflow_dispatch: jobs: diff --git a/.github/workflows/create-rule-meta.yml b/.github/workflows/create-rule-meta.yml index 3c049578..b5991ae6 100644 --- a/.github/workflows/create-rule-meta.yml +++ b/.github/workflows/create-rule-meta.yml @@ -1,7 +1,7 @@ name: create-rule-meta.json on: push: - branches: [ "main" ] + branches: [ "*" ] workflow_dispatch: jobs: From 29b5b3ac27ed9fe9942f2199bb11112bcb44311a Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 08:16:27 +0900 Subject: [PATCH 12/27] chg: Output horizontally --- WELA.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index 0ac15ad3..61910f10 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -204,7 +204,7 @@ $pwsScrEnabled = CheckRegistryValue -registryPath "HKLM:\SOFTWARE\Wow6432Node\Po $pwsModStatus = if ($pwsModEnabled) { "Enabled" } else { "Disabled" } $pwsSrcStatus = if ($pwsScrEnabled) { "Enabled" } else { "Disabled" } -# 123 / 1860 (6%) +# Step 7: Calculate the total usable rate $totalUsableSecRate = CalculateTotalUsableRate -usableRate $usableSecRate $totalUsablePwsClaRate = CalculateTotalUsableRate -usableRate $usablePwsClaRate $totalUsablePwsModRate = CalculateTotalUsableRate -usableRate $usablePwsModRate @@ -223,6 +223,6 @@ $totalRulesCount = ($totalCounts | Measure-Object -Property Count -Sum).Sum $utilizationPercentage = "{0:N2}" -f (($totalUsable / $totalRulesCount) * 100) Write-Output "You can utilize $utilizationPercentage% of your detection rules." -# Step 7: Save the lists of usable and unusable rules to CSV files +# Step 8: Save the lists of usable and unusable rules to CSV files $usableSecRules | Select-Object title, level, id | Export-Csv -Path "UsableRules.csv" -NoTypeInformation $unusableRules | Select-Object title, level, id | Export-Csv -Path "UnusableRules.csv" -NoTypeInformation From 3748ac2afb738a4b0ccb40e45d169bbd0b6607c3 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 08:19:11 +0900 Subject: [PATCH 13/27] chg: Output horizontally --- .github/workflows/create-rule-meta.yml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.github/workflows/create-rule-meta.yml b/.github/workflows/create-rule-meta.yml index b5991ae6..ab3433b5 100644 --- a/.github/workflows/create-rule-meta.yml +++ b/.github/workflows/create-rule-meta.yml @@ -1,7 +1,7 @@ name: create-rule-meta.json on: push: - branches: [ "*" ] + branches: [ "main" ] workflow_dispatch: jobs: @@ -19,15 +19,3 @@ jobs: - name: Run run: cd wela-extractor && cargo run --release -- ../hayabusa-rules ../config/eid_subcategory_mapping.csv ../config/security_rules.json - - - name: Push changes - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - git config --global user.name 'github-actions[bot]' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - git add *.json - git commit -m "Automated update" - if [ "$(git log -1 --pretty=%B)" = "Automated update" ]; then - git push origin main - fi From 6861a7dfb09ee8ce48f8b7a76a9185813f7a7d9f Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 10:37:55 +0900 Subject: [PATCH 14/27] chg: Output horizontally --- WELA.ps1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index 61910f10..f1f718ab 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -106,8 +106,10 @@ function CalculateTotalUsableRate { } function ShowRulesCountsByLevel { - param ($usableRate, $msg) - Write-Output $msg + param ($usableRate, $msg, $colorMsg) + Write-Host -NoNewline $msg + $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Paritial") { "DarkYellow" } else { "White" } + Write-Host "$colorMsg" -ForegroundColor $color $levelColorMap = [ordered]@{ "critical" = "Red" "high" = "DarkYellow" @@ -119,7 +121,7 @@ function ShowRulesCountsByLevel { Write-Host -NoNewline " - " $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] - Write-Host -NoNewline "$($_.Level) rules: $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color + Write-Host -NoNewline "$($_.Level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color if ($i -lt $usableRate.Count - 1) { Write-Host -NoNewline ", " @@ -210,10 +212,10 @@ $totalUsablePwsClaRate = CalculateTotalUsableRate -usableRate $usablePwsClaRate $totalUsablePwsModRate = CalculateTotalUsableRate -usableRate $usablePwsModRate $totalUsablePwsScrRate = CalculateTotalUsableRate -usableRate $usablePwsScrRate -ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules: $totalUsableSecRate (Partially Enabled)" -ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules: $totalUsablePwsClaRate (Enabled)" -ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules: $totalUsablePwsModRate ($pwsModStatus)" -ShowRulesCountsByLevel -usableRate $usablePwsScrRate -msg "PowerShell script block logging detection rules: $totalUsablePwsScrRate ($pwsSrcStatus)" +ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules:" -colorMsg "$totalUsableSecRate (Partially Enabled)" +ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules:" -colorMsg "$totalUsablePwsClaRate (Enabled)" +ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules:" -colorMsg "$totalUsablePwsModRate ($pwsModStatus)" +ShowRulesCountsByLevel -usableRate $usablePwsScrRate -msg "PowerShell script block logging detection rules:" -colorMsg "$totalUsablePwsScrRate ($pwsSrcStatus)" Write-Output "Usable detection rules list saved to: UsableRules.csv" Write-Output "Unusable detection rules list saved to: UnusableRules.csv" From 55b3513edf6619570fd47f0c871c2aa3633ba7c8 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 10:38:59 +0900 Subject: [PATCH 15/27] chg: Output horizontally --- WELA.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index f1f718ab..275e37e2 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -212,10 +212,10 @@ $totalUsablePwsClaRate = CalculateTotalUsableRate -usableRate $usablePwsClaRate $totalUsablePwsModRate = CalculateTotalUsableRate -usableRate $usablePwsModRate $totalUsablePwsScrRate = CalculateTotalUsableRate -usableRate $usablePwsScrRate -ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules:" -colorMsg "$totalUsableSecRate (Partially Enabled)" -ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules:" -colorMsg "$totalUsablePwsClaRate (Enabled)" -ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules:" -colorMsg "$totalUsablePwsModRate ($pwsModStatus)" -ShowRulesCountsByLevel -usableRate $usablePwsScrRate -msg "PowerShell script block logging detection rules:" -colorMsg "$totalUsablePwsScrRate ($pwsSrcStatus)" +ShowRulesCountsByLevel -usableRate $usableSecRate -msg "Security event log detection rules: " -colorMsg "$totalUsableSecRate (Partially Enabled)" +ShowRulesCountsByLevel -usableRate $usablePwsClaRate -msg "PowerShell classic logging detection rules: " -colorMsg "$totalUsablePwsClaRate (Enabled)" +ShowRulesCountsByLevel -usableRate $usablePwsModRate -msg "PowerShell module logging detection rules: " -colorMsg "$totalUsablePwsModRate ($pwsModStatus)" +ShowRulesCountsByLevel -usableRate $usablePwsScrRate -msg "PowerShell script block logging detection rules: " -colorMsg "$totalUsablePwsScrRate ($pwsSrcStatus)" Write-Output "Usable detection rules list saved to: UsableRules.csv" Write-Output "Unusable detection rules list saved to: UnusableRules.csv" From f26a8bc6b20cc6b15ea4e347872485f9e54099c3 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 10:39:54 +0900 Subject: [PATCH 16/27] chg: Output horizontally --- WELA.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index 275e37e2..607fe294 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -108,7 +108,7 @@ function CalculateTotalUsableRate { function ShowRulesCountsByLevel { param ($usableRate, $msg, $colorMsg) Write-Host -NoNewline $msg - $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Paritial") { "DarkYellow" } else { "White" } + $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -contains "Paritial") { "DarkYellow" } else { "White" } Write-Host "$colorMsg" -ForegroundColor $color $levelColorMap = [ordered]@{ "critical" = "Red" From 3a800ea1ed0c54848f0432c7b7f82c986717890a Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 10:40:38 +0900 Subject: [PATCH 17/27] chg: Output horizontally --- WELA.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index 607fe294..f9cce727 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -108,7 +108,7 @@ function CalculateTotalUsableRate { function ShowRulesCountsByLevel { param ($usableRate, $msg, $colorMsg) Write-Host -NoNewline $msg - $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -contains "Paritial") { "DarkYellow" } else { "White" } + $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Partially") { "DarkYellow" } else { "White" } Write-Host "$colorMsg" -ForegroundColor $color $levelColorMap = [ordered]@{ "critical" = "Red" From ec88eff4db5c3419e267334604cad8d2372accc6 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 21 Mar 2025 10:41:29 +0900 Subject: [PATCH 18/27] chg: Output horizontally --- WELA.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELA.ps1 b/WELA.ps1 index f9cce727..dbbe565c 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -108,7 +108,7 @@ function CalculateTotalUsableRate { function ShowRulesCountsByLevel { param ($usableRate, $msg, $colorMsg) Write-Host -NoNewline $msg - $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Partially") { "DarkYellow" } else { "White" } + $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Partially") { "DarkYellow" } else { "Green" } Write-Host "$colorMsg" -ForegroundColor $color $levelColorMap = [ordered]@{ "critical" = "Red" From 48ed63e36a58cce9e9a8f11d985ef61ce24a31a6 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 22 Mar 2025 14:58:50 +0900 Subject: [PATCH 19/27] refactor --- WELA.ps1 | 145 +---------------------------- WELAFunctions.psm1 | 226 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+), 144 deletions(-) create mode 100644 WELAFunctions.psm1 diff --git a/WELA.ps1 b/WELA.ps1 index dbbe565c..42c59ae9 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -1,147 +1,4 @@ -function CheckRegistryValue { - param ( - [string]$registryPath, - [string]$valueName, - [int]$expectedValue - ) - - try { - $value = Get-ItemProperty -Path $registryPath -Name $valueName -ErrorAction Stop - if ($value.$valueName -eq $expectedValue) { - return $true - } else { - return $false - } - } catch { - return $false - } -} - -function Set-Applicable { - param ( - [string]$autidpolTxt, - [string]$jsonRulePath - ) - - $extractedGuids = [System.Collections.Generic.HashSet[string]]::new() - Get-Content -Path $autidpolTxt | Select-String -NotMatch "No Auditing" | ForEach-Object { - if ($_ -match '{(.*?)}') { - [void]$extractedGuids.Add($matches[1]) - } - } - - $pwshModuleLogging = CheckRegistryValue -registryPath "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -valueName "EnableModuleLogging" -expectedValue 1 - $pwshScriptLogging = CheckRegistryValue -registryPath "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -valueName "EnableScriptBlockLogging" -expectedValue 1 - - $jsonContent = Get-Content -Path $jsonRulePath -Raw | ConvertFrom-Json - foreach ($rule in $jsonContent) { - $rule | Add-Member -MemberType NoteProperty -Name "applicable" -Value $false - if ($rule.channel -eq "pwsh") { - if ($rule.event_ids -contains "400") { - $rule.applicable = $true - } elseif ($rule.event_ids -contains "4103") { - $rule.applicable = $pwshModuleLogging - } elseif ($rule.event_ids -contains "4104") { - $rule.applicable = $pwshScriptLogging - } - continue - } - foreach ($guid in $rule.subcategory_guids) { - if ($extractedGuids.Contains($guid)) { - $rule.applicable = $true - break - } - } - } - return $jsonContent -} - -function Get-RuleCounts { - param ($rules) - $levels = @("critical", "high", "medium", "low", "informational") - $counts = @{} - - $rules | Group-Object -Property level | ForEach-Object { - $counts[$_.Name] = $_.Count - } - - foreach ($level in $levels) { - if (-not $counts.ContainsKey($level)) { - $counts[$level] = 0 - } - } - - return $counts.GetEnumerator() | ForEach-Object { - [PSCustomObject]@{ - Level = $_.Key - Count = $_.Value - } - } -} - -function CalculateUsableRate { - param ($counts, $totalCounts) - $result = @() - $totalCounts | ForEach-Object { - $level = $_.Level - $total = $_.Count - $usableCount = ($counts | Where-Object Level -eq $level | Select-Object -ExpandProperty Count -First 1) - if ($null -eq $usableCount) { $usableCount = 0 } - $percentage = if ($total -ne 0) { "{0:N2}" -f ($usableCount / $total * 100) } else { "0.00" } - $result += [PSCustomObject]@{ - Level = $level - UsableCount = $usableCount - TotalCount = $total - Percentage = $percentage - } - } - return $result -} - -function CalculateTotalUsableRate { - param ($usableRate) - $totalUsable = ($usableRate | Measure-Object -Property UsableCount -Sum).Sum - $totalRulesCount = ($usableRate | Measure-Object -Property TotalCount -Sum).Sum - return "{0:N2}%" -f ($totalUsable / $totalRulesCount * 100) -} - -function ShowRulesCountsByLevel { - param ($usableRate, $msg, $colorMsg) - Write-Host -NoNewline $msg - $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Partially") { "DarkYellow" } else { "Green" } - Write-Host "$colorMsg" -ForegroundColor $color - $levelColorMap = [ordered]@{ - "critical" = "Red" - "high" = "DarkYellow" - "medium" = "Yellow" - "low" = "Green" - "informational" = "White" # Assuming a default color for informational - } - $i = 0 - Write-Host -NoNewline " - " - $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { - $color = $levelColorMap[$_.Level] - Write-Host -NoNewline "$($_.Level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color - if ($i -lt $usableRate.Count - 1) - { - Write-Host -NoNewline ", " - } - $i++ - } - Write-Output "" - Write-Output "" -} - -function Test-IsAdministrator { - $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() - $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator - return (New-Object Security.Principal.WindowsPrincipal($currentUser)).IsInRole($adminRole) -} - -if (-not (Test-IsAdministrator)) { - Write-Output "This script must be run as an Administrator." - exit -} +Import-Module -Name ./WELAFunctions.psm1 # Set the console encoding to UTF-8 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 diff --git a/WELAFunctions.psm1 b/WELAFunctions.psm1 new file mode 100644 index 00000000..735e6475 --- /dev/null +++ b/WELAFunctions.psm1 @@ -0,0 +1,226 @@ +<# +.SYNOPSIS + Checks if a registry value matches the expected value. +.DESCRIPTION + This function retrieves a registry value and compares it to the expected value. +.PARAMETER registryPath + The path to the registry key. +.PARAMETER valueName + The name of the registry value. +.PARAMETER expectedValue + The expected value to compare against. +.RETURNS + [bool] $true if the registry value matches the expected value, otherwise $false. +#> +function CheckRegistryValue { + param ( + [string]$registryPath, + [string]$valueName, + [int]$expectedValue + ) + + try { + $value = Get-ItemProperty -Path $registryPath -Name $valueName -ErrorAction Stop + if ($value.$valueName -eq $expectedValue) { + return $true + } else { + return $false + } + } catch { + return $false + } +} + + +<# +.SYNOPSIS + Sets the applicable rules based on the provided audit policy text and JSON rule path. + +.DESCRIPTION + This function reads the audit policy text file and extracts GUIDs. It then checks the registry values for PowerShell logging settings and updates the applicability of rules in the JSON file based on these settings and the extracted GUIDs. + +.PARAMETER autidpolTxt + The path to the audit policy text file. + +.PARAMETER jsonRulePath + The path to the JSON rule file. + +.RETURNS + The updated JSON content with the applicability of rules set. + +.EXAMPLE + Set-Applicable -autidpolTxt "C:\path\to\auditpol.txt" -jsonRulePath "C:\path\to\rules.json" +#> +function Set-Applicable { + param ( + [string]$autidpolTxt, + [string]$jsonRulePath + ) + + $extractedGuids = [System.Collections.Generic.HashSet[string]]::new() + Get-Content -Path $autidpolTxt | Select-String -NotMatch "No Auditing" | ForEach-Object { + if ($_ -match '{(.*?)}') { + [void]$extractedGuids.Add($matches[1]) + } + } + + $pwshModuleLogging = CheckRegistryValue -registryPath "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -valueName "EnableModuleLogging" -expectedValue 1 + $pwshScriptLogging = CheckRegistryValue -registryPath "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -valueName "EnableScriptBlockLogging" -expectedValue 1 + + $jsonContent = Get-Content -Path $jsonRulePath -Raw | ConvertFrom-Json + foreach ($rule in $jsonContent) { + $rule | Add-Member -MemberType NoteProperty -Name "applicable" -Value $false + if ($rule.channel -eq "pwsh") { + if ($rule.event_ids -contains "400") { + $rule.applicable = $true + } elseif ($rule.event_ids -contains "4103") { + $rule.applicable = $pwshModuleLogging + } elseif ($rule.event_ids -contains "4104") { + $rule.applicable = $pwshScriptLogging + } + continue + } + foreach ($guid in $rule.subcategory_guids) { + if ($extractedGuids.Contains($guid)) { + $rule.applicable = $true + break + } + } + } + return $jsonContent +} + + +<# +.SYNOPSIS + Groups the rules by their level and counts the number of rules in each level. +.PARAMETER rules + The collection of rules to be grouped and counted. +.RETURNS + A hashtable with the count of rules for each level. +#> +function Get-RuleCounts { + param ($rules) + $levels = @("critical", "high", "medium", "low", "informational") + $counts = @{} + + $rules | Group-Object -Property level | ForEach-Object { + $counts[$_.Name] = $_.Count + } + + foreach ($level in $levels) { + if (-not $counts.ContainsKey($level)) { + $counts[$level] = 0 + } + } + + return $counts.GetEnumerator() | ForEach-Object { + [PSCustomObject]@{ + Level = $_.Key + Count = $_.Value + } + } +} + +<# +.SYNOPSIS + Calculates the usable rate of rules based on their counts and total counts. +.PARAMETER counts + The counts of usable rules for each level. +.PARAMETER totalCounts + The total counts of rules for each level. +.RETURNS + A collection of objects representing the usable rate for each level. +#> +function CalculateUsableRate { + param ($counts, $totalCounts) + $result = @() + $totalCounts | ForEach-Object { + $level = $_.Level + $total = $_.Count + $usableCount = ($counts | Where-Object Level -eq $level | Select-Object -ExpandProperty Count -First 1) + if ($null -eq $usableCount) { $usableCount = 0 } + $percentage = if ($total -ne 0) { "{0:N2}" -f ($usableCount / $total * 100) } else { "0.00" } + $result += [PSCustomObject]@{ + Level = $level + UsableCount = $usableCount + TotalCount = $total + Percentage = $percentage + } + } + return $result +} + + +<# +.SYNOPSIS + Calculates the total usable rate of rules. +.PARAMETER usableRate + The collection of objects representing the usable rate for each level. +.RETURNS + A string representing the total usable rate as a percentage. +#> +function CalculateTotalUsableRate { + param ($usableRate) + $totalUsable = ($usableRate | Measure-Object -Property UsableCount -Sum).Sum + $totalRulesCount = ($usableRate | Measure-Object -Property TotalCount -Sum).Sum + return "{0:N2}%" -f ($totalUsable / $totalRulesCount * 100) +} + + +<# +.SYNOPSIS + Displays the counts of rules by their level with color-coded output. +.PARAMETER usableRate + The collection of objects representing the usable rate for each level. +.PARAMETER msg + The message to display before the counts. +.PARAMETER colorMsg + The message to display with color coding. +#> +function ShowRulesCountsByLevel { + param ($usableRate, $msg, $colorMsg) + Write-Host -NoNewline $msg + $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Partially") { "DarkYellow" } else { "Green" } + Write-Host "$colorMsg" -ForegroundColor $color + $levelColorMap = [ordered]@{ + "critical" = "Red" + "high" = "DarkYellow" + "medium" = "Yellow" + "low" = "Green" + "informational" = "White" # Assuming a default color for informational + } + $i = 0 + Write-Host -NoNewline " - " + $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { + $color = $levelColorMap[$_.Level] + Write-Host -NoNewline "$($_.Level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color + if ($i -lt $usableRate.Count - 1) + { + Write-Host -NoNewline ", " + } + $i++ + } + Write-Output "" + Write-Output "" +} + +<# +.SYNOPSIS + Checks if the current user is an administrator. +.DESCRIPTION + This function determines if the current user has administrative privileges. +.RETURNS + [bool] $true if the current user is an administrator, otherwise $false. +#> +function Test-IsAdministrator { + $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() + $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator + return (New-Object Security.Principal.WindowsPrincipal($currentUser)).IsInRole($adminRole) +} + +if (-not (Test-IsAdministrator)) { + Write-Output "This script must be run as an Administrator." + exit +} + From e23d6430a1168b10590b7ee7bc03848134d371fa Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:22:15 +0900 Subject: [PATCH 20/27] refactor --- WELA.ps1 | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index 42c59ae9..eaea63ac 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -1,12 +1,4 @@ Import-Module -Name ./WELAFunctions.psm1 - -# Set the console encoding to UTF-8 -[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 - -# Step 1: Run the auditpol command using cmd.exe and redirect its output to a file -$autidpolTxt = "auditpol_output.txt" -Start-Process -FilePath "cmd.exe" -ArgumentList "/c chcp 437 & auditpol /get /category:* /r" -NoNewWindow -Wait -RedirectStandardOutput $autidpolTxt - $logo = @" ┏┓┏┓┏┳━━━┳┓ ┏━━━┓ ┃┃┃┃┃┃┏━━┫┃ ┃┏━┓┃ @@ -17,42 +9,47 @@ $logo = @" by Yamato Security "@ + +# Set the console encoding to UTF-8 +[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 + +# Step 1: Run the auditpol command using cmd.exe and redirect its output to a file +$autidpolTxt = "auditpol_output.txt" +Start-Process -FilePath "cmd.exe" -ArgumentList "/c chcp 437 & auditpol /get /category:* /r" -NoNewWindow -Wait -RedirectStandardOutput $autidpolTxt + Write-Host $logo -ForegroundColor Green # Step 3: Set the applicable flag for each rule $rules = Set-Applicable -autidpolTxt $autidpolTxt -jsonRulePath "./config/security_rules.json" - -$allSecRules = $rules | Where-Object { $_.channel -eq "sec" } -$allPwsClaRules = $rules | Where-Object { $_.channel -eq "pwsh" -and $_.event_ids -contains "400" } +$allSecRules = $rules | Where-Object { $_.channel -eq "sec" } +$allPwsClaRules = $rules | Where-Object { $_.channel -eq "pwsh" -and ($_.event_ids -contains "400" -or $_.event_ids -contains "600" -or $_.event_ids.Count -eq 0) } $allPwsModRules = $rules | Where-Object { $_.channel -eq "pwsh" -and $_.event_ids -contains "4103" } $allPwsScrRules = $rules | Where-Object { $_.channel -eq "pwsh" -and $_.event_ids -contains "4104" } -$usableSecRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "sec" } -$usablePwsRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" } +$usableSecRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "sec" } +$usablePwsRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" } $usablePwsClaRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" -and ($_.event_ids -contains "400" -or $_.event_ids -contains "600" -or $_.event_ids.Count -eq 0) } $usablePwsModRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" -and $_.event_ids -contains "4103" } $usablePwsScrRules = $rules | Where-Object { $_.applicable -eq $true -and $_.channel -eq "pwsh" -and $_.event_ids -contains "4104" } -$unusableRules = $rules | Where-Object { $_.applicable -eq $false } - # Step 4: Count the number of usable and unusable rules for each level -$totalCounts = Get-RuleCounts -rules $rules -$totalSecCounts = Get-RuleCounts -rules $allSecRules -$totalPwsCounts = Get-RuleCounts -rules $allPwsClaRules +$totalCounts = Get-RuleCounts -rules $rules +$totalSecCounts = Get-RuleCounts -rules $allSecRules +$totalPwsCounts = Get-RuleCounts -rules $allPwsClaRules $totalPwsClaCounts = Get-RuleCounts -rules $allPwsClaRules $totalPwsModCounts = Get-RuleCounts -rules $allPwsModRules $totalPwsScrCounts = Get-RuleCounts -rules $allPwsScrRules -$usableSecCounts = Get-RuleCounts -rules $usableSecRules -$usablePwsCounts = Get-RuleCounts -rules $usablePwsRules +$usableSecCounts = Get-RuleCounts -rules $usableSecRules +$usablePwsCounts = Get-RuleCounts -rules $usablePwsRules $usablePwsClaCounts = Get-RuleCounts -rules $usablePwsClaRules $usablePwsModCounts = Get-RuleCounts -rules $usablePwsModRules $usablePwsScrCounts = Get-RuleCounts -rules $usablePwsScrRules # Step 5: Calculate the usable rate for each level -$usableSecRate = CalculateUsableRate -counts $usableSecCounts -totalCounts $totalSecCounts -$usablePwsRate = CalculateUsableRate -counts $usablePwsCounts -totalCounts $totalPwsCounts +$usableSecRate = CalculateUsableRate -counts $usableSecCounts -totalCounts $totalSecCounts +$usablePwsRate = CalculateUsableRate -counts $usablePwsCounts -totalCounts $totalPwsCounts $usablePwsClaRate = CalculateUsableRate -counts $usablePwsClaCounts -totalCounts $totalPwsClaCounts $usablePwsModRate = CalculateUsableRate -counts $usablePwsModCounts -totalCounts $totalPwsModCounts $usablePwsScrRate = CalculateUsableRate -counts $usablePwsScrCounts -totalCounts $totalPwsScrCounts @@ -64,7 +61,7 @@ $pwsModStatus = if ($pwsModEnabled) { "Enabled" } else { "Disabled" } $pwsSrcStatus = if ($pwsScrEnabled) { "Enabled" } else { "Disabled" } # Step 7: Calculate the total usable rate -$totalUsableSecRate = CalculateTotalUsableRate -usableRate $usableSecRate +$totalUsableSecRate = CalculateTotalUsableRate -usableRate $usableSecRate $totalUsablePwsClaRate = CalculateTotalUsableRate -usableRate $usablePwsClaRate $totalUsablePwsModRate = CalculateTotalUsableRate -usableRate $usablePwsModRate $totalUsablePwsScrRate = CalculateTotalUsableRate -usableRate $usablePwsScrRate @@ -83,5 +80,6 @@ $utilizationPercentage = "{0:N2}" -f (($totalUsable / $totalRulesCount) * 100) Write-Output "You can utilize $utilizationPercentage% of your detection rules." # Step 8: Save the lists of usable and unusable rules to CSV files +$unusableRules = $rules | Where-Object { $_.applicable -eq $false } $usableSecRules | Select-Object title, level, id | Export-Csv -Path "UsableRules.csv" -NoTypeInformation $unusableRules | Select-Object title, level, id | Export-Csv -Path "UnusableRules.csv" -NoTypeInformation From 4ed4df8c25b5e26ab3cb96ff94fb06fe78b27fb9 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:27:48 +0900 Subject: [PATCH 21/27] informational -> info --- WELAFunctions.psm1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WELAFunctions.psm1 b/WELAFunctions.psm1 index 735e6475..f97000df 100644 --- a/WELAFunctions.psm1 +++ b/WELAFunctions.psm1 @@ -194,7 +194,8 @@ function ShowRulesCountsByLevel { Write-Host -NoNewline " - " $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] - Write-Host -NoNewline "$($_.Level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color + $level = if ($_.Level -eq "informational") { "info" } else { $_.Level } + Write-Host -NoNewline "$($level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color if ($i -lt $usableRate.Count - 1) { Write-Host -NoNewline ", " From 1a1a44ed17a87642ff0de2a344460a681e270c42 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:36:23 +0900 Subject: [PATCH 22/27] informational -> info --- WELAFunctions.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELAFunctions.psm1 b/WELAFunctions.psm1 index f97000df..83ff96ae 100644 --- a/WELAFunctions.psm1 +++ b/WELAFunctions.psm1 @@ -194,7 +194,7 @@ function ShowRulesCountsByLevel { Write-Host -NoNewline " - " $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] - $level = if ($_.Level -eq "informational") { "info" } else { $_.Level } + $level = if ($_.Level -match "informational") { "info" } else { $_.Level } Write-Host -NoNewline "$($level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color if ($i -lt $usableRate.Count - 1) { From 188555f6d2e7fefefea0c4bd068d5289ee45bc38 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:37:37 +0900 Subject: [PATCH 23/27] informational -> info --- WELAFunctions.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELAFunctions.psm1 b/WELAFunctions.psm1 index 83ff96ae..f97000df 100644 --- a/WELAFunctions.psm1 +++ b/WELAFunctions.psm1 @@ -194,7 +194,7 @@ function ShowRulesCountsByLevel { Write-Host -NoNewline " - " $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] - $level = if ($_.Level -match "informational") { "info" } else { $_.Level } + $level = if ($_.Level -eq "informational") { "info" } else { $_.Level } Write-Host -NoNewline "$($level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color if ($i -lt $usableRate.Count - 1) { From 52ea6956bc04b3cc5dad8e0dd480ee7c1a1afe15 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:41:47 +0900 Subject: [PATCH 24/27] informational -> info --- WELAFunctions.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELAFunctions.psm1 b/WELAFunctions.psm1 index f97000df..83ff96ae 100644 --- a/WELAFunctions.psm1 +++ b/WELAFunctions.psm1 @@ -194,7 +194,7 @@ function ShowRulesCountsByLevel { Write-Host -NoNewline " - " $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] - $level = if ($_.Level -eq "informational") { "info" } else { $_.Level } + $level = if ($_.Level -match "informational") { "info" } else { $_.Level } Write-Host -NoNewline "$($level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color if ($i -lt $usableRate.Count - 1) { From 111124c0b90c97ab40261d55dd26dbcb91397ca3 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 22 Mar 2025 17:30:01 +0900 Subject: [PATCH 25/27] update --- WELA.ps1 | 3 ++- WELAFunctions.psm1 | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WELA.ps1 b/WELA.ps1 index eaea63ac..7d884f82 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -23,6 +23,7 @@ Write-Host $logo -ForegroundColor Green $rules = Set-Applicable -autidpolTxt $autidpolTxt -jsonRulePath "./config/security_rules.json" $allSecRules = $rules | Where-Object { $_.channel -eq "sec" } +$allPwsRules = $rules | Where-Object { $_.channel -eq "pwsh" } $allPwsClaRules = $rules | Where-Object { $_.channel -eq "pwsh" -and ($_.event_ids -contains "400" -or $_.event_ids -contains "600" -or $_.event_ids.Count -eq 0) } $allPwsModRules = $rules | Where-Object { $_.channel -eq "pwsh" -and $_.event_ids -contains "4103" } $allPwsScrRules = $rules | Where-Object { $_.channel -eq "pwsh" -and $_.event_ids -contains "4104" } @@ -36,7 +37,7 @@ $usablePwsScrRules = $rules | Where-Object { $_.applicable -eq $true -and $_.cha # Step 4: Count the number of usable and unusable rules for each level $totalCounts = Get-RuleCounts -rules $rules $totalSecCounts = Get-RuleCounts -rules $allSecRules -$totalPwsCounts = Get-RuleCounts -rules $allPwsClaRules +$totalPwsCounts = Get-RuleCounts -rules $allPwsRules $totalPwsClaCounts = Get-RuleCounts -rules $allPwsClaRules $totalPwsModCounts = Get-RuleCounts -rules $allPwsModRules $totalPwsScrCounts = Get-RuleCounts -rules $allPwsScrRules diff --git a/WELAFunctions.psm1 b/WELAFunctions.psm1 index 83ff96ae..98bbda73 100644 --- a/WELAFunctions.psm1 +++ b/WELAFunctions.psm1 @@ -71,7 +71,7 @@ function Set-Applicable { foreach ($rule in $jsonContent) { $rule | Add-Member -MemberType NoteProperty -Name "applicable" -Value $false if ($rule.channel -eq "pwsh") { - if ($rule.event_ids -contains "400") { + if ($rule.event_ids -contains "400" -or $rule.event_ids -contains "600" -or $rule.event_ids.Count -eq 0) { $rule.applicable = $true } elseif ($rule.event_ids -contains "4103") { $rule.applicable = $pwshModuleLogging From 21a2da65c55dc38e9a1311e45466c1310e1cefc5 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 22 Mar 2025 17:32:35 +0900 Subject: [PATCH 26/27] update --- WELAFunctions.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELAFunctions.psm1 b/WELAFunctions.psm1 index 98bbda73..d5e1ceb5 100644 --- a/WELAFunctions.psm1 +++ b/WELAFunctions.psm1 @@ -195,7 +195,7 @@ function ShowRulesCountsByLevel { $usableRate | Sort-Object { $levelColorMap.Keys.IndexOf($_.Level) } | ForEach-Object { $color = $levelColorMap[$_.Level] $level = if ($_.Level -match "informational") { "info" } else { $_.Level } - Write-Host -NoNewline "$($level): $($_.UsableCount) / $($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color + Write-Host -NoNewline "$($level): $($_.UsableCount)/$($_.TotalCount) ($($_.Percentage)%)" -ForegroundColor $color if ($i -lt $usableRate.Count - 1) { Write-Host -NoNewline ", " From 112d55c4d562f612b44a4d5a8f7621846bdf7f8f Mon Sep 17 00:00:00 2001 From: Yamato Security <71482215+YamatoSecurity@users.noreply.github.com> Date: Mon, 24 Mar 2025 11:30:32 +0900 Subject: [PATCH 27/27] update color --- WELAFunctions.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WELAFunctions.psm1 b/WELAFunctions.psm1 index d5e1ceb5..005aca1d 100644 --- a/WELAFunctions.psm1 +++ b/WELAFunctions.psm1 @@ -181,7 +181,7 @@ function CalculateTotalUsableRate { function ShowRulesCountsByLevel { param ($usableRate, $msg, $colorMsg) Write-Host -NoNewline $msg - $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Partially") { "DarkYellow" } else { "Green" } + $color = if ($colorMsg -match "Disabled") { "Red" } elseif ($colorMsg -match "Partially") { "Yellow" } else { "Green" } Write-Host "$colorMsg" -ForegroundColor $color $levelColorMap = [ordered]@{ "critical" = "Red"