diff --git a/PowerHuntShares.psm1 b/PowerHuntShares.psm1
index e8344e0..e26efc0 100644
--- a/PowerHuntShares.psm1
+++ b/PowerHuntShares.psm1
@@ -4,7 +4,7 @@
#--------------------------------------
# Author: Scott Sutherland, 2024 NetSPI
# License: 3-clause BSD
-# Version: v1.93
+# Version: v1.94
# 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
{
@@ -1735,123 +1735,6 @@ function Invoke-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"
@@ -2063,13 +1946,13 @@ function Invoke-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]@{
@@ -2120,7 +2003,108 @@ function Invoke-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
@@ -3046,216 +3030,58 @@ function Invoke-HuntSMBShares
# Set default
$ShareRowCountInteresting = "No"
- # Define common image and other formats to filter out later
- $ImageFormats = @("*.jpg", "*.jpeg", "*.png", "*.gif", "*.bmp", "*.ico", "*.svg", "*.webp", "*.mif", "*.heic", "*.msi")
+ # Check if interesting files
+ # For each category generate count and list
+ $ShareNameInterestingFilesInsideHTML = ""
+ $ShareNameInterestingFilesOutsideHTML = ""
+ $FileNamePatternCategories | select Category -ExpandProperty Category |
+ foreach{
+
+ # Get category
+ $ShareNameCategoryName = $_
- # Check if interesting files - Secrets
- # Files that may contain passwords, key, or other authentication tokens
- $ShareRowInterestingFileListSecrets = ""
- $ShareRowInterestingFileListSecretsCount = 0
- $ShareRowCountInterestingSecrets = "No"
- $FileNamePatternsSecrets = @(
- "*.bacpac*",
- "*.bat*",
- "*.config*",
- "*.dtsx*",
- "*.json*",
- "*.ps1*",
- "*.psm1*",
- "*.UDL*",
- "*config.php*",
- "*Credentials*",
- "*Creds*",
- "*keys*",
- "*pass*",
- "*private*",
- "*secret*",
- "*secure*",
- "*security*",
- "*web.conf*",
- "*htaccess*",
- "*htpasswd*",
- "*inetpub*",
- "applicationhost.config*",
- "auth*",
- "config.xml*",
- "context.xml*",
- "db2cli.ini*",
- "ftpd.*",
- "ftpusers*",
- "httpd.conf*",
- "hudson.security.HudsonPrivateSecurityRealm.*",
- "jboss-cli.xml*",
- "jboss-logmanager.properties*",
- "jenkins.model.JenkinsLocationConfiguration.*",
- "machine.config*",
- "my.*",
- "mysql.user*",
- "nginx.conf*",
- "*ntds.dit*",
- "pg_hba.conf*",
- "php.ini*",
- "putty.reg*",
- "postgresql.conf*",
- "SAM",
- "SAM-*",
- "SAM_*",
- "SYSTEM",
- "server.xml*",
- "shadow*",
- "standalone.xml*",
- "tnsnames.ora*",
- "tomcat-users.xml*",
- "sitemanager.xml*",
- "users.*",
- "*.vmx*",
- "*.vmdk*",
- "*.nvram*",
- "*.vmsd*",
- "*.vmsn*",
- "*.vmss*",
- "*.vmem*",
- "*.vhd*",
- "*.vhdx*",
- "*.avhd*",
- "*.avhdx*",
- "*.vsv*",
- "*.vbox*",
- "*.vbox-prev*",
- "*.vdi*",
- "*.hdd*",
- "*.sav*",
- "*.pvm*",
- "*.pvs*",
- "*.qcow*",
- "*.qcow2*",
- "*.img*",
- "*vcenter*",
- "*vault*",
- "*DefaultAppPool*",
- "*WinSCP.ini*",
- "*.kdbx",
- "wp-config.php*"
- )
+ # 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 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
+ # Get category count
+ $ShareNameCategoryFilesCount = $ShareNameCategoryFilesBase | measure | select count -expandproperty count
- # File to check
- $CheckThisfileOut = $_
-
- # Check if it should be excluded
- $ImageFormats |
- foreach{
- if($CheckThisfileOut -like "$_"){
- $ExcludeThisFile = 1
- }
- }
-
- # 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 = @"
+
+