From 7cdee4b62cdcd7f344facc6c8e8e1676214a1275 Mon Sep 17 00:00:00 2001 From: Evan Hosinski Date: Fri, 10 Oct 2025 16:57:12 -0400 Subject: [PATCH] Enhance directory detection to handle prefix matching and eliminate duplicates Helps to discover directories with a prefix instead of just by exact match --- .../pkg/hunt/detect/directory/directories.go | 67 ++++++++++++++++++- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/internal/pkg/hunt/detect/directory/directories.go b/internal/pkg/hunt/detect/directory/directories.go index ec34138..0b402d7 100644 --- a/internal/pkg/hunt/detect/directory/directories.go +++ b/internal/pkg/hunt/detect/directory/directories.go @@ -12,14 +12,33 @@ var appData = os.Getenv("APPDATA") func Detect() []string { var suspiciousDirectories []string + seen := make(map[string]bool) // Prevent duplicates fmt.Printf("[*] Enumerating Suspicious Directories \n") // Check for common directories for _, dir := range common.CommonDirectories { dir = replaceAppData(dir) - if _, err := os.Stat(dir); err == nil { - fmt.Printf(" [?] Found %s\n", dir) - suspiciousDirectories = append(suspiciousDirectories, dir) + + // Check if this is a prefix pattern (ends with incomplete path such as Screen Connect "C:\Program Files (x86)\ScreenConnect Client (") + if isPrefix(dir) { + // Find all directories matching this prefix + matches := findPrefixMatches(dir) + for _, match := range matches { + if !seen[match] { + fmt.Printf(" [?] Found %s\n", match) + suspiciousDirectories = append(suspiciousDirectories, match) + seen[match] = true + } + } + } else { + // Exact match + if _, err := os.Stat(dir); err == nil { + if !seen[dir] { + fmt.Printf(" [?] Found %s\n", dir) + suspiciousDirectories = append(suspiciousDirectories, dir) + seen[dir] = true + } + } } } fmt.Printf("[+] Found %d Suspicious Directories\n", len(suspiciousDirectories)) @@ -27,6 +46,7 @@ func Detect() []string { return suspiciousDirectories } +// replaceAppData replaces {{APPDATA}} with the actual APPDATA path func replaceAppData(path string) string { if strings.Contains(path, "{{APPDATA}}") { p := strings.Replace(path, "{{APPDATA}}", "", -1) @@ -34,3 +54,44 @@ func replaceAppData(path string) string { } return path } + +// isPrefix checks if a path is a prefix pattern (incomplete path for matching) +func isPrefix(path string) bool { + // If path ends with "(" or other incomplete patterns, it's a prefix + return strings.HasSuffix(path, "(") || strings.HasSuffix(path, "\\") +} + +// findPrefixMatches finds all directories that start with the given prefix +func findPrefixMatches(prefix string) []string { + var matches []string + + // Get the parent directory to search in + parentDir := filepath.Dir(prefix) + + // Check if parent directory exists + if _, err := os.Stat(parentDir); os.IsNotExist(err) { + return matches + } + + // Read all entries in the parent directory + entries, err := os.ReadDir(parentDir) + if err != nil { + return matches + } + + // Get the base name prefix + basePrefix := filepath.Base(prefix) + + // Check each entry + for _, entry := range entries { + if entry.IsDir() { + // Check if this directory name starts with our prefix + if strings.HasPrefix(entry.Name(), basePrefix) { + fullPath := filepath.Join(parentDir, entry.Name()) + matches = append(matches, fullPath) + } + } + } + + return matches +}