diff --git a/Scripts/Analyze-HuntSMBShares.ps1 b/Scripts/Analyze-HuntSMBShares.ps1
index f64f4c0..43f3f28 100644
--- a/Scripts/Analyze-HuntSMBShares.ps1
+++ b/Scripts/Analyze-HuntSMBShares.ps1
@@ -5,7 +5,7 @@
#--------------------------------------
# Author: Scott Sutherland, 2024 NetSPI
# License: 3-clause BSD
-# Version: v1.46
+# Version: v1.56
# References: This script includes custom code and code taken and modified from the open source projects PowerView, Invoke-Ping, and Invoke-Parrell.
function Analyze-HuntSMBShares
{
@@ -1043,7 +1043,6 @@ function Analyze-HuntSMBShares
#Write-Output " [*][$Time] - Summary report data generated."
#Write-Output " [*][$Time] - $Top5ShareCountTotal of $AllAccessibleSharesCount ($DupPercent) shares are associated with the top $SampleSum share names."
-
# ----------------------------------------------------------------------
# Create Interesting Files Table
# ----------------------------------------------------------------------
@@ -1310,123 +1309,6 @@ function Analyze-HuntSMBShares
} | select | ForEach-Object { "'$_'" }) -join ", "
$IFCategoryListCount = "[$IFCategoryList]"
-
- <#
-
- # Define list of words associated with sensitive data
- $FileNamePatternsSecrets = $FileNamePatternsAll | where category -like "*Secret*" | select Keyword -ExpandProperty keyword
-
- # Define list of words associated with password files
- $FileNamePatternsData = $FileNamePatternsAll | where category -like "*Sensitive*" | select Keyword -ExpandProperty keyword
-
- # Get a list of file names from each folder group for the target share name
- $InterestingFilesAllFileNames = $ExcessiveSharePrivs | select FileList -Unique | foreach {$_.FileList -split "`r`n"} | Where-Object {$_ -ne ''} | foreach {$_.ToLower()}| select -Unique
-
- # Identify Secrets
- $InterestingFilesAllSecrets = $FileNamePatternsSecrets |
- foreach {
- $TargetSecret = $_
- $InterestingFilesAllFileNames |
- foreach {
- if($_ -like "$TargetSecret"){
-
- # return file name match
- $_
- }
- }
- }
-
- # Create new secret files objects
- $InterestingFilesAllSecretsObjects = $InterestingFilesAllSecrets |
- foreach{
-
- # Set target file
- $TargetSecretFile = $_
-
- # Filter for record with the target file
- $TargetSecretMatches = $ExcessiveSharePrivs | where FileList -like "*$TargetSecretFile*" | select ComputerName,ShareName,SharePath -Unique
- $TargetSecretMatches |
- foreach {
-
- # Select the propertity and make new ones
- $TargetSecretComputer = $_.ComputerName
- $TargetSecretShareName = $_.ShareName
- $TargetSecretSharePath = $_.SharePath
- $TargetSecretUNCPath = "$TargetSecretSharePath\$TargetSecretFile"
- $TargetSecretType = "Secrets"
-
- # Create updated object
- $object = New-Object psobject
- $object | add-member noteproperty ComputerName $TargetSecretComputer
- $object | add-member noteproperty ShareName $TargetSecretShareName
- $object | add-member noteproperty SharePath $TargetSecretSharePath
- $object | add-member noteproperty UncPath $TargetSecretUNCPath
- $object | add-member noteproperty FileName $TargetSecretFile
- $object | add-member noteproperty DataType $TargetSecretType
-
- # Return object
- $object
- }
- } | select ComputerName,ShareName,SharePath,UncPath,FileName,DataType -Unique
-
- # Identify Data
- $InterestingFilesAllData = $FileNamePatternsData |
- foreach {
- $TargetSecret = $_
- $InterestingFilesAllFileNames |
- foreach {
- if($_ -like "$TargetSecret"){
-
- # return file name match
- $_
- }
- }
- }
-
- # Create new data files objects
- $InterestingFilesAllDataObjects = $InterestingFilesAllData |
- foreach{
-
- # Set target file
- $TargetSecretFile = $_
-
- # Filter for record with the target file
- $TargetSecretMatches = $ExcessiveSharePrivs | where FileList -like "*$TargetSecretFile*" | select ComputerName,ShareName,SharePath -Unique
- $TargetSecretMatches |
- foreach {
-
- # Select the propertity and make new ones
- $TargetSecretComputer = $_.ComputerName
- $TargetSecretShareName = $_.ShareName
- $TargetSecretSharePath = $_.SharePath
- $TargetSecretUNCPath = "$TargetSecretSharePath\$TargetSecretFile"
- $TargetSecretType = "Sensitive"
-
- # Create updated object
- $object = New-Object psobject
- $object | add-member noteproperty ComputerName $TargetSecretComputer
- $object | add-member noteproperty ShareName $TargetSecretShareName
- $object | add-member noteproperty SharePath $TargetSecretSharePath
- $object | add-member noteproperty UncPath $TargetSecretUNCPath
- $object | add-member noteproperty FileName $TargetSecretFile
- $object | add-member noteproperty DataType $TargetSecretType
-
- # Return object
- $object
- }
- } | select ComputerName,ShareName,SharePath,UncPath,FileName,DataType -Unique
-
- # Combine objects
- $InterestingFilesAllObjects = $InterestingFilesAllSecretsObjects + $InterestingFilesAllDataObjects
-
-
- # Count objects
- $InterestingFilesAllSecretsFullCount = $InterestingFilesAllSecretsObjects | measure | select count -ExpandProperty count
- $InterestingFilesAllSecretsFullCountU = $InterestingFilesAllSecretsObjects | select FileName -Unique | measure | select count -ExpandProperty count
- $InterestingFilesAllDataFullcount = $InterestingFilesAllDataObjects | measure | select count -ExpandProperty count
- $InterestingFilesAllDataFullcountU = $InterestingFilesAllDataObjects | select FileName -Unique | measure | select count -ExpandProperty count
- #>
-
# Outbout objects to file
$InterestingFilesAllObjects | Export-Csv -NoTypeInformation "$OutputDirectory\$TargetDomain-Shares-Interesting-Files.csv"
@@ -1638,13 +1520,13 @@ function Analyze-HuntSMBShares
if($ShareRowHasWrite -eq 1){ $ShareNameRiskValue = $ShareNameRiskValue + $RiskWeightWrite } # Write Access
if($ShareRowHasRead -eq 1){ $ShareNameRiskValue = $ShareNameRiskValue + $RiskWeightRead } # Read Access
if($ShareRowHasEmpty -eq 1){ $ShareNameRiskValue = $ShareNameRiskValue + $RiskWeightEmpty } # Empty Folders
- if($ShareRowHasStale -eq 1){ $ShareNameRiskValue = $ShareNameRiskValue + $RiskWeightStale } # Stake Folders
+ if($ShareRowHasStale -eq 1){ $ShareNameRiskValue = $ShareNameRiskValue + $RiskWeightStale } # Stake Folders
- # Set Risk Score
- If($ShareNameRiskValue -ge 11 ) { $RiskLevel = "High"}
- If($ShareNameRiskValue -ge 20 ) { $RiskLevel = "Critical"}
- If($ShareNameRiskValue -lt 11 ) { $RiskLevel = "Medium"}
- If($ShareNameRiskValue -lt 4 ) { $RiskLevel = "Low"}
+ # Check risk level - Highest wins
+ If($ShareNameRiskValue -le 4 ) { $RiskLevel = "Low"}
+ If($ShareNameRiskValue -gt 4 -and $ShareNameRiskValue -lt 11 ) { $RiskLevel = "Medium"}
+ If($ShareNameRiskValue -ge 11 -and $ShareNameRiskValue -lt 20 ) { $RiskLevel = "High"}
+ If($ShareNameRiskValue -ge 20 ) { $RiskLevel = "Critical"}
# Append new column to object
$newObject = [PSCustomObject]@{
@@ -1695,7 +1577,108 @@ function Analyze-HuntSMBShares
$RiskLevelCountLow = $ExcessiveSharePrivsFinal | where RiskLevel -eq 'Low' | measure | select count -ExpandProperty count
$RiskLevelCountMedium = $ExcessiveSharePrivsFinal | where RiskLevel -eq 'Medium' | measure | select count -ExpandProperty count
$RiskLevelCountHigh = $ExcessiveSharePrivsFinal | where RiskLevel -eq 'High' | measure | select count -ExpandProperty count
- $RiskLevelCountCritical = $ExcessiveSharePrivsFinal | where RiskLevel -eq 'Critical' | measure | select count -ExpandProperty count
+ $RiskLevelCountCritical = $ExcessiveSharePrivsFinal | where RiskLevel -eq 'Critical' | measure | select count -ExpandProperty count
+
+ # ----------------------------------------------------------------------
+ # Create Computer Summary Information
+ # ----------------------------------------------------------------------
+ # TBD
+
+
+ # ----------------------------------------------------------------------
+ # Create Share Name Summary Information
+ # ----------------------------------------------------------------------
+
+ # Get unique share name count
+ $ShareNameChartCount = $ExcessiveSharePrivsFinal | where ShareName -ne "" | select ShareName -Unique |
+ foreach{
+ if( ($_.sharename -ne 'SYSVOL') -and ($_.sharename -ne 'NETLOGON'))
+ {
+ $_
+ }
+ } | measure | select count -ExpandProperty count
+
+ # Get unique share count
+ $ShareNameChartCountUnique = $ExcessiveSharePrivsFinal | where ShareName -ne "" |
+ foreach{
+ if( ($_.SharePath -notlike "\*SYSVOL") -and ($_.SharePath -notlike"\*NETLOGON"))
+ {
+ $_
+ }
+ } | select SharePath -Unique | measure | select count -ExpandProperty count
+
+ # Get share name severity
+ # Reivew ACLs for each share name, highest severity wins
+ $RiskLevelShareNameCountCritical = 0
+ $RiskLevelShareNameCountHigh = 0
+ $RiskLevelShareNameCountMedium = 0
+ $RiskLevelShareNameCountLow = 0
+ $ExcessiveSharePrivsFinal | where ShareName -ne "" |
+ foreach{
+
+ # filter out sysvol and netlogon
+ if( ($_.sharename -ne 'SYSVOL') -and ($_.sharename -ne 'NETLOGON'))
+ {
+ $_
+ }
+ } | select ShareName -Unique |
+ foreach {
+
+ # Set target share name
+ $TargetRiskShareName = $_.ShareName
+
+ # Grab the risk level for the highest risk acl for the share name
+ $ShareNameTopACLRiskScore = $ExcessiveSharePrivsFinal | where ShareName -eq $TargetRiskShareName | select RiskScore | sort RiskScore -Descending | select -First 1 | select RiskScore -ExpandProperty RiskScore
+
+ # Check risk level - Highest wins
+ If($ShareNameTopACLRiskScore -le 4 ) { $RiskLevelShareNameResult = "Low"}
+ If($ShareNameTopACLRiskScore -gt 4 -and $ShareNameTopACLRiskScore -lt 11 ) { $RiskLevelShareNameResult = "Medium"}
+ If($ShareNameTopACLRiskScore -ge 11 -and $ShareNameTopACLRiskScore -lt 20 ) { $RiskLevelShareNameResult = "High"}
+ If($ShareNameTopACLRiskScore -ge 20 ) { $RiskLevelShareNameResult = "Critical"}
+
+ # Increment counts
+ if($RiskLevelShareNameResult -eq "Low" ){$RiskLevelShareNameCountLow = $RiskLevelShareNameCountLow + 1}
+ if($RiskLevelShareNameResult -eq "Medium" ){$RiskLevelShareNameCountMedium = $RiskLevelShareNameCountMedium + 1}
+ if($RiskLevelShareNameResult -eq "High" ){$RiskLevelShareNameCountHigh = $RiskLevelShareNameCountHigh + 1}
+ if($RiskLevelShareNameResult -eq "Critical"){$RiskLevelShareNameCountCritical = $RiskLevelShareNameCountCritical + 1}
+ }
+
+ # ----------------------------------------------------------------------
+ # Create Folder Group Summary Information
+ # ----------------------------------------------------------------------
+ $RiskLevelFolderGroupCountCritical = 0
+ $RiskLevelFolderGroupCountHigh = 0
+ $RiskLevelFolderGroupCountMedium = 0
+ $RiskLevelFolderGroupCountLow = 0
+ $FolderGroupChartCount = $ExcessiveSharePrivsFinal | select FileListGroup -Unique | measure | select count -ExpandProperty count # Unique folder group
+ $ExcessiveSharePrivsFinal | select FileListGroup -Unique |
+ foreach {
+
+ # Set target share name
+ $TargetFileListGroup = $_.FileListGroup
+
+ # Grab the risk level for the highest risk acl for the share name
+ $FileListGroupTopACLRiskScore = $ExcessiveSharePrivsFinal | where FileListGroup -eq $TargetFileListGroup | select RiskScore | sort RiskScore -Descending | select -First 1 | select RiskScore -ExpandProperty RiskScore
+
+ # Check risk level - Highest wins
+ If($FileListGroupTopACLRiskScore -le 4 ) { $RiskLevelFileListGroupResult = "Low"}
+ If($FileListGroupTopACLRiskScore -gt 4 -and $FileListGroupTopACLRiskScore -lt 11 ) { $RiskLevelFileListGroupResult = "Medium"}
+ If($FileListGroupTopACLRiskScore -ge 11 -and $FileListGroupTopACLRiskScore -lt 20 ) { $RiskLevelFileListGroupResult = "High"}
+ If($FileListGroupTopACLRiskScore -ge 20 ) { $RiskLevelFileListGroupResult = "Critical"}
+
+ # Increment counts
+ if($RiskLevelFileListGroupResult -eq "Low" ){$RiskLevelFolderGroupCountLow = $RiskLevelFolderGroupCountLow + 1}
+ if($RiskLevelFileListGroupResult -eq "Medium" ){$RiskLevelFolderGroupCountMedium = $RiskLevelFolderGroupCountMedium + 1}
+ if($RiskLevelFileListGroupResult -eq "High" ){$RiskLevelFolderGroupCountHigh = $RiskLevelFolderGroupCountHigh + 1}
+ if($RiskLevelFileListGroupResult -eq "Critical"){$RiskLevelFolderGroupCountCritical = $RiskLevelFolderGroupCountCritical + 1}
+ }
+
+ # select all interance
+
+ # ----------------------------------------------------------------------
+ # Create ACL Summary Information
+ # ----------------------------------------------------------------------
+ # TBD
# ----------------------------------------------------------------------
# Create Timeline Reports
@@ -2622,107 +2605,58 @@ function Analyze-HuntSMBShares
# Set default
$ShareRowCountInteresting = "No"
- # Check if interesting files - Secrets
- # Files that may contain passwords, key, or other authentication tokens
- $ShareRowInterestingFileListSecrets = ""
- $ShareRowInterestingFileListSecretsCount = 0
- $ShareRowCountInterestingSecrets = "No"
-
- # Check for matches
- $ShareRowInterestingFileListSecrets = foreach ($pattern in $FileNamePatternsSecrets) {
-
- # Parse the filenames for all shares with the target name into a list
- # $FullFileListSim - define in above sections
-
- # Check if interesting file pattern matches the file name
- $FullFileListSim |
- foreach {
-
- # Reset exclude flag
- $ExcludeThisFile = 0
+ # Check if interesting files
+ # For each category generate count and list
+ $ShareNameInterestingFilesInsideHTML = ""
+ $ShareNameInterestingFilesOutsideHTML = ""
+ $FileNamePatternCategories | select Category -ExpandProperty Category |
+ foreach{
+
+ # Get category
+ $ShareNameCategoryName = $_
- # File to check
- $CheckThisfileOut = $_
+ # Get list of that sharename and category
+ $ShareNameCategoryFilesBase = $InterestingFilesAllObjects | Where ShareName -eq "$ShareName" | where Category -eq "$ShareNameCategoryName" | select FileName
+ $ShareNameCategoryFiles = $InterestingFilesAllObjects | Where ShareName -eq "$ShareName" | where Category -eq "$ShareNameCategoryName" | select FileName | ForEach-Object { $ASDF = $_.FileName; "$ASDF
" } | out-string
- # Check if it should be excluded
- $ImageFormats |
- foreach{
- if($CheckThisfileOut -like "$_"){
- $ExcludeThisFile = 1
- }
- }
+ # Get category count
+ $ShareNameCategoryFilesCount = $ShareNameCategoryFilesBase | measure | select count -expandproperty count
- # Check if it matches pattern
- if ($_ -like $pattern -and $ExcludeThisFile -eq 0) {
-
- # v1 add file name to link
- "$_
"
-
- # v2 add hyperlinked sharepath that expands betwen the: file name %(count)
- }
+ # Generate HTML with Category
+ if($ShareNameCategoryFilesCount -ne 0){
+ $ShareNameInterestingFilesHTMLPrep = @"
+
+