Analysis/Get-RegistryAnalysis.ps1

function Get-RegistryAnalysis {
    <#
    .SYNOPSIS
        Analyzes Windows Registry for security-relevant keys and modifications
    .DESCRIPTION
        Scans critical registry locations for suspicious entries, unauthorized modifications,
        and security misconfigurations
    .PARAMETER IncludeAutoRun
        Include AutoRun registry locations in analysis
    .PARAMETER CheckPermissions
        Check registry key permissions for anomalies
    .PARAMETER ExportPath
        Path to export detailed results
    .EXAMPLE
        Get-RegistryAnalysis
        Get-RegistryAnalysis -IncludeAutoRun -CheckPermissions -ExportPath "C:\Audits"
    .OUTPUTS
        PSCustomObject with registry analysis results
    #>

    
    [CmdletBinding()]
    param(
        [Parameter()]
        [switch]$IncludeAutoRun,
        
        [Parameter()]
        [switch]$CheckPermissions,
        
        [Parameter()]
        [string]$ExportPath
    )
    
    begin {
        Write-Host "Analyzing Windows Registry..." -ForegroundColor Cyan
        
        $results = [PSCustomObject]@{
            AnalysisDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            SecuritySettings = @()
            AutoRunEntries = @()
            ServiceKeys = @()
            PolicyKeys = @()
            SuspiciousKeys = @()
            PermissionIssues = @()
            Statistics = @{
                TotalKeysScanned = 0
                SuspiciousFindings = 0
                AutoRunCount = 0
                PermissionIssues = 0
            }
        }
        
        # Critical registry paths to analyze
        $criticalPaths = @{
            # Security settings
            'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' = 'LSA Security Settings'
            'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' = 'System Policies'
            'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' = 'SMB Settings'
            'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest' = 'WDigest Settings'
            'HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog' = 'Event Log Policies'
            
            # Services
            'HKLM:\SYSTEM\CurrentControlSet\Services' = 'Services'
        }
        
        # AutoRun locations
        $autoRunPaths = @(
            'HKLM:\Software\Microsoft\Windows\CurrentVersion\Run',
            'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce',
            'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run',
            'HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce',
            'HKLM:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders',
            'HKLM:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders',
            'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon'
        )
    }
    
    process {
        try {
            # Analyze critical security settings
            Write-Verbose "Analyzing security settings..."
            foreach ($path in $criticalPaths.Keys) {
                if (Test-Path $path) {
                    try {
                        $key = Get-Item -Path $path -ErrorAction Stop
                        $results.Statistics.TotalKeysScanned++
                        
                        $properties = Get-ItemProperty -Path $path -ErrorAction SilentlyContinue
                        
                        # Analyze LSA settings
                        if ($path -match 'Lsa$') {
                            $restrictAnonymous = if ($null -ne $properties.PSObject.Properties['RestrictAnonymous']) { $properties.RestrictAnonymous } else { $null }
                            $limitBlankPasswordUse = if ($null -ne $properties.PSObject.Properties['LimitBlankPasswordUse']) { $properties.LimitBlankPasswordUse } else { $null }
                            $noLMHash = if ($null -ne $properties.PSObject.Properties['NoLMHash']) { $properties.NoLMHash } else { $null }
                            $disableDomainCreds = if ($null -ne $properties.PSObject.Properties['DisableDomainCreds']) { $properties.DisableDomainCreds } else { $null }
                            $everyoneIncludesAnonymous = if ($null -ne $properties.PSObject.Properties['EveryoneIncludesAnonymous']) { $properties.EveryoneIncludesAnonymous } else { $null }
                            
                            $keyObj = [PSCustomObject]@{
                                Path = $path
                                Category = $criticalPaths[$path]
                                RestrictAnonymous = $restrictAnonymous
                                LimitBlankPasswordUse = $limitBlankPasswordUse
                                NoLMHash = $noLMHash
                                DisableDomainCreds = $disableDomainCreds
                                EveryoneIncludesAnonymous = $everyoneIncludesAnonymous
                                Findings = @()
                            }
                            
                            # Check for security issues
                            if ($restrictAnonymous -ne 1) {
                                $keyObj.Findings += "RestrictAnonymous not set to secure value"
                                $results.Statistics.SuspiciousFindings++
                            }
                            if ($limitBlankPasswordUse -ne 1) {
                                $keyObj.Findings += "Blank passwords not restricted"
                                $results.Statistics.SuspiciousFindings++
                            }
                            
                            $results.SecuritySettings += $keyObj
                        }
                        
                        # Analyze WDigest settings
                        if ($path -match 'WDigest$') {
                            $useLogonCredential = if ($null -ne $properties.PSObject.Properties['UseLogonCredential']) { $properties.UseLogonCredential } else { $null }
                            if ($useLogonCredential -eq 1) {
                                $results.SecuritySettings += [PSCustomObject]@{
                                    Path = $path
                                    Category = 'WDigest Credential Caching'
                                    Finding = 'WDigest credential caching is ENABLED - credentials stored in plaintext!'
                                    Severity = 'Critical'
                                    Recommendation = 'Set UseLogonCredential to 0'
                                }
                                $results.Statistics.SuspiciousFindings++
                            }
                        }
                        
                        # Analyze UAC settings
                        if ($path -match 'Policies\\System$') {
                            $enableLUA = if ($null -ne $properties.PSObject.Properties['EnableLUA']) { $properties.EnableLUA } else { $null }
                            $consentPromptBehaviorAdmin = if ($null -ne $properties.PSObject.Properties['ConsentPromptBehaviorAdmin']) { $properties.ConsentPromptBehaviorAdmin } else { $null }
                            $enableInstallerDetection = if ($null -ne $properties.PSObject.Properties['EnableInstallerDetection']) { $properties.EnableInstallerDetection } else { $null }
                            $promptOnSecureDesktop = if ($null -ne $properties.PSObject.Properties['PromptOnSecureDesktop']) { $properties.PromptOnSecureDesktop } else { $null }
                            
                            $keyObj = [PSCustomObject]@{
                                Path = $path
                                Category = 'User Account Control'
                                EnableLUA = $enableLUA
                                ConsentPromptBehaviorAdmin = $consentPromptBehaviorAdmin
                                EnableInstallerDetection = $enableInstallerDetection
                                PromptOnSecureDesktop = $promptOnSecureDesktop
                                Findings = @()
                            }
                            
                            if ($enableLUA -ne 1) {
                                $keyObj.Findings += "UAC is disabled"
                                $results.Statistics.SuspiciousFindings++
                            }
                            if ($promptOnSecureDesktop -ne 1) {
                                $keyObj.Findings += "UAC not prompting on secure desktop"
                            }
                            
                            $results.SecuritySettings += $keyObj
                        }
                        
                    }
                    catch {
                        Write-Verbose "Could not analyze $path : $_"
                    }
                }
            }
            
            # Analyze AutoRun entries if requested
            if ($IncludeAutoRun) {
                Write-Verbose "Analyzing AutoRun registry locations..."
                foreach ($path in $autoRunPaths) {
                    if (Test-Path $path) {
                        try {
                            $properties = Get-ItemProperty -Path $path -ErrorAction SilentlyContinue
                            
                            if ($properties) {
                                $properties.PSObject.Properties | Where-Object { $_.Name -notmatch '^PS' } | ForEach-Object {
                                    $isSuspicious = $false
                                    $reasons = @()
                                    
                                    # Check for suspicious indicators
                                    if ($_.Value -match '(temp|appdata\\local\\temp|users\\public)') {
                                        $isSuspicious = $true
                                        $reasons += "Running from temporary or public location"
                                    }
                                    
                                    if ($_.Value -match '(cmd|powershell|wscript|cscript|mshta).*\.(exe|bat|vbs|js)') {
                                        $isSuspicious = $true
                                        $reasons += "Executes scripting engine"
                                    }
                                    
                                    $results.AutoRunEntries += [PSCustomObject]@{
                                        Location = $path
                                        Name = $_.Name
                                        Value = $_.Value
                                        Suspicious = $isSuspicious
                                        Reasons = if ($reasons) { $reasons -join '; ' } else { $null }
                                    }
                                    
                                    $results.Statistics.AutoRunCount++
                                    if ($isSuspicious) { $results.Statistics.SuspiciousFindings++ }
                                }
                            }
                        }
                        catch {
                            Write-Verbose "Could not analyze AutoRun path $path : $_"
                        }
                    }
                }
            }
            
            # Analyze service keys
            Write-Verbose "Analyzing service registry keys..."
            $servicePath = 'HKLM:\SYSTEM\CurrentControlSet\Services'
            if (Test-Path $servicePath) {
                $services = Get-ChildItem -Path $servicePath -ErrorAction SilentlyContinue | 
                    Select-Object -First 50  # Limit to avoid performance issues
                
                foreach ($service in $services) {
                    try {
                        $serviceProps = Get-ItemProperty -Path $service.PSPath -ErrorAction SilentlyContinue
                        
                        $imagePath = if ($null -ne $serviceProps -and $null -ne $serviceProps.PSObject.Properties['ImagePath']) { $serviceProps.ImagePath } else { $null }
                        
                        if ($imagePath) {
                            $isSuspicious = $false
                            $reasons = @()
                            
                            # Check for suspicious service paths
                            if ($imagePath -match '(temp|appdata|users\\public)') {
                                $isSuspicious = $true
                                $reasons += "Service running from suspicious location"
                            }
                            
                            # Check for services without proper quotes
                            if ($imagePath -match '^[A-Z]:\\.*\s.*\.exe' -and 
                                $imagePath -notmatch '^"') {
                                $isSuspicious = $true
                                $reasons += "Unquoted service path with spaces (potential privilege escalation)"
                            }
                            
                            if ($isSuspicious) {
                                $results.ServiceKeys += [PSCustomObject]@{
                                    ServiceName = $service.PSChildName
                                    ImagePath = $imagePath
                                    Start = if ($null -ne $serviceProps.PSObject.Properties['Start']) { $serviceProps.Start } else { $null }
                                    Reasons = $reasons -join '; '
                                }
                                $results.Statistics.SuspiciousFindings++
                            }
                        }
                    }
                    catch {
                        Write-Verbose "Could not analyze service $($service.PSChildName)"
                    }
                }
            }
            
            # Check registry permissions if requested
            if ($CheckPermissions) {
                Write-Verbose "Checking registry key permissions..."
                $criticalKeysToCheck = @(
                    'HKLM:\SAM',
                    'HKLM:\SECURITY',
                    'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
                )
                
                foreach ($keyPath in $criticalKeysToCheck) {
                    if (Test-Path $keyPath) {
                        try {
                            $acl = Get-Acl -Path $keyPath -ErrorAction Stop
                            
                            # Check for overly permissive access
                            $permissiveSids = @('S-1-1-0', 'S-1-5-32-545', 'S-1-5-11')
                            foreach ($access in $acl.Access) {
                                $isPermissiveIdentity = $false
                                foreach ($sid in $permissiveSids) {
                                    if (Test-IdentityReferenceIsSid -IdentityReference $access.IdentityReference -Sid $sid) {
                                        $isPermissiveIdentity = $true
                                        break
                                    }
                                }
                                if ($isPermissiveIdentity -and
                                    $access.RegistryRights -match '(FullControl|Write|Modify)') {
                                    
                                    $results.PermissionIssues += [PSCustomObject]@{
                                        Path = $keyPath
                                        Identity = $access.IdentityReference
                                        Rights = $access.RegistryRights
                                        AccessControlType = $access.AccessControlType
                                        Severity = 'High'
                                    }
                                    $results.Statistics.PermissionIssues++
                                }
                            }
                        }
                        catch {
                            Write-Verbose "Could not check permissions for $keyPath"
                        }
                    }
                }
            }
            
        }
        catch {
            Write-Error "Error during registry analysis: $_"
            throw
        }
    }
    
    end {
        # Display summary
        Write-Host "`nRegistry Analysis Complete!" -ForegroundColor Green
        Write-Host "`n=== Statistics ===" -ForegroundColor Cyan
        Write-Host "Keys scanned: $($results.Statistics.TotalKeysScanned)" -ForegroundColor Yellow
        Write-Host "Suspicious findings: $($results.Statistics.SuspiciousFindings)" -ForegroundColor $(if ($results.Statistics.SuspiciousFindings -gt 0) { 'Red' } else { 'Green' })
        
        if ($IncludeAutoRun) {
            Write-Host "AutoRun entries found: $($results.Statistics.AutoRunCount)" -ForegroundColor Yellow
        }
        
        if ($CheckPermissions) {
            Write-Host "Permission issues: $($results.Statistics.PermissionIssues)" -ForegroundColor $(if ($results.Statistics.PermissionIssues -gt 0) { 'Red' } else { 'Green' })
        }
        
        # Export if requested
        if ($ExportPath) {
            if (-not (Test-Path $ExportPath)) {
                New-Item -Path $ExportPath -ItemType Directory -Force | Out-Null
            }
            $exportFile = Join-Path -Path $ExportPath -ChildPath "RegistryAnalysis_$(Get-Date -Format 'yyyyMMdd_HHmmss').json"
            $results | ConvertTo-Json -Depth 5 | Out-File -FilePath $exportFile -Encoding UTF8
            Write-Host "`nResults exported to: $exportFile" -ForegroundColor Cyan
        }
        
        return $results
    }
}