AutorunScan.psm1
|
#Requires -Version 5.1 # AutorunScan - https://github.com/dooblpls/AutorunScan - MIT License # Enumerates Windows autostart locations (Sysinternals Autoruns scope + extras) with MITRE ATT&CK mapping. $script:Mitre = @{ 'T1037.001' = 'Boot or Logon Initialization Scripts: Logon Script (Windows)' 'T1053.005' = 'Scheduled Task/Job: Scheduled Task' 'T1137.001' = 'Office Application Startup: Office Template Macros' 'T1137.002' = 'Office Application Startup: Office Test' 'T1137.004' = 'Office Application Startup: Outlook Home Page' 'T1137.006' = 'Office Application Startup: Add-ins' 'T1176.001' = 'Software Extensions: Browser Extensions' 'T1197' = 'BITS Jobs' 'T1543.003' = 'Create or Modify System Process: Windows Service' 'T1546' = 'Event Triggered Execution' 'T1546.001' = 'Event Triggered Execution: Change Default File Association' 'T1546.002' = 'Event Triggered Execution: Screensaver' 'T1546.003' = 'Event Triggered Execution: WMI Event Subscription' 'T1546.007' = 'Event Triggered Execution: Netsh Helper DLL' 'T1546.008' = 'Event Triggered Execution: Accessibility Features' 'T1546.009' = 'Event Triggered Execution: AppCert DLLs' 'T1546.010' = 'Event Triggered Execution: AppInit DLLs' 'T1546.012' = 'Event Triggered Execution: Image File Execution Options Injection' 'T1546.013' = 'Event Triggered Execution: PowerShell Profile' 'T1546.015' = 'Event Triggered Execution: Component Object Model Hijacking' 'T1547.001' = 'Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder' 'T1547.002' = 'Boot or Logon Autostart Execution: Authentication Package' 'T1547.003' = 'Boot or Logon Autostart Execution: Time Providers' 'T1547.004' = 'Boot or Logon Autostart Execution: Winlogon Helper DLL' 'T1547.005' = 'Boot or Logon Autostart Execution: Security Support Provider' 'T1547.006' = 'Boot or Logon Autostart Execution: Kernel Modules and Extensions' 'T1547.008' = 'Boot or Logon Autostart Execution: LSASS Driver' 'T1547.010' = 'Boot or Logon Autostart Execution: Port Monitors' 'T1547.012' = 'Boot or Logon Autostart Execution: Print Processors' 'T1547.014' = 'Boot or Logon Autostart Execution: Active Setup' 'T1548.002' = 'Abuse Elevation Control Mechanism: Bypass User Account Control' 'T1556' = 'Modify Authentication Process' 'T1556.002' = 'Modify Authentication Process: Password Filter DLL' 'T1556.008' = 'Modify Authentication Process: Network Provider DLL' 'T1564' = 'Hide Artifacts' 'T1574.001' = 'Hijack Execution Flow: DLL' 'T1574.012' = 'Hijack Execution Flow: COR_PROFILER' } # Kind: Values = each value of the key (Filter = regex on value name, '' = all, '^$' = default value) # SubValues = matching values in all subkeys (recursive) | ClsidKeys / ClsidValues = COM CLSIDs -> InprocServer32 # ProgIdKeys = subkey names are ProgIDs. Split = regex to split one value into several entries. # HKCU:\ is expanded to every loaded user hive, HKLM:\SOFTWARE\ additionally to Wow6432Node. '*' = wildcard, '[*]' = literal '*' key. $script:Rows = @' Category;Kind;Mitre;Filter;Split;Path Logon;Values;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Logon;Values;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce Logon;SubValues;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx Logon;Values;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices Logon;Values;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce Logon;Values;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run Logon;Values;T1547.001;;;HKCU:\Software\Microsoft\Windows\CurrentVersion\Run Logon;Values;T1547.001;;;HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce Logon;SubValues;T1547.001;;;HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnceEx Logon;Values;T1547.001;;;HKCU:\Software\Microsoft\Windows\CurrentVersion\RunServices Logon;Values;T1547.001;;;HKCU:\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce Logon;Values;T1547.001;;;HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run Logon;Values;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\Run Logon;Values;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\RunOnce Logon;SubValues;T1547.001;;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\RunOnceEx Logon;Values;T1547.001;^StartupPrograms$;,;HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd Logon;Values;T1547.001;^InitialProgram$;;HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp Logon;Values;T1547.001;^(Load|Run)$;;HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows Logon;Values;T1547.001;^IconServiceLib$;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows Logon;Values;T1547.001;^Shell$;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System Logon;Values;T1547.001;^Shell$;;HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\System Logon;Values;T1547.001;^AlternateShell$;;HKLM:\SYSTEM\CurrentControlSet\Control\SafeBoot Logon;Values;T1547.001;^(Startup|Common Startup)$;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders Logon;Values;T1547.001;^Startup$;;HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders Logon;SubValues;T1547.014;^StubPath$;;HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components Logon;Values;T1037.001;^UserInitMprLogonScript$;;HKCU:\Environment Logon;SubValues;T1037.001;^Script$;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts Logon;SubValues;T1037.001;^Script$;;HKCU:\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts Winlogon;Values;T1547.004;^Userinit$;,;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon Winlogon;Values;T1547.004;^(Shell|Taskman|AppSetup|VmApplet|GinaDLL)$;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon Winlogon;Values;T1547.004;^(Shell|Userinit|Taskman)$;;HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon Winlogon;SubValues;T1547.004;^DllName$;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify Winlogon;SubValues;T1547.004;^DllName$;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions Winlogon;ClsidKeys;T1556;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers Winlogon;ClsidKeys;T1556;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters Winlogon;ClsidKeys;T1556;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\PLAP Providers Boot Execute;Values;T1547.001;^(BootExecute|BootExecuteNoPnpSync|SetupExecute|Execute|S0InitialCommand|PlatformExecute)$;;HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager Boot Execute;Values;T1547.001;^ImagePath$;;HKLM:\SYSTEM\CurrentControlSet\Control\BootVerificationProgram Boot Execute;Values;T1547.001;^CmdLine$;;HKLM:\SYSTEM\Setup AppInit;Values;T1546.010;^AppInit_DLLs$;[ ,];HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows AppInit;Values;T1546.009;;;HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDlls Known DLLs;Values;T1574.001;;;HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs Image Hijacks;SubValues;T1546.012;^(Debugger|VerifierDlls)$;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options Image Hijacks;SubValues;T1546.012;^MonitorProcess$;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit Image Hijacks;Values;T1546;^AutoRun$;;HKLM:\SOFTWARE\Microsoft\Command Processor Image Hijacks;Values;T1546;^AutoRun$;;HKCU:\Software\Microsoft\Command Processor Image Hijacks;Values;T1546;^Debugger$;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug Image Hijacks;Values;T1546;^DbgManagedDebugger$;;HKLM:\SOFTWARE\Microsoft\.NETFramework Image Hijacks;Values;T1546;^(Debugger|ReflectDebugger)$;;HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\Hangs Image Hijacks;Values;T1574.012;^(COR_PROFILER|COR_PROFILER_PATH.*|CORECLR_PROFILER|CORECLR_PROFILER_PATH.*)$;;HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment Image Hijacks;Values;T1574.012;^(COR_PROFILER|COR_PROFILER_PATH.*|CORECLR_PROFILER|CORECLR_PROFILER_PATH.*)$;;HKCU:\Environment LSA;Values;T1547.002;^Authentication Packages$;;HKLM:\SYSTEM\CurrentControlSet\Control\Lsa LSA;Values;T1556.002;^Notification Packages$;;HKLM:\SYSTEM\CurrentControlSet\Control\Lsa LSA;Values;T1547.005;^Security Packages$;;HKLM:\SYSTEM\CurrentControlSet\Control\Lsa LSA;Values;T1547.005;^Security Packages$;;HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\OSConfig LSA;Values;T1547.005;^SecurityProviders$;,;HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders LSA;Values;T1547.008;^Extensions$;;HKLM:\SYSTEM\CurrentControlSet\Control\LsaExtensionConfig\LsaSrv LSA;Values;T1547.008;^LsaDbExtPt$;;HKLM:\SYSTEM\CurrentControlSet\Services\NTDS Print Monitors;SubValues;T1547.010;^Driver$;;HKLM:\SYSTEM\CurrentControlSet\Control\Print\Monitors Print Monitors;SubValues;T1547.012;^Driver$;;HKLM:\SYSTEM\CurrentControlSet\Control\Print\Environments\*\Print Processors Time Providers;SubValues;T1547.003;^DllName$;;HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders Netsh;Values;T1546.007;;;HKLM:\SOFTWARE\Microsoft\NetSh Screensaver;Values;T1546.002;^SCRNSAVE\.EXE$;;HKCU:\Control Panel\Desktop Screensaver;Values;T1546.002;^SCRNSAVE\.EXE$;;HKCU:\Software\Policies\Microsoft\Windows\Control Panel\Desktop Winsock;SubValues;;^LibraryPath$;;HKLM:\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\NameSpace_Catalog5 Winsock;Values;;^AutodialDLL$;;HKLM:\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters Explorer;ClsidValues;T1546.015;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\ShellServiceObjectDelayLoad Explorer;ClsidKeys;T1546.015;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellServiceObjects Explorer;ClsidValues;T1546.015;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SharedTaskScheduler Explorer;ClsidValues;T1546.015;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks Explorer;ClsidKeys;T1546.015;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers Explorer;ClsidKeys;T1546.015;;;HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers Explorer;ClsidKeys;T1546.015;;;HKLM:\SOFTWARE\Classes\PROTOCOLS\Handler Explorer;ClsidKeys;T1546.015;;;HKLM:\SOFTWARE\Classes\PROTOCOLS\Filter Internet Explorer;ClsidKeys;T1176.001;;;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects Internet Explorer;ClsidKeys;T1176.001;;;HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects Internet Explorer;ClsidValues;T1176.001;;;HKLM:\SOFTWARE\Microsoft\Internet Explorer\Toolbar Internet Explorer;SubValues;T1176.001;^(Exec|Script|ClsidExtension)$;;HKLM:\SOFTWARE\Microsoft\Internet Explorer\Extensions Internet Explorer;SubValues;T1176.001;^(Exec|Script|ClsidExtension)$;;HKCU:\Software\Microsoft\Internet Explorer\Extensions Internet Explorer;ClsidValues;T1176.001;;;HKCU:\Software\Microsoft\Internet Explorer\UrlSearchHooks Browser;Values;T1176.001;;;HKLM:\SOFTWARE\Policies\Google\Chrome\ExtensionInstallForcelist Browser;Values;T1176.001;;;HKLM:\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallForcelist Codecs;Values;;;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32 Codecs;Values;;;;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Font Drivers Codecs;ClsidKeys;;;;HKLM:\SOFTWARE\Classes\Filter Codecs;ClsidKeys;;;;HKLM:\SOFTWARE\Classes\CLSID\{083863F1-70DE-11d0-BD40-00A0C911CE86}\Instance Codecs;ClsidKeys;;;;HKLM:\SOFTWARE\Classes\CLSID\{AC757296-3522-4E11-9862-C17BE5A1767E}\Instance Codecs;ClsidKeys;;;;HKLM:\SOFTWARE\Classes\CLSID\{7ED96837-96F0-4812-B211-F13C24117ED3}\Instance Codecs;ClsidKeys;;;;HKLM:\SOFTWARE\Classes\CLSID\{ABE3B9A4-257D-4B97-BD1A-294AF496222E}\Instance Office;ProgIdKeys;T1137.006;;;HKLM:\SOFTWARE\Microsoft\Office\*\Addins Office;ProgIdKeys;T1137.006;;;HKCU:\Software\Microsoft\Office\*\Addins Office;Values;T1137.006;^OPEN\d*$;;HKCU:\Software\Microsoft\Office\*\Excel\Options Office;Values;T1137.002;^$;;HKLM:\SOFTWARE\Microsoft\Office test\Special\Perf Office;Values;T1137.002;^$;;HKCU:\Software\Microsoft\Office test\Special\Perf Office;SubValues;T1137.004;^URL$;;HKCU:\Software\Microsoft\Office\*\Outlook\WebView Office;Values;T1137.004;^(Stamp|UserDefinedUrl)$;;HKCU:\Software\Microsoft\Office\*\Outlook\Today '@ | ConvertFrom-Csv -Delimiter ';' foreach ($h in 'HKLM:\SOFTWARE\Classes', 'HKCU:\Software\Classes') { foreach ($t in 'exefile', 'batfile', 'cmdfile', 'comfile', 'piffile', 'scrfile', 'htafile', 'htmlfile', 'VBSFile', 'JSFile', 'WSFFile') { $script:Rows += [pscustomobject]@{ Category = 'Image Hijacks'; Kind = 'Values'; Mitre = 'T1546.001'; Filter = '^$'; Split = ''; Path = "$h\$t\shell\open\command" } } foreach ($o in '[*]', 'AllFileSystemObjects', 'Directory', 'Directory\Background', 'Folder', 'Drive') { foreach ($x in 'ContextMenuHandlers', 'PropertySheetHandlers', 'CopyHookHandlers', 'DragDropHandlers', 'ColumnHandlers') { $script:Rows += [pscustomobject]@{ Category = 'Explorer'; Kind = 'ClsidKeys'; Mitre = 'T1546.015'; Filter = ''; Split = ''; Path = "$h\$o\ShellEx\$x" } } } } foreach ($t in 'ms-settings', 'mscfile', 'Folder', 'exefile') { # classic UAC bypass hijacks $script:Rows += [pscustomobject]@{ Category = 'Image Hijacks'; Kind = 'Values'; Mitre = 'T1548.002'; Filter = '^(|DelegateExecute)$'; Split = ''; Path = "HKCU:\Software\Classes\$t\shell\open\command" } } $GuidRx = '^\{[0-9a-fA-F-]{36}\}$' $script:SearchDirs = @("$env:windir\System32", $env:windir, "$env:windir\System32\wbem", "$env:windir\System32\drivers", "$env:windir\System32\spool\prtprocs\x64", "$env:windir\System32\spool\prtprocs\w32x86") + ($env:Path -split ';' | Where-Object { $_ }) function Find-File([string]$p) { $p = $p.Trim().Trim('"').TrimStart('@') if (-not $p) { return } foreach ($q in $p, ($p -replace ',.*$'), ($p -replace '\|.*$')) { try { $rooted = [IO.Path]::IsPathRooted($q) } catch { continue } $cands = if ($rooted) { $q, "$q.exe", "$q.dll" } else { foreach ($d in $script:SearchDirs) { "$d\$q"; "$d\$q.exe"; "$d\$q.dll" } } foreach ($c in $cands) { if ([IO.File]::Exists($c)) { return [IO.Path]::GetFullPath($c) } } } } <# .SYNOPSIS Resolves an autostart command line to the file that actually gets loaded (handles quoting, environment variables, \SystemRoot\, \??\, unquoted paths with spaces, rundll32 targets and bare file names on the search path). .EXAMPLE Resolve-AutorunImage 'rundll32.exe shell32.dll,Control_RunDLL' #> function Resolve-AutorunImage([string]$Command) { if (-not $Command.Trim().Trim('"')) { return } $c = [Environment]::ExpandEnvironmentVariables($Command.Trim()) -replace '^\\\?\?\\' -replace '^\\SystemRoot\\', "$env:windir\" -replace '^(?i)system32\\', "$env:windir\System32\" -replace '^(?i)autocheck\s+' $f = $null if ($c -match '^"([^"]+)"') { $f = Find-File $matches[1] } else { # unquoted "C:\Program Files\x.exe -a": grow token by token until a file exists $tok = $c -split ' ' for ($i = 0; $i -lt $tok.Count -and -not $f; $i++) { $f = Find-File ($tok[0..$i] -join ' ') } } if ($f -match '\\rundll32\.exe$' -and $c -match 'rundll32(?:\.exe)?"?\s+"?([^",]+)') { $dll = Find-File $matches[1] if ($dll) { $f = $dll } } $f } # direct .NET access: the registry provider is ~100x slower for thousands of lookups function Get-RegValue([string]$Path, [string]$Name = '') { if ($Path -notmatch '^(HKLM:|Registry::HKEY_USERS)\\(.+)$') { return } $hive = if ($matches[1] -eq 'HKLM:') { [Microsoft.Win32.Registry]::LocalMachine } else { [Microsoft.Win32.Registry]::Users } $k = try { $hive.OpenSubKey($matches[2]) } catch { Write-Verbose "$_" } if ($k) { $k.GetValue($Name, $null, 'DoNotExpandEnvironmentNames') } } function Resolve-Clsid([string]$Clsid, [string]$UserRoot) { if ($Clsid -notmatch $GuidRx) { return } $roots = @(if ($UserRoot) { "$UserRoot\Software\Classes" }) + 'HKLM:\SOFTWARE\Classes', 'HKLM:\SOFTWARE\Classes\Wow6432Node' foreach ($r in $roots) { foreach ($s in 'InprocServer32', 'LocalServer32') { $v = Get-RegValue "$r\CLSID\$Clsid\$s" if ($v) { return $v } } } } function Get-UserRoot($Key) { if ($Key.Name -match '^HKEY_USERS\\([^\\]+)') { "Registry::HKEY_USERS\$($matches[1])" } } function Expand-Hive([string]$Path) { if ($Path -like 'HKCU:\*') { foreach ($sid in $script:UserSids) { "Registry::HKEY_USERS\$sid\" + $Path.Substring(6) } } elseif ($Path -like 'HKLM:\SOFTWARE\*') { $Path; $Path -replace '^HKLM:\\SOFTWARE\\', 'HKLM:\SOFTWARE\Wow6432Node\' } else { $Path } } function Get-RegKey([string]$Path) { # own wildcard expansion: provider wildcards on HKCR take minutes. '[*]' = literal '*' key $seg = $Path -split '\\' $i = 0; while ($i -lt $seg.Count -and $seg[$i] -notmatch '[*?\[]') { $i++ } $keys = @(Get-Item -LiteralPath ($seg[0..($i - 1)] -join '\') -ErrorAction Ignore) for (; $i -lt $seg.Count; $i++) { $p = $seg[$i] $keys = foreach ($k in $keys) { if (-not $k) { continue } if ($p -match '[*?]' -and $p -ne '[*]') { $names = $k.GetSubKeyNames() -like $p } else { $names = $p -replace '^\[\*\]$', '*' } foreach ($n in $names) { try { $k.OpenSubKey($n) } catch { Write-Verbose "$_" } } } } $keys | Where-Object { $_ } } function Get-SubKeyTree($Key) { foreach ($n in $Key.GetSubKeyNames()) { try { $s = $Key.OpenSubKey($n) } catch { continue } if ($s) { $s; Get-SubKeyTree $s } } } function ConvertTo-AutorunEntry { param($Category, $Location, $Entry, $Command, $Mitre, $Info, $Image) if (-not $PSBoundParameters.ContainsKey('Image')) { $Image = Resolve-AutorunImage $Command } $vi = if ($Image) { try { [Diagnostics.FileVersionInfo]::GetVersionInfo($Image) } catch { Write-Verbose "$_" } } [pscustomobject]@{ Category = $Category Entry = $Entry Command = $Command ImagePath = $Image Description = $vi.FileDescription Company = $vi.CompanyName Signer = $null SHA256 = $null Mitre = $Mitre Technique = $script:Mitre["$Mitre"] Info = $Info Location = $Location } } function Get-RegistryAutorun($Row) { $split = { param($d) foreach ($x in @($d)) { if ($Row.Split -and $x -is [string]) { $x -split $Row.Split } else { $x } } } foreach ($key in Get-RegKey $Row.Path) { $user = Get-UserRoot $key switch ($Row.Kind) { 'Values' { foreach ($n in $key.GetValueNames()) { if ($n -notmatch $Row.Filter) { continue } foreach ($d in & $split $key.GetValue($n, $null, 'DoNotExpandEnvironmentNames')) { if ("$d".Trim()) { ConvertTo-AutorunEntry $Row.Category $key.Name $(if ($n) { $n } else { '(Default)' }) "$d".Trim() $Row.Mitre } } } } 'SubValues' { foreach ($sk in Get-SubKeyTree $key) { foreach ($n in $sk.GetValueNames()) { if ($n -notmatch $Row.Filter) { continue } foreach ($d in & $split $sk.GetValue($n, $null, 'DoNotExpandEnvironmentNames')) { if ("$d".Trim()) { ConvertTo-AutorunEntry $Row.Category $sk.Name ($sk.Name -replace '^.*\\') "$d".Trim() $Row.Mitre $n } } } } } 'ClsidValues' { foreach ($n in $key.GetValueNames()) { $id = if ($n -match $GuidRx) { $n } else { "$($key.GetValue($n))" } ConvertTo-AutorunEntry $Row.Category $key.Name $(if ($n) { $n } else { '(Default)' }) (Resolve-Clsid $id $user) $Row.Mitre $id } } 'ClsidKeys' { foreach ($n in $key.GetSubKeyNames()) { $sk = try { $key.OpenSubKey($n) } catch { Write-Verbose "$_" } $id = @($n, "$($sk.GetValue(''))", "$($sk.GetValue('CLSID'))") -match $GuidRx | Select-Object -First 1 ConvertTo-AutorunEntry $Row.Category $key.Name $n (Resolve-Clsid $id $user) $Row.Mitre $id } } 'ProgIdKeys' { foreach ($n in $key.GetSubKeyNames()) { $sk = try { $key.OpenSubKey($n) } catch { Write-Verbose "$_" } $cmd = $sk.GetValue('Manifest') if (-not $cmd) { foreach ($r in @(if ($user) { "$user\Software\Classes" }) + 'HKLM:\SOFTWARE\Classes') { $id = Get-RegValue "$r\$n\CLSID" if ($id) { $cmd = Resolve-Clsid $id $user; break } } } ConvertTo-AutorunEntry $Row.Category $key.Name $n $cmd $Row.Mitre "LoadBehavior=$($sk.GetValue('LoadBehavior'))" } } } } } <# .SYNOPSIS Enumerates Windows autostart locations (Sysinternals Autoruns scope plus more) with MITRE ATT&CK mapping. .DESCRIPTION Categories: Logon, Winlogon, Explorer, Internet Explorer, Browser, Scheduled Tasks, Services, Drivers, Codecs, Boot Execute, Image Hijacks, AppInit, Known DLLs, Winsock, Print Monitors, LSA, Network Providers, Time Providers, Netsh, Screensaver, WMI, Office, PowerShell, Accessibility, COM Hijack, BITS. Run elevated in 64-bit PowerShell, otherwise other users' hives, some tasks, BITS jobs etc. are missing. .PARAMETER Category Only scan these categories (wildcards allowed), e.g. 'Logon','Image*'. .PARAMETER VerifySignature Check the Authenticode signature of each image (Signer column, catalog signatures included). .PARAMETER HideMicrosoft Hide entries with a valid Microsoft signature (implies -VerifySignature). .PARAMETER Hash Compute the SHA256 of each image file (e.g. for a VirusTotal lookup). .EXAMPLE Get-Autorun -HideMicrosoft | Out-GridView .EXAMPLE Get-Autorun -VerifySignature -Hash | Export-Csv autoruns.csv -NoTypeInformation -Encoding UTF8 .EXAMPLE Get-Autorun | Group-Object Mitre | Sort-Object Count -Descending .LINK https://github.com/dooblpls/AutorunScan #> function Get-Autorun { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Category', Justification = 'Used inside the $want scriptblock')] [CmdletBinding()] param([string[]]$Category = '*', [switch]$VerifySignature, [switch]$HideMicrosoft, [switch]$Hash) if ([Environment]::Is64BitOperatingSystem -and -not [Environment]::Is64BitProcess) { Write-Warning '32-bit PowerShell on 64-bit Windows: System32 and registry are redirected, results are incomplete.' } $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('Administrators') if (-not $isAdmin) { Write-Warning 'Not running elevated: other users, some scheduled tasks, BITS jobs etc. are missing.' } $want = { param($c) foreach ($p in $Category) { if ($c -like $p) { return $true } }; $false } $script:UserSids = (Get-ChildItem Registry::HKEY_USERS -ErrorAction Ignore).PSChildName -match '^S-1-5-(18|21-[\d-]+)$' $profiles = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' -ErrorAction Ignore | ForEach-Object { $_.GetValue('ProfileImagePath') } | Where-Object { $_ -and (Test-Path -LiteralPath $_ -ErrorAction Ignore) } $sigCache = @{} $seen = [Collections.Generic.HashSet[string]]::new() & { foreach ($row in $script:Rows) { if (& $want $row.Category) { foreach ($p in Expand-Hive $row.Path) { Get-RegistryAutorun ([pscustomobject]@{ Category = $row.Category; Kind = $row.Kind; Mitre = $row.Mitre; Filter = $row.Filter; Split = $row.Split; Path = $p }) } } } # --- file system based --- $files = @( foreach ($p in $profiles) { 'Logon', 'T1547.001', "$p\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\*" 'PowerShell', 'T1546.013', "$p\Documents\WindowsPowerShell\*profile.ps1", "$p\Documents\PowerShell\*profile.ps1", "$p\OneDrive*\*\WindowsPowerShell\*profile.ps1", "$p\OneDrive*\*\PowerShell\*profile.ps1" 'Office', 'T1137.001', "$p\AppData\Roaming\Microsoft\Word\STARTUP\*", "$p\AppData\Roaming\Microsoft\Excel\XLSTART\*" 'Office', 'T1137.006', "$p\AppData\Roaming\Microsoft\AddIns\*" 'Browser', 'T1176.001', "$p\AppData\Roaming\Mozilla\Firefox\Profiles\*\extensions\*" } 'Logon', 'T1547.001', "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\*" 'Logon', 'T1037.001', "$env:windir\System32\GroupPolicy\*\Scripts\*\*", "$env:windir\System32\GroupPolicyUsers\*\*\Scripts\*\*" 'PowerShell', 'T1546.013', "$env:windir\System32\WindowsPowerShell\v1.0\*profile.ps1", "$env:ProgramFiles\PowerShell\*\*profile.ps1" 'Office', 'T1137.001', "$env:ProgramFiles\Microsoft Office\root\Office*\STARTUP\*", "$env:ProgramFiles\Microsoft Office\root\Office*\XLSTART\*" 'Accessibility', 'T1546.008', ('sethc', 'utilman', 'osk', 'Magnify', 'Narrator', 'DisplaySwitch', 'AtBroker' | ForEach-Object { "$env:windir\System32\$_.exe" }) ) $cat = $null; $mitre = $null foreach ($x in $files) { if ($x -notmatch '[\\/]') { if ($x -match '^T\d') { $mitre = $x } else { $cat = $x }; continue } if (-not (& $want $cat)) { continue } foreach ($f in Get-ChildItem -Path $x -Force -File -ErrorAction Ignore | Where-Object Name -ne 'desktop.ini') { $cmd = $f.FullName if ($f.Extension -eq '.lnk') { $l = (New-Object -ComObject WScript.Shell).CreateShortcut($f.FullName) $cmd = "$($l.TargetPath) $($l.Arguments)".Trim() } ConvertTo-AutorunEntry $cat $f.DirectoryName $f.Name $cmd $mitre $f.LastWriteTime.ToString('s') } } if (& $want 'Browser') { foreach ($p in $profiles) { foreach ($m in Get-ChildItem "$p\AppData\Local\*\User Data\*\Extensions\*\*\manifest.json", "$p\AppData\Local\*\*\User Data\*\Extensions\*\*\manifest.json" -ErrorAction Ignore) { $j = try { Get-Content -LiteralPath $m.FullName -Raw | ConvertFrom-Json } catch { Write-Verbose "$_" } $name = $j.name if ($name -match '^__MSG_(.+)__$') { # localized name: _locales\<default_locale>\messages.json, keys are case-insensitive $msg = try { Get-Content -LiteralPath "$($m.DirectoryName)\_locales\$($j.default_locale)\messages.json" -Raw | ConvertFrom-Json } catch { Write-Verbose "$_" } $prop = $msg.PSObject.Properties | Where-Object Name -eq $matches[1] | Select-Object -First 1 if ($prop) { $name = $prop.Value.message } } ConvertTo-AutorunEntry 'Browser' $m.Directory.Parent.Parent.FullName "$name [$($m.Directory.Parent.Name)]" $m.DirectoryName 'T1176.001' "v$($j.version)" -Image $null } } } # --- services / drivers --- if (& $want 'Services') { foreach ($s in Get-CimInstance Win32_Service) { $p = "HKLM:\SYSTEM\CurrentControlSet\Services\$($s.Name)" $dll = Get-RegValue "$p\Parameters" 'ServiceDll' ConvertTo-AutorunEntry 'Services' $p $s.Name $(if ($dll) { $dll } else { $s.PathName }) 'T1543.003' "$($s.StartMode)/$($s.State): $($s.DisplayName)" $fc = Get-RegValue $p 'FailureCommand' if ($fc) { ConvertTo-AutorunEntry 'Services' $p "$($s.Name) (FailureCommand)" $fc 'T1543.003' } } } if (& $want 'Drivers') { foreach ($d in Get-CimInstance Win32_SystemDriver) { ConvertTo-AutorunEntry 'Drivers' "HKLM:\SYSTEM\CurrentControlSet\Services\$($d.Name)" $d.Name $d.PathName 'T1547.006' "$($d.StartMode)/$($d.State): $($d.DisplayName)" } } if (& $want 'Network Providers') { $order = Get-RegValue 'HKLM:\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order' 'ProviderOrder' foreach ($n in "$order" -split ',' | Where-Object { $_ }) { $p = "HKLM:\SYSTEM\CurrentControlSet\Services\$n\NetworkProvider" ConvertTo-AutorunEntry 'Network Providers' $p $n (Get-RegValue $p 'ProviderPath') 'T1556.008' } } if (& $want 'Winsock') { foreach ($c in 'Catalog_Entries', 'Catalog_Entries64') { foreach ($k in Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\Protocol_Catalog9\$c" -ErrorAction Ignore) { # PackedCatalogItem: char[260] DLL path, then WSAPROTOCOL_INFOW (szProtocol at +116) $b = $k.GetValue('PackedCatalogItem') if ($b.Length -lt 888) { continue } $dll = [Text.Encoding]::Default.GetString($b, 0, 260).Split([char]0)[0] $name = [Text.Encoding]::Unicode.GetString($b, 376, 512).Split([char]0)[0] ConvertTo-AutorunEntry 'Winsock' $k.Name $name $dll '' $c } } } # --- scheduled tasks --- if (& $want 'Scheduled Tasks') { $tasks = @(Get-ScheduledTask -ErrorAction Ignore) foreach ($t in $tasks) { foreach ($a in $t.Actions) { $cmd = if ($a.Execute) { "$($a.Execute) $($a.Arguments)".Trim() } else { Resolve-Clsid $a.ClassId } ConvertTo-AutorunEntry 'Scheduled Tasks' "Task Scheduler$($t.TaskPath)" "$($t.TaskPath)$($t.TaskName)" $cmd 'T1053.005' "$($t.State)$(if ($a.ClassId) { " COM $($a.ClassId) $($a.Data)" })" } } if ($isAdmin) { # tasks hidden from the API (SD removed, e.g. Tarrask) still live in TaskCache\Tree $known = @{}; foreach ($t in $tasks) { $known["$($t.TaskPath)$($t.TaskName)"] = 1 } foreach ($k in Get-SubKeyTree (Get-Item 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree')) { if (-not $k.GetValue('Id')) { continue } $name = '\' + ($k.Name -replace '^.*\\TaskCache\\Tree\\') if (-not $k.GetValue('SD') -or -not $known[$name]) { ConvertTo-AutorunEntry 'Scheduled Tasks' $k.Name $name '' 'T1564' "HIDDEN: no SD or not visible via Task Scheduler API, Id $($k.GetValue('Id'))" -Image $null } } } } # --- WMI event subscriptions --- if (& $want 'WMI') { foreach ($ns in 'root\subscription', 'root\default') { $filters = @{}; Get-CimInstance -Namespace $ns -ClassName __EventFilter -ErrorAction Ignore | ForEach-Object { $filters[$_.Name] = $_.Query } $bind = @{}; Get-CimInstance -Namespace $ns -ClassName __FilterToConsumerBinding -ErrorAction Ignore | ForEach-Object { $bind[$_.Consumer.Name] = $filters[$_.Filter.Name] } foreach ($c in Get-CimInstance -Namespace $ns -ClassName __EventConsumer -ErrorAction Ignore) { $cmd = @($c.CommandLineTemplate, $c.ExecutablePath, $c.ScriptFileName, $c.ScriptText) | Where-Object { $_ } | Select-Object -First 1 ConvertTo-AutorunEntry 'WMI' "$ns\$($c.CimClass.CimClassName)" $c.Name "$cmd" 'T1546.003' "Filter: $($bind[$c.Name])" } } } # --- per-user COM objects (shadow HKLM = classic COM hijack) --- if (& $want 'COM Hijack') { foreach ($sid in $script:UserSids) { foreach ($k in Get-RegKey "Registry::HKEY_USERS\$sid\Software\Classes\CLSID") { foreach ($id in $k.GetSubKeyNames()) { foreach ($s in 'InprocServer32', 'LocalServer32', 'TreatAs', 'ScriptletURL') { $sk = try { $k.OpenSubKey("$id\$s") } catch { Write-Verbose "$_" } if (-not $sk -or -not $sk.GetValue('')) { continue } $shadow = if (Test-Path -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\$id") { 'shadows HKLM CLSID' } ConvertTo-AutorunEntry 'COM Hijack' $sk.Name $id $sk.GetValue('', $null, 'DoNotExpandEnvironmentNames') 'T1546.015' "$s $shadow".Trim() } } } } } if ((& $want 'BITS') -and $isAdmin) { foreach ($j in Get-BitsTransfer -AllUsers -ErrorAction Ignore) { ConvertTo-AutorunEntry 'BITS' "BITS\$($j.OwnerAccount)" $j.DisplayName "$($j.NotifyCmdLine)" 'T1197' "$($j.JobState): $($j.FileList.RemoteName -join ', ')" } } } | ForEach-Object { # shared (non-redirected) keys show up again under Wow6432Node if (-not $seen.Add("$($_.Category)|$($_.Entry)|$($_.Command)|$($_.Location -replace '\\Wow6432Node')")) { return } if (($VerifySignature -or $HideMicrosoft) -and $_.ImagePath) { if (-not $sigCache.ContainsKey($_.ImagePath)) { $s = Get-AuthenticodeSignature -LiteralPath $_.ImagePath -ErrorAction Ignore $sigCache[$_.ImagePath] = if ($s.SignerCertificate) { "($($s.Status)) " + ($s.SignerCertificate.Subject -replace '^CN="?([^,"]+).*', '$1') } else { "($($s.Status))" } } $_.Signer = $sigCache[$_.ImagePath] } if ($HideMicrosoft -and $_.Signer -like '(Valid) Microsoft*') { return } if ($Hash -and $_.ImagePath) { $_.SHA256 = (Get-FileHash -LiteralPath $_.ImagePath -ErrorAction Ignore).Hash } $_ } } Export-ModuleMember -Function Get-Autorun, Resolve-AutorunImage |