@@ -397,7 +397,85 @@ function Find-AllPersistence {
397397 return $false
398398 }
399399 }
400-
400+ function Get-APPID {
401+ param (
402+ [String ]
403+ $RootPath = $null ,
404+ [String ]
405+ $AppCLSID = $null
406+ )
407+
408+ $appName = " "
409+
410+ if ($null -ne $AppCLSID ) {
411+ $appIDList = Get-ItemProperty " $RootPath \Software\Classes\appid\*"
412+ foreach ($app in $appIDList ) {
413+ if ($null -ne $app.AppID -and $app.AppID -eq $AppCLSID ) {
414+ $appName = $app.PsChildName
415+ break
416+ }
417+ }
418+ }
419+ return $appName
420+ }
421+ function Get-CLSIDPayload {
422+ param (
423+ [String ]
424+ $RootPath = $null ,
425+ [String ]
426+ $CLSID = $null
427+ )
428+
429+ $dll = " "
430+
431+ $registryKey = (Get-ItemProperty " $rootPath \Software\Classes\CLSID\$CLSID \InprocServer32" )
432+ if ($null -eq $registryKey ) {
433+ $registryKey = (Get-ItemProperty " $rootPath \Software\Classes\CLSID\$CLSID \LocalServer32" )
434+ }
435+ if ($null -eq $registryKey ) {
436+ $registryKey = (Get-ItemProperty " Registry::HKEY_LOCAL_MACHINE\Software\Classes\CLSID\$CLSID \InprocServer32" )
437+ }
438+ if ($null -eq $registryKey ) {
439+ $registryKey = (Get-ItemProperty " Registry::HKEY_LOCAL_MACHINE\Software\Classes\CLSID\$CLSID \LocalServer32" )
440+ }
441+
442+ if ($null -eq $registryKey ) {
443+ $appName = " "
444+ $AppId = (Get-ItemProperty " $rootPath \Software\Classes\CLSID\$CLSID " )." AppId"
445+ if ($null -ne $AppId ) {
446+ if (-not $AppId.Contains (" {" )) {
447+ $AppId = " {$AppId }"
448+ }
449+ $appName = Get-APPID - RootPath $rootPath - CLSID $AppId
450+
451+ }
452+ else {
453+ $AppId = (Get-ItemProperty " Registry::HKEY_LOCAL_MACHINE\Software\Classes\CLSID\$CLSID " )." AppId"
454+ if ($null -ne $AppId ) {
455+ if (-not $AppId.Contains (" {" )) {
456+ $AppId = " {$AppId }"
457+ }
458+ $appName = Get-APPID - RootPath " Registry::HKEY_LOCAL_MACHINE" - AppCLSID $AppId
459+ }
460+ }
461+
462+ if ($appName -ne " " ) {
463+ $dll = $appName
464+ }
465+
466+ }
467+
468+ else {
469+ $dll = $registryKey .' (default)'
470+
471+ if ($null -ne $dll ) {
472+ if ($dll.EndsWith (" mscoree.dll" ) -and $null -ne $registryKey .' CodeBase' -and $registryKey .' CodeBase' -ne " " ) {
473+ $dll = $registryKey .' CodeBase'
474+ }
475+ }
476+ }
477+ return $dll
478+ }
401479 function Parse-NetUser {
402480 <#
403481 . SYNOPSIS
@@ -1628,25 +1706,99 @@ function Find-AllPersistence {
16281706 }
16291707
16301708 function Get-ScheduledTasks {
1709+
16311710 Write-Verbose - Message " $hostname - Getting scheduled tasks"
1632- $tasks = Get-ScheduledTask
1633- if ($tasks ) {
1634- foreach ($task in $tasks ) {
1635- $propPath = $task.TaskPath
1636- $propPath += $task.TaskName
1637- $path = ($task.Actions ).Execute + " " + ($task.Actions ).Arguments
1638- if ($task.UserId -eq ' SYSTEM' ) {
1711+
1712+ $tasksPath = " $env: windir \System32\Tasks"
1713+
1714+ $taskFileList = Get-ChildItem - Path $tasksPath - Recurse | Where-Object { ! $_.PSIsContainer }
1715+
1716+ $ErrorActionPreference = " SilentlyContinue"
1717+
1718+ foreach ($taskFile in $taskFileList ) {
1719+
1720+ [xml ] $xmlTask = Get-Content $taskFile.FullName
1721+
1722+ $propPath = $taskFile.FullName.Replace ($tasksPath , " " )
1723+
1724+ if ($null -ne $xmlTask.Task.Principals.Principal.UserId ) {
1725+ $userID = $xmlTask.Task.Principals.Principal.UserId
1726+ if (($userID -eq ' SYSTEM' ) -or ($userID -eq ' S-1-5-18' ) -or ($userID -eq ' S-1-5-19' ) -or ($userID -eq ' S-1-5-20' )) {
16391727 $access = ' System'
16401728 }
16411729 else {
16421730 $access = ' User'
16431731 }
1732+ }
1733+ elseif ($null -ne $xmlTask.Task.Principals.Principal.GroupId ) {
1734+ $groupID = $xmlTask.Task.Principals.Principal.GroupId
1735+ if (($groupID -eq ' SYSTEM' ) -or ($groupID -eq ' S-1-5-18' ) -or ($groupID -eq ' S-1-5-19' ) -or ($groupID -eq ' S-1-5-20' )) {
1736+ $access = ' System'
1737+ }
1738+ else {
1739+ $access = ' User'
1740+ }
1741+ }
1742+ else {
1743+ $access = " Unknow"
1744+ }
1745+
1746+ if ($null -ne $xmlTask.Task.Actions.Exec.Command ) {
1747+ $command = $xmlTask.Task.Actions.Exec.Command
1748+ $value = $command + " " + $xmlTask.Task.Actions.Exec.Arguments
1749+ }
1750+
1751+ elseif ($null -ne $xmlTask.Task.Actions.ComHandler.ClassId ) {
1752+ $ClassId = $xmlTask.Task.Actions.ComHandler.ClassId
1753+ if (-not $ClassId.Contains (" {" )) {
1754+ $ClassId = " {$ClassId }"
1755+ }
16441756
1645- $PersistenceObject = New-PersistenceObject - Hostname $hostname - Technique ' Scheduled Task' - Classification ' MITRE ATT&CK T1053.005' - Path $propPath - Value $path - AccessGained $access - Note " Scheduled tasks run executables or actions when certain conditions, such as user log in or machine boot up, are met." - Reference ' https://attack.mitre.org/techniques/T1053/005/'
1646- $null = $persistenceObjectArray.Add ($PersistenceObject )
1647- }
1757+ $rootPath = $null
1758+
1759+ if ($access -eq " System" ) {
1760+ $rootPath = " Registry::HKEY_LOCAL_MACHINE"
1761+ }
1762+
1763+ elseif ($null -ne $userID ) {
1764+ if ($userID.Contains (" \" )) {
1765+ $domain , $username = $userID.Split (" \" , 2 )
1766+ $objUser = New-Object System.Security.Principal.NTAccount($domain , $username )
1767+ $userID = $objUser.Translate ([System.Security.Principal.SecurityIdentifier ]).Value
1768+ }
1769+ $rootPath = " Registry::HKEY_USERS\$userID "
1770+
1771+ }
1772+ elseif ($null -ne $groupID ) {
1773+ if ($groupID.Contains (" \" )) {
1774+ $domain , $username = $userID.Split (" \" , 2 )
1775+ $objUser = New-Object System.Security.Principal.NTAccount($domain , $username )
1776+ $groupID = $objUser.Translate ([System.Security.Principal.SecurityIdentifier ]).Value
1777+ }
1778+ $rootPath = " Registry::HKEY_USERS\$groupID "
1779+ }
1780+
1781+ if ($null -ne $rootPath ) {
1782+ $dll = Get-CLSIDPayload - RootPath $rootPath - CLSID $ClassId
1783+ if ($dll -eq " " ) {
1784+ $value = $ClassId
1785+ }
1786+ else {
1787+ $value = $dll
1788+ }
1789+ }
1790+
1791+ else {
1792+ $value = " Unknow"
1793+ }
1794+ }
1795+
1796+ $PersistenceObject = New-PersistenceObject - Hostname $hostname - Technique ' Scheduled Task' - Classification ' MITRE ATT&CK T1053.005' - Path $propPath - Value $value - AccessGained $access - Note " Scheduled tasks run executables or actions when certain conditions, such as user log in or machine boot up, are met." - Reference ' https://attack.mitre.org/techniques/T1053/005/'
1797+ $null = $persistenceObjectArray.Add ($PersistenceObject )
1798+
16481799 }
16491800 Write-Verbose - Message ' '
1801+
16501802 }
16511803
16521804 function Get-BitsJobsNotifyCmdLine {
@@ -2468,11 +2620,6 @@ function Find-AllPersistence {
24682620 Get-RDPWDSStartupPrograms
24692621 break
24702622 }
2471- ' ScheduledTasks' {
2472- Get-ScheduledTasks
2473- break
2474- }
2475-
24762623 ' Screensaver' {
24772624 Get-Screensaver
24782625 break
0 commit comments