diff --git a/PowerHuntShares.psm1 b/PowerHuntShares.psm1 index eeeb985..ad48505 100644 --- a/PowerHuntShares.psm1 +++ b/PowerHuntShares.psm1 @@ -4,7 +4,7 @@ #-------------------------------------- # Author: Scott Sutherland, 2024 NetSPI # License: 3-clause BSD -# Version: v1.115 +# Version: v1.116 # References: This script includes custom code and code taken and modified from the open source projects PowerView, Invoke-Ping, and Invoke-Parrell. function Invoke-HuntSMBShares { @@ -3571,6 +3571,63 @@ function Invoke-HuntSMBShares $GetRowUncPathsRaw = $ExcessiveSharePrivs | where ShareName -EQ "$ShareName" | Select SharePath -Unique $GetRowUncPathsCount = $GetRowUncPathsRaw | measure | select count -ExpandProperty count $GetRowUncPaths = $GetRowUncPathsRaw | ForEach-Object { $ASDF = $_.SharePath; "$ASDF
" } | Out-String + + # ---------------------------------------------------------------------- + # Create Share Summary Information + # ---------------------------------------------------------------------- + + # Get share path count + $SharePathChartCount = $ExcessiveSharePrivsFinal | where SharePath -ne "" | + foreach{ + if( ($_.sharename -ne 'SYSVOL') -and ($_.sharename -ne 'NETLOGON')) + { + $_ + } + } | select SharePath -Unique | measure | select count -ExpandProperty count + + # Get share path severity + # Reivew ACLs for each share path, highest severity wins + $RiskLevelSharePathCountCritical = 0 + $RiskLevelSharePathCountHigh = 0 + $RiskLevelSharePathCountMedium = 0 + $RiskLevelSharePathCountLow = 0 + $ExcessiveSharePrivsFinal | where SharePath -ne "" | + foreach{ + + # filter out sysvol and netlogon + if( ($_.SharePath -ne 'SYSVOL') -and ($_.SharePath -ne 'NETLOGON')) + { + $_ + } + } | select SharePath -Unique | + foreach { + + # Set target share name + $TargetRiskSharePath = $_.SharePath + + # Grab the risk level for the highest risk acl for the share name + $SharePathTopACLRiskScore = $ExcessiveSharePrivsFinal | where SharePath -eq $TargetRiskSharePath | select RiskScore | sort RiskScore -Descending | select -First 1 | select RiskScore -ExpandProperty RiskScore + + # Check risk level - Highest wins + If($SharePathTopACLRiskScore -le 4 ) { $RiskLevelSharePathResult = "Low"} + If($SharePathTopACLRiskScore -gt 4 -and $SharePathTopACLRiskScore -lt 11 ) { $RiskLevelSharePathResult = "Medium"} + If($SharePathTopACLRiskScore -ge 11 -and $SharePathTopACLRiskScore -lt 20 ) { $RiskLevelSharePathResult = "High"} + If($SharePathTopACLRiskScore -ge 20 ) { $RiskLevelSharePathResult = "Critical"} + + # Increment counts + if($RiskLevelSharePathResult -eq "Low" ){$RiskLevelSharePathCountLow = $RiskLevelSharePathCountLow + 1} + if($RiskLevelSharePathResult -eq "Medium" ){$RiskLevelSharePathCountMedium = $RiskLevelSharePathCountMedium + 1} + if($RiskLevelSharePathResult -eq "High" ){$RiskLevelSharePathCountHigh = $RiskLevelSharePathCountHigh + 1} + if($RiskLevelSharePathResult -eq "Critical"){$RiskLevelSharePathCountCritical = $RiskLevelSharePathCountCritical + 1} + } + + # Counts + <# + $RiskLevelSharePathCountLow + $RiskLevelSharePathCountMedium + $RiskLevelSharePathCountHigh + $RiskLevelSharePathCountCritical + #> # ---------------------------------------------------------------------- # Build Share Name Summary Page Rows @@ -9487,7 +9544,7 @@ const ChartDashboardIFOptions = { }], chart: { type: 'bar', - height: 250 + height: 300 }, plotOptions: { bar: { @@ -9735,44 +9792,73 @@ ChartDashboardIF.render(); // Dashboard Page: Risk Level chart // -------------------------- +// Set data series +var DataSeriesComputers = [$RiskLevelComputersCountLow, $RiskLevelComputersCountMedium, $RiskLevelComputersCountHigh, $RiskLevelComputersCountCritical]; +var DataSeriesShares = [$RiskLevelSharePathCountLow, $RiskLevelSharePathCountMedium, $RiskLevelSharePathCountHigh, $RiskLevelSharePathCountCritical]; +var DataSeriesACEs = [$RiskLevelCountLow, $RiskLevelCountMedium, $RiskLevelCountHigh,$RiskLevelCountCritical]; + +// Reverse each array +DataSeriesComputers.reverse(); +DataSeriesShares.reverse(); +DataSeriesACEs.reverse(); + +// Find max values +var maxComputer = Math.max(...DataSeriesComputers); +var maxShares = Math.max(...DataSeriesShares); +var maxACEs = Math.max(...DataSeriesACEs); +var maxValueOverall = Math.max(maxComputer, maxShares, maxACEs); + // Initialize ApexCharts const ChartDashboardRiskOptions = { series: [{ - data: [$RiskLevelCountCritical, $RiskLevelCountHigh, $RiskLevelCountMedium, $RiskLevelCountLow] + name: 'Computers', + data: DataSeriesComputers + //color: 'blue' // Set color for Computers series + },{ + name: 'Shares', + data: DataSeriesShares + //color: 'green' // Set color for Shares series + },{ + name: 'ACEs', + data: DataSeriesACEs + //color: 'red' // Set color for ACEs series }], chart: { type: 'bar', - height: 250 + height: 300 }, plotOptions: { bar: { borderRadius: 0, borderRadiusApplication: 'end', horizontal: true, - colors: { - backgroundBarColors: ['#e0e0e0'], - backgroundBarOpacity: 1, - ranges: [{ - from: 0, - to: 1000, - color: '#f08c41' - }] - } + barHeight: '90%', // Reduce bar height for more space + barGap: '0%', // Adds gap between bars in the same group + // barSpacing: 0.0 // Adds space between the groups (risk levels) } }, + colors: ['#DBDCD6', '#E4A628', '#07142A'], // Colors for the bars dataLabels: { - enabled: false + enabled: true, + style: { + fontSize: '12px', + colors: ['#07142A', '#07142A', '#E4A628'] // colors for the lables #FF9965 + }, + offsetX: 0 }, grid: { - show: false + show: true, + opacity: 0.5 }, xaxis: { - categories: ['Critical','High','Medium','Low'] + categories: ['Critical','High','Medium','Low'], + max: maxValueOverall, + min: 0 }, title: { - text: 'ACE Count by Risk Level', - align: 'center', // Aligns the title, can be 'left', 'center', or 'right' - margin: 10, // Adjusts the space between the title and the chart + text: 'Asset Count by Risk Level', + align: 'center', + margin: 10, style: { fontSize: '16px', fontWeight: 'bold',