Skip to content

Commit 93a7961

Browse files
authored
Merge pull request #39 from jakehildreth:feat/html-dashboard
feat: add New-LS2Dashboard function for generating interactive HTML dashboard
2 parents a5e0759 + 0660981 commit 93a7961

File tree

1 file changed

+276
-0
lines changed

1 file changed

+276
-0
lines changed

Public/New-LS2Dashboard.ps1

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
function New-LS2Dashboard {
2+
<#
3+
.SYNOPSIS
4+
Generates an interactive HTML dashboard for Locksmith2 scan results.
5+
6+
.DESCRIPTION
7+
Creates a comprehensive HTML dashboard with left navigation menu showing:
8+
- All issues with expanded principals
9+
- Issues filtered by type (Template, CA, Object)
10+
- Risky principals analysis
11+
12+
Supports light/dark mode toggle and interactive filtering/sorting.
13+
Requires PSWriteHTML module (Install-Module PSWriteHTML).
14+
15+
.PARAMETER FilePath
16+
Path where the HTML dashboard will be saved.
17+
Default: $env:TEMP\Locksmith2-Dashboard.html
18+
19+
.PARAMETER Show
20+
Opens the dashboard in default browser after generation.
21+
22+
.PARAMETER ExpandGroups
23+
Expands group principals into individual member issues.
24+
25+
.PARAMETER Online
26+
Uses online CDN resources instead of embedding CSS/JS.
27+
Results in smaller file size but requires internet connection to view.
28+
29+
.INPUTS
30+
None. This function does not accept pipeline input.
31+
32+
.OUTPUTS
33+
None. Generates an HTML file at the specified path.
34+
35+
.EXAMPLE
36+
Invoke-Locksmith2
37+
New-LS2Dashboard -FilePath C:\Reports\locksmith-dashboard.html -Show
38+
39+
Runs a scan and generates an interactive dashboard.
40+
41+
.EXAMPLE
42+
New-LS2Dashboard -ExpandGroups -Show
43+
44+
Generates dashboard with group memberships expanded to individual principals.
45+
46+
.EXAMPLE
47+
New-LS2Dashboard -FilePath C:\Reports\report.html -Online
48+
49+
Generates a smaller dashboard file using online CDN resources.
50+
51+
.NOTES
52+
Author: Jake Hildreth (@jakehildreth)
53+
Requires: PSWriteHTML module (https://github.com/EvotecIT/PSWriteHTML)
54+
Requires: PowerShell 5.1 or later
55+
56+
The dashboard reads from the current IssueStore. Run Invoke-Locksmith2 or
57+
Find-LS2Vulnerable* functions first to populate the store with scan data.
58+
59+
.LINK
60+
Invoke-Locksmith2
61+
62+
.LINK
63+
Find-LS2RiskyPrincipal
64+
65+
.LINK
66+
Get-FlattenedIssues
67+
#>
68+
[CmdletBinding()]
69+
param(
70+
[Parameter()]
71+
[string]$FilePath = "$env:TEMP\Locksmith2-Dashboard.html",
72+
73+
[Parameter()]
74+
[switch]$Show,
75+
76+
[Parameter()]
77+
[switch]$ExpandGroups,
78+
79+
[Parameter()]
80+
[switch]$Online
81+
)
82+
83+
#requires -Version 5.1
84+
85+
# Check for PSWriteHTML module
86+
if (-not (Get-Module -ListAvailable -Name PSWriteHTML)) {
87+
Write-Error "PSWriteHTML module is required. Install with: Install-Module PSWriteHTML"
88+
return
89+
}
90+
91+
Import-Module PSWriteHTML -ErrorAction Stop
92+
93+
# Check if IssueStore is populated
94+
if (-not $script:IssueStore -or $script:IssueStore.Count -eq 0) {
95+
Write-Warning "IssueStore is empty. Run Invoke-Locksmith2 or Find-LS2Vulnerable* functions first."
96+
Write-Warning "Generating empty dashboard..."
97+
}
98+
99+
# Get all issues from IssueStore
100+
$allIssues = Get-FlattenedIssues
101+
102+
# Expand groups if requested
103+
if ($ExpandGroups) {
104+
Write-Verbose "Expanding group memberships for dashboard..."
105+
$allIssues = $allIssues | ForEach-Object { Expand-IssueByGroup $_ }
106+
}
107+
108+
# Filter issues by category
109+
$templateTechniques = @('ESC1', 'ESC2', 'ESC3c1', 'ESC3c2', 'ESC4a', 'ESC4o', 'ESC9')
110+
$caTechniques = @('ESC6', 'ESC7a', 'ESC7m', 'ESC11', 'ESC16')
111+
$objectTechniques = @('ESC5a', 'ESC5o')
112+
113+
$templateIssues = $allIssues | Where-Object { $_.Technique -in $templateTechniques }
114+
$caIssues = $allIssues | Where-Object { $_.Technique -in $caTechniques }
115+
$objectIssues = $allIssues | Where-Object { $_.Technique -in $objectTechniques }
116+
117+
# Get risky principals
118+
Write-Verbose "Calculating principal risk scores..."
119+
$riskyPrincipals = Find-LS2RiskyPrincipal
120+
121+
# Prepare data for tables - select key properties for display
122+
$allIssuesTable = $allIssues | Select-Object `
123+
Technique,
124+
Forest,
125+
Name,
126+
IdentityReference,
127+
ActiveDirectoryRights,
128+
@{N='Enabled';E={if($null -ne $_.Enabled){$_.Enabled}else{'-'}}},
129+
@{N='CAFullName';E={if($_.CAFullName){$_.CAFullName}else{'-'}}},
130+
@{N='Owner';E={if($_.Owner){$_.Owner}else{'-'}}},
131+
@{N='Members';E={if($_.MemberCount){$_.MemberCount}else{'-'}}}
132+
133+
$templateIssuesTable = $templateIssues | Select-Object `
134+
Technique, Name, IdentityReference, ActiveDirectoryRights, Enabled, MemberCount
135+
136+
$caIssuesTable = $caIssues | Select-Object `
137+
Technique, Name, CAFullName, IdentityReference, ActiveDirectoryRights, MemberCount
138+
139+
$objectIssuesTable = $objectIssues | Select-Object `
140+
Technique, Name, Owner, IdentityReference, ActiveDirectoryRights, MemberCount
141+
142+
$principalsTable = $riskyPrincipals | Select-Object `
143+
Principal,
144+
IssueCount,
145+
@{N='Techniques';E={$_.Techniques -join ', '}},
146+
@{N='VulnerableObjects';E={$_.VulnerableObjects.Count}}
147+
148+
$forestName = if ($script:Forest) { $script:Forest } else { 'Unknown Forest' }
149+
150+
# Generate HTML Dashboard
151+
New-HTML -TitleText "Locksmith2 Security Dashboard - $forestName" -Online:$Online -FilePath $FilePath -Show:$Show {
152+
153+
# Use tabs for single-page navigation with content switching
154+
New-HTMLTabStyle -SlimTabs -Transition -SelectorColor Magenta
155+
156+
New-HTMLTab -Name 'All Issues' -IconSolid exclamation-triangle -IconColor Red {
157+
New-HTMLSection -Invisible {
158+
New-HTMLPanel -Width 10% {
159+
New-HTMLText -Text "All Issues - Expanded Principals ($($allIssues.Count) total)" -FontSize 20 -FontWeight bold
160+
New-HTMLText -Text @"
161+
This view shows all discovered AD CS vulnerabilities with group memberships expanded to individual principals.
162+
Issues are marked with the ESC technique and show which principals can exploit each configuration.
163+
"@ -Color '#888' -FontSize 14
164+
}
165+
New-HTMLPanel {
166+
New-HTMLTable -DataTable $allIssuesTable `
167+
-Filtering `
168+
-PagingLength 25 `
169+
-Buttons @('copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5', 'searchBuilder', 'searchPanes') `
170+
-Title 'All AD CS Security Issues' {
171+
New-TableButtonSearchBuilder -ButtonName 'Search Builder'
172+
New-HTMLTableCondition -Name 'Technique' -ComparisonType string -Operator like -Value 'ESC1*' -BackgroundColor '#ffebee' -Color Black
173+
New-HTMLTableCondition -Name 'Technique' -ComparisonType string -Operator like -Value 'ESC7*' -BackgroundColor '#fff3e0' -Color Black
174+
New-HTMLTableCondition -Name 'Members' -ComparisonType string -Operator ne -Value '-' -BackgroundColor '#e8f5e9' -Color Black
175+
}
176+
}
177+
}
178+
}
179+
180+
New-HTMLTab -Name 'Templates' -IconSolid file-contract -IconColor Orange {
181+
New-HTMLSection -Invisible {
182+
New-HTMLPanel -Width 10% {
183+
New-HTMLText -Text "Certificate Template Issues ($($templateIssues.Count) issues)" -FontSize 20 -FontWeight bold
184+
New-HTMLText -Text @"
185+
Certificate templates are the most common source of AD CS vulnerabilities. These issues allow principals to request
186+
certificates with dangerous permissions, subject alternative names, or enrollment agent capabilities.
187+
"@ -Color '#888' -FontSize 14
188+
}
189+
New-HTMLPanel {
190+
New-HTMLTable -DataTable $templateIssuesTable `
191+
-Filtering `
192+
-PagingLength 25 `
193+
-Buttons @('copyHtml5', 'excelHtml5', 'csvHtml5') `
194+
-Title 'Template Vulnerabilities' {
195+
New-HTMLTableCondition -Name 'Technique' -Value 'ESC1' -BackgroundColor '#ffcdd2' -Color Black
196+
New-HTMLTableCondition -Name 'Enabled' -Value $true -BackgroundColor '#fff9c4' -Color Black
197+
}
198+
}
199+
}
200+
}
201+
202+
New-HTMLTab -Name 'CAs' -IconSolid certificate -IconColor Yellow {
203+
New-HTMLSection -Invisible {
204+
New-HTMLPanel -Width 10% {
205+
New-HTMLText -Text "Certification Authority Issues ($($caIssues.Count) issues)" -FontSize 20 -FontWeight bold
206+
New-HTMLText -Text @"
207+
CA-level issues involve dangerous role assignments (ESC7) or insecure CA configurations (ESC6, ESC11, ESC16).
208+
These vulnerabilities grant principals excessive control over certificate issuance.
209+
"@ -Color '#888' -FontSize 14
210+
}
211+
New-HTMLPanel {
212+
New-HTMLTable -DataTable $caIssuesTable `
213+
-Filtering `
214+
-PagingLength 25 `
215+
-Buttons @('copyHtml5', 'excelHtml5', 'csvHtml5') `
216+
-Title 'CA Configuration Issues' {
217+
New-HTMLTableCondition -Name 'Technique' -Value 'ESC7a' -BackgroundColor '#ffccbc' -Color Black
218+
New-HTMLTableCondition -Name 'Technique' -Value 'ESC7m' -BackgroundColor '#ffe0b2' -Color Black
219+
}
220+
}
221+
}
222+
}
223+
224+
New-HTMLTab -Name 'Objects' -IconSolid folder -IconColor Blue {
225+
New-HTMLSection -Invisible {
226+
New-HTMLPanel -Width 10% {
227+
New-HTMLText -Text "PKI Object Issues ($($objectIssues.Count) issues)" -FontSize 20 -FontWeight bold
228+
New-HTMLText -Text @"
229+
ESC5 vulnerabilities involve dangerous ownership or write permissions on PKI infrastructure objects.
230+
These allow principals to modify templates, CAs, or other critical AD CS components.
231+
"@ -Color '#888' -FontSize 14
232+
}
233+
New-HTMLPanel {
234+
New-HTMLTable -DataTable $objectIssuesTable `
235+
-Filtering `
236+
-PagingLength 25 `
237+
-Buttons @('copyHtml5', 'excelHtml5', 'csvHtml5') `
238+
-Title 'Infrastructure Object Issues' {
239+
New-HTMLTableCondition -Name 'Technique' -Value 'ESC5a' -BackgroundColor '#c5e1a5' -Color Black
240+
New-HTMLTableCondition -Name 'Technique' -Value 'ESC5o' -BackgroundColor '#fff59d' -Color Black
241+
}
242+
}
243+
}
244+
}
245+
246+
New-HTMLTab -Name 'Risky Principals' -IconSolid user-shield -IconColor Purple {
247+
New-HTMLSection -Invisible {
248+
New-HTMLPanel -Width 10% {
249+
New-HTMLText -Text "Principal Risk Analysis ($($principalsTable.Count) principals)" -FontSize 20 -FontWeight bold
250+
New-HTMLText -Text @"
251+
This analysis shows which principals have access to the most AD CS vulnerabilities. Principals with high issue counts
252+
represent concentrated risk and should be prioritized for remediation or monitoring.
253+
"@ -Color '#888' -FontSize 14
254+
}
255+
New-HTMLPanel {
256+
New-HTMLTable -DataTable $principalsTable `
257+
-Filtering `
258+
-PagingLength 25 `
259+
-Buttons @('copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5') `
260+
-Title 'Principals by Risk Score' `
261+
-DefaultSortColumn 'IssueCount' `
262+
-DefaultSortOrder Descending {
263+
New-HTMLTableCondition -Name 'IssueCount' -ComparisonType number -Operator gt -Value 10 -BackgroundColor '#ef5350' -Color White
264+
New-HTMLTableCondition -Name 'IssueCount' -ComparisonType number -Operator ge -Value 5 -BackgroundColor '#ff9800' -Color White
265+
New-HTMLTableCondition -Name 'IssueCount' -ComparisonType number -Operator ge -Value 1 -BackgroundColor '#fdd835' -Color Black
266+
}
267+
}
268+
}
269+
}
270+
}
271+
272+
Write-Verbose "Dashboard generated: $FilePath"
273+
if (-not $Show) {
274+
Write-Host "Dashboard saved to: $FilePath"
275+
}
276+
}

0 commit comments

Comments
 (0)