From 0bd22e6385290caa88c3756c1b73f45e20c67ad5 Mon Sep 17 00:00:00 2001 From: eleetas Date: Fri, 10 Feb 2017 17:20:05 -0800 Subject: [PATCH 01/19] Handled cases of no installed DB and only one installed DB --- CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 b/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 index bfa0e31..d4bfe79 100644 --- a/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 +++ b/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 @@ -67,8 +67,11 @@ Outputs objects representing the relevant information regarding installed applic Get-CSRegistryValue -ValueNameOnly | Group-Object -Property ValueName -AsHashTable $InstalledSdb = Get-CSRegistryKey -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSdb' @CommonArgs + if (-not $InstalledSdb) { continue } + if ($InstalledSdb.GetType() -isnot [System.Array]) { $InstalledSdb = @($InstalledSdb)} + $CurrentSdb = 0 - + foreach ($Database in $InstalledSdb) { $GUID = $Database.SubKey.Split('\')[-1] From 0844f66dac15af594ded3d9bf998ce5dbbbc0bc0 Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Sun, 21 May 2017 10:13:03 -0700 Subject: [PATCH 02/19] Adding AppCompatCache --- CimSweep/ArtifactRetrieval/AppCompatCache.ps1 | 329 ++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 CimSweep/ArtifactRetrieval/AppCompatCache.ps1 diff --git a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 new file mode 100644 index 0000000..048a89b --- /dev/null +++ b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 @@ -0,0 +1,329 @@ +function Get-CSAppCompatCache { +<# +.SYNOPSIS + +Retrieves and parses entries from the AppCompatCache based on OS version. + +Author: Jesse Davis (@secabstraction) +License: BSD 3-Clause + +.DESCRIPTION + +Get-CSAppCompatCache parses entries from the Application Compatibility Cache stored in the registry. + +.PARAMETER CimSession + +Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. + +.EXAMPLE + +Get-CSAppCompatCache + +.EXAMPLE + +Get-CSAppCompatCache -CimSession $CimSession + +.OUTPUTS + +CimSweep.AppCompatCacheEntry + +Outputs objects consisting of the application's file path and that file's last modified time. Note: the LastModified property is a UTC datetime string in Round-trip format. + +#> + + [CmdletBinding()] + [OutputType('CimSweep.AppCompatCacheEntry')] + param ( + [Alias('Session')] + [ValidateNotNullOrEmpty()] + [Microsoft.Management.Infrastructure.CimSession[]] + $CimSession + ) + + begin { + # If a CIM session is not provided, trick the function into thinking there is one. + if (-not $PSBoundParameters['CimSession']) { + $CimSession = '' + $CIMSessionCount = 1 + } else { + $CIMSessionCount = $CimSession.Count + } + + $CurrentCIMSession = 0 + } + + process { + foreach ($Session in $CimSession) { + $ComputerName = $Session.ComputerName + if (-not $Session.ComputerName) { $ComputerName = 'localhost' } + + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Installed App Compat database sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ + + $CommonArgs = @{} + + if ($Session.Id) { $CommonArgs['CimSession'] = $Session } + + $Parameters = @{ + ClassName = 'Win32_OperatingSystem' + Property = @('Version','OSArchitecture') + } + + $OS = Get-CimInstance @Parameters @CommonArgs + + $Parameters = @{ + Hive = 'HKLM' + SubKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache' + ValueName = 'AppCompatCache' + } + + $AppCompatCache = Get-CSRegistryValue @Parameters @CommonArgs + + ConvertFrom-ByteArray -CacheBytes $AppCompatCache.ValueContent -OSVersion $OS.Version -OSArchitecture $OS.OSArchitecture + } + } + end {} +} + + +function ConvertFrom-ByteArray { +<# +.SYNOPSIS + +Converts bytes from the AppCompatCache registry key into objects. + +Author: Jesse Davis (@secabstraction) +License: BSD 3-Clause + +Thanks to @ericrzimmerman for these test files https://github.com/EricZimmerman/AppCompatCacheParser/tree/master/AppCompatCacheParserTest/TestFiles + +.DESCRIPTION + +ConvertFrom-ByteArray converts bytes from the AppCompatCache registry key into objects. + +.PARAMETER CacheBytes + +Byte array from the AppCompatCache registry key. + +.PARAMETER OSVersion + +Specifies the operating system version from which the AppCompatCache bytes were retrieved. + +.PARAMETER OSArchitecture + +Specifies the bitness of the operating system from which the AppCompatCache bytes were retrieved. + +.EXAMPLE + +ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArchitecture 32-bit +#> + param ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [byte[]] + $CacheBytes, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $OSVersion, + + [Parameter()] + [ValidateSet('32-bit','64-bit')] + [string] + $OSArchitecture + ) + + $MemoryStream = New-Object IO.MemoryStream -ArgumentList @(,$CacheBytes) + $BinaryReader = New-Object IO.BinaryReader -ArgumentList $MemoryStream + + $ASCIIEncoding = [Text.Encoding]::ASCII + $UnicodeEncoding = [Text.Encoding]::Unicode + + switch ($OSVersion) { + + { $_ -like '10.*' } { # Windows 10 + + $null = $BinaryReader.BaseStream.Seek(48, [IO.SeekOrigin]::Begin) + + # check for magic + if ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') { + $null = $BinaryReader.BaseStream.Seek(52, [IO.SeekOrigin]::Begin) # offset shifted in creators update + if ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') { throw 'Not Windows 10' } + } + + do { # parse entries + $null = $BinaryReader.BaseStream.Seek(8, [IO.SeekOrigin]::Current) # padding between entries + + $Path = $UnicodeEncoding.GetString($BinaryReader.ReadBytes($BinaryReader.ReadUInt16())) + $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime + + $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes + + [PSCustomObject]@{ + PSTypeName = 'CimSweep.AppCompatCacheEntry' + Path = $Path + LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + } + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') + } + + { $_ -like '6.3*' } { # Windows 8.1 / Server 2012 R2 + + $null = $BinaryReader.BaseStream.Seek(128, [IO.SeekOrigin]::Begin) + + # check for magic + if ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') { throw 'Not windows 8.1/2012r2' } + + do { # parse entries + $null = $BinaryReader.BaseStream.Seek(8, [IO.SeekOrigin]::Current) # padding & datasize + + $Path = $UnicodeEncoding.GetString($BinaryReader.ReadBytes($BinaryReader.ReadUInt16())) + + $null = $BinaryReader.ReadBytes(10) # skip insertion/shim flags & padding + + $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime + + $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes + + [PSCustomObject]@{ + PSTypeName = 'CimSweep.AppCompatCacheEntry' + Path = $Path + LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + } + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') + } + + { $_ -like '6.2*' } { # Windows 8.0 / Server 2012 + + # check for magic + $null = $BinaryReader.BaseStream.Seek(128, [IO.SeekOrigin]::Begin) + if ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '00ts') { throw 'Not Windows 8/2012' } + + do { # parse entries + $null = $BinaryReader.BaseStream.Seek(8, [IO.SeekOrigin]::Current) # padding & datasize + + $Path = $UnicodeEncoding.GetString($BinaryReader.ReadBytes($BinaryReader.ReadUInt16())) + + $null = $BinaryReader.BaseStream.Seek(10, [IO.SeekOrigin]::Current) # skip insertion/shim flags & padding + + $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime + + $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes + + [PSCustomObject]@{ + PSTypeName = 'CimSweep.AppCompatCacheEntry' + Path = $Path + LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + } + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '00ts') + } + + { $_ -like '6.1*' } { # Windows 7 / Server 2008 R2 + + # check for magic + if ([BitConverter]::ToString($BinaryReader.ReadBytes(4)[3..0]) -ne 'BA-DC-0F-EE') { throw 'Not Windows 7/2008R2'} + + $NumberOfEntries = $BinaryReader.ReadInt32() + + $null = $BinaryReader.BaseStream.Seek(128, [IO.SeekOrigin]::Begin) # skip padding + + if ($OSArchitecture -eq '32-bit') { + + do { + $EntryPosition++ + + $PathSize = $BinaryReader.ReadUInt16() + + $null = $BinaryReader.ReadUInt16() # MaxPathSize + + $PathOffset = $BinaryReader.ReadInt32() + + $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime + + $null = $BinaryReader.BaseStream.Seek(16, [IO.SeekOrigin]::Current) + + $Position = $BinaryReader.BaseStream.Position + + $null = $BinaryReader.BaseStream.Seek($PathOffset, [IO.SeekOrigin]::Begin) + + $Path = $UnicodeEncoding.GetString($BinaryReader.ReadBytes($PathSize)) + + $null = $BinaryReader.BaseStream.Seek($Position, [IO.SeekOrigin]::Begin) + + [PSCustomObject]@{ + PSTypeName = 'CimSweep.AppCompatCacheEntry' + Path = $Path + LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + } + } until ($EntryPosition -eq $NumberOfEntries) + } + + else { # 64-bit + + do { + $EntryPosition++ + + $PathSize = $BinaryReader.ReadUInt16() + + # Padding + $null = $BinaryReader.BaseStream.Seek(6, [IO.SeekOrigin]::Current) + + $PathOffset = $BinaryReader.ReadInt64() + $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime + + $null = $BinaryReader.BaseStream.Seek(24, [IO.SeekOrigin]::Current) + + $Position = $BinaryReader.BaseStream.Position + + $null = $BinaryReader.BaseStream.Seek($PathOffset, [IO.SeekOrigin]::Begin) + + $Path = $UnicodeEncoding.GetString($BinaryReader.ReadBytes($PathSize)) + + $null = $BinaryReader.BaseStream.Seek($Position, [IO.SeekOrigin]::Begin) + + [PSCustomObject]@{ + PSTypeName = 'CimSweep.AppCompatCacheEntry' + Path = $Path + LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + } + } until ($EntryPosition -eq $NumberOfEntries) + } + } + + { $_ -like '6.0*' } { <# Windows Vista / Server 2008 #> } + + { $_ -like '5.2*' } { <# Windows XP Pro 64-bit / Server 2003 (R2) #> } + + { $_ -like '5.1*' } { # Windows XP 32-bit + + # check for magic + if ([BitConverter]::ToString($BinaryReader.ReadBytes(4)[3..0]) -ne 'DE-AD-BE-EF') { throw 'Not Windows XP 32-bit'} + + $NumberOfEntries = $BinaryReader.ReadInt32() # this is always 96, even if there aren't 96 entries + + $null = $BinaryReader.BaseStream.Seek(400, [IO.SeekOrigin]::Begin) # skip padding + + do { # parse entries + $EntryPosition++ + $Path = $UnicodeEncoding.GetString($BinaryReader.ReadBytes(528)).TrimEnd("`0") # 528 == MAX_PATH + 4 unicode chars + $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime + + if (($LastModifiedTime.Year -eq 1600) -and !$Path) { break } # empty entries == end + + $null = $BinaryReader.BaseStream.Seek(16, [IO.SeekOrigin]::Current) # skip some bytes + + [PSCustomObject]@{ + PSTypeName = 'CimSweep.AppCompatCacheEntry' + Path = $Path + LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + } + } until ($EntryPosition -eq $NumberOfEntries) + } + } + $BinaryReader.Dispose() + $MemoryStream.Dispose() +} + +Export-ModuleMember -Function Get-CSAppCompatCache \ No newline at end of file From 33bb8cbc09e5d00487f4fc692c1cc6f723af075e Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Mon, 22 May 2017 05:43:56 -0700 Subject: [PATCH 03/19] Updated the manifest --- CimSweep/CimSweep.psd1 | 1 + 1 file changed, 1 insertion(+) diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index d057c61..a994f59 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -37,6 +37,7 @@ FunctionsToExport = @( 'Get-CSAVInfo', 'Get-CSProxyConfig', 'Get-CSInstalledAppCompatShimDatabase', + 'Get-CSAppCompatCache', 'Get-CSBitlockerKeyProtector', 'Get-CSDeviceGuardStatus' ) From 99dce3075615a57dfeef8c1fe82f2b6eb3c5ad84 Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Mon, 22 May 2017 08:22:42 -0700 Subject: [PATCH 04/19] Added Network Profiles sweep --- CimSweep/ArtifactRetrieval/AppCompatCache.ps1 | 2 +- .../ArtifactRetrieval/NetworkProfiles.ps1 | 108 ++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 diff --git a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 index 048a89b..4ec4423 100644 --- a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 +++ b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 @@ -58,7 +58,7 @@ Outputs objects consisting of the application's file path and that file's last m if (-not $Session.ComputerName) { $ComputerName = 'localhost' } # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Installed App Compat database sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + Write-Progress -Id 1 -Activity 'CimSweep - AppCompatCache sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) $CurrentCIMSession++ $CommonArgs = @{} diff --git a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 new file mode 100644 index 0000000..a90bb05 --- /dev/null +++ b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 @@ -0,0 +1,108 @@ +function Get-CSNetworkProfile { +<# +.SYNOPSIS + +Retrieves and parses entries from the AppCompatCache based on OS version. + +Author: Jesse Davis (@secabstraction) +License: BSD 3-Clause + +.DESCRIPTION + +Get-CSAppCompatCache parses entries from the Application Compatibility Cache stored in the registry. + +.PARAMETER CimSession + +Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. + +.EXAMPLE + +Get-CSAppCompatCache + +.EXAMPLE + +Get-CSAppCompatCache -CimSession $CimSession + +.OUTPUTS + +CimSweep.AppCompatCacheEntry + +Outputs objects consisting of the application's file path and that file's last modified time. Note: the LastModified property is a UTC datetime string in Round-trip format. + +#> + + [CmdletBinding()] + [OutputType('CimSweep.NetworkProfile')] + param ( + [Alias('Session')] + [ValidateNotNullOrEmpty()] + [Microsoft.Management.Infrastructure.CimSession[]] + $CimSession + ) + + begin { + # If a CIM session is not provided, trick the function into thinking there is one. + if (-not $PSBoundParameters['CimSession']) { + $CimSession = '' + $CIMSessionCount = 1 + } else { + $CIMSessionCount = $CimSession.Count + } + + $CurrentCIMSession = 0 + } + + process { + foreach ($Session in $CimSession) { + $ComputerName = $Session.ComputerName + if (-not $Session.ComputerName) { $ComputerName = 'localhost' } + + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Network Profiles sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ + + $CommonArgs = @{} + + if ($Session.Id) { $CommonArgs['CimSession'] = $Session } + + $Parameters = @{ + Hive = 'HKLM' + SubKey = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles' + } + + Get-CSRegistryKey @Parameters @CommonArgs | ForEach-Object { + $Properties = @{} + Get-CSRegistryValue -Hive $_.Hive -SubKey $_.SubKey @CommonArgs | ForEach-Object { + if ($_.ValueName -like "Date*") { + $BinaryReader = New-Object IO.BinaryReader (New-Object IO.MemoryStream (,$_.ValueContent)) + + $Year = $BinaryReader.ReadInt16() + $Month = $BinaryReader.ReadInt16() + $null = $BinaryReader.ReadInt16() # skip week day + $Day = $BinaryReader.ReadInt16() + $Hour = $BinaryReader.ReadInt16() + $Minute = $BinaryReader.ReadInt16() + $Second = $BinaryReader.ReadInt16() + $Millisecond = $BinaryReader.ReadInt16() + + $BinaryReader.BaseStream.Dispose() + $BinaryReader.Dispose() + + $Properties.Add($_.ValueName, [datetime]::new($Year, $Month, $Day, $Hour, $Minute, $Second, $Millisecond, [DateTimeKind]::Utc).ToString('o')) + } + elseif ($_.ValueName -eq 'NameType') { + $Type = switch ($_.ValueContent) { + 6 { 'Ethernet' } + 23 { 'VPN' } + 71 { 'WiFi' } + } + $Properties.Add('Type',$Type) + } + else { $Properties.Add($_.ValueName, $_.ValueContent) } + } + [PSCustomObject]$Properties + } + } + } + end {} +} \ No newline at end of file From 64d05907cec812589adee4c58c08247c6b261480 Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Mon, 22 May 2017 08:26:33 -0700 Subject: [PATCH 05/19] Added Network Profiles sweep --- CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 index a90bb05..5ca9f78 100644 --- a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 +++ b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 @@ -2,14 +2,14 @@ <# .SYNOPSIS -Retrieves and parses entries from the AppCompatCache based on OS version. +Retrieves network profile information. Author: Jesse Davis (@secabstraction) License: BSD 3-Clause .DESCRIPTION -Get-CSAppCompatCache parses entries from the Application Compatibility Cache stored in the registry. +Get-CSNetworkProfile retrieves and parses network profile information stored in the registry. .PARAMETER CimSession @@ -17,17 +17,17 @@ Specifies the CIM session to use for this cmdlet. Enter a variable that contains .EXAMPLE -Get-CSAppCompatCache +Get-CSNetworkProfile .EXAMPLE -Get-CSAppCompatCache -CimSession $CimSession +Get-CSNetworkProfile -CimSession $CimSession .OUTPUTS -CimSweep.AppCompatCacheEntry +CimSweep.NetworkProfile -Outputs objects consisting of the application's file path and that file's last modified time. Note: the LastModified property is a UTC datetime string in Round-trip format. +Outputs objects consisting of relevant network profile information. Note: the timestamps of this object are a UTC datetime string in Round-trip format. #> From f3714245049f41c72e758f31fa2d31ea256db800 Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Mon, 22 May 2017 08:27:35 -0700 Subject: [PATCH 06/19] Added Network Profiles sweep --- CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 index 5ca9f78..3fb4736 100644 --- a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 +++ b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 @@ -58,7 +58,7 @@ Outputs objects consisting of relevant network profile information. Note: the ti if (-not $Session.ComputerName) { $ComputerName = 'localhost' } # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Network Profiles sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + Write-Progress -Id 1 -Activity 'CimSweep - Network Profile sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) $CurrentCIMSession++ $CommonArgs = @{} From a918c0073bae3dfa924fb89ddf3783b4fb6fe43b Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Mon, 22 May 2017 08:30:29 -0700 Subject: [PATCH 07/19] Added Network Profiles sweep --- CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 | 4 +++- CimSweep/CimSweep.psd1 | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 index 3fb4736..07407ad 100644 --- a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 +++ b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 @@ -105,4 +105,6 @@ Outputs objects consisting of relevant network profile information. Note: the ti } } end {} -} \ No newline at end of file +} + +Export-ModuleMember -Function Get-CSNetworkProfile \ No newline at end of file diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index a994f59..a49b62c 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -36,6 +36,7 @@ FunctionsToExport = @( 'Get-CSVulnerableServicePermission', 'Get-CSAVInfo', 'Get-CSProxyConfig', + 'Get-CSNetworkProfile', 'Get-CSInstalledAppCompatShimDatabase', 'Get-CSAppCompatCache', 'Get-CSBitlockerKeyProtector', From d2926a04b69faacba4b9f2d4edfb7c7e7f924faf Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Mon, 22 May 2017 13:44:00 -0700 Subject: [PATCH 08/19] Added UserAssist Sweep --- CimSweep/ArtifactRetrieval/UserAssist.ps1 | 113 ++++++++++++++++++++++ CimSweep/CimSweep.psd1 | 1 + 2 files changed, 114 insertions(+) create mode 100644 CimSweep/ArtifactRetrieval/UserAssist.ps1 diff --git a/CimSweep/ArtifactRetrieval/UserAssist.ps1 b/CimSweep/ArtifactRetrieval/UserAssist.ps1 new file mode 100644 index 0000000..5ea52d9 --- /dev/null +++ b/CimSweep/ArtifactRetrieval/UserAssist.ps1 @@ -0,0 +1,113 @@ +function Get-CSUserAssist { +<# +.SYNOPSIS + +Retrieves and parses user assist entries. + +Author: Jesse Davis (@secabstraction) +License: BSD 3-Clause + +.DESCRIPTION + +Get-CSNetworkProfile retrieves and parses user assist entry information stored in the registry. + +.PARAMETER CimSession + +Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. + +.EXAMPLE + +Get-CSUserAssist + +.EXAMPLE + +Get-CSUserAssist -CimSession $CimSession + +.OUTPUTS + +CimSweep.UserAssistEntry + +Outputs objects consisting of relevant user assist information. Note: the LastExecutedTime of this object is a UTC datetime string in Round-trip format. + +#> + + [CmdletBinding()] + [OutputType('CimSweep.UserAssistEntry')] + param ( + [Alias('Session')] + [ValidateNotNullOrEmpty()] + [Microsoft.Management.Infrastructure.CimSession[]] + $CimSession + ) + + begin { + # If a CIM session is not provided, trick the function into thinking there is one. + if (-not $PSBoundParameters['CimSession']) { + $CimSession = '' + $CIMSessionCount = 1 + } else { + $CIMSessionCount = $CimSession.Count + } + + $CurrentCIMSession = 0 + } + + process { + foreach ($Session in $CimSession) { + $ComputerName = $Session.ComputerName + if (-not $Session.ComputerName) { $ComputerName = 'localhost' } + + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - UserAssist sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ + + $CommonArgs = @{} + + if ($Session.Id) { $CommonArgs['CimSession'] = $Session } + + $UserSids = Get-HKUSID @CommonArgs + + foreach ($Sid in $UserSids) { + + $Parameters = @{ + Hive = 'HKU' + SubKey = "$Sid\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist" + Recurse = $true + } + + Get-CSRegistryKey @Parameters @CommonArgs | ForEach-Object { + if ($_.SubKey -like "*Count") { + Get-CSRegistryValue -Hive $_.Hive -SubKey $_.SubKey @CommonArgs | ForEach-Object { + + # Decrypt Rot13 from https://github.com/StackCrash/PoshCiphers + # truncated && streamlined algorithm a little + + $PlainCharList = New-Object Collections.Generic.List[char] + foreach ($CipherChar in $_.ValueName.ToCharArray()) { + + switch ($CipherChar) { + { $_ -ge 65 -and $_ -le 90 } { $PlainCharList.Add((((($_ - 65 - 13) % 26 + 26) % 26) + 65)) } # Uppercase characters + { $_ -ge 97 -and $_ -le 122 } { $PlainCharList.Add((((($_ - 97 - 13) % 26 + 26) % 26) + 97)) } # Lowercase characters + default { $PlainCharList.Add($CipherChar) } # Pass through symbols and numbers + } + } + + # Parse LastExecutedTime from binary data + $FileTime = [datetime]::FromFileTime([BitConverter]::ToInt64($_.ValueContent[60..67],0)) + + [PSCustomObject]@{ + PSTypeName = 'CimSweep.UserAssistEntry' + Name = -join $PlainCharList + UserSid = $Sid + LastExecutedTime = $FileTime.ToUniversalTime().ToString('o') + } + } + } + } + } + } + } + end {} +} + +Export-ModuleMember -Function Get-CSUserAssist \ No newline at end of file diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index a49b62c..20853ef 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -39,6 +39,7 @@ FunctionsToExport = @( 'Get-CSNetworkProfile', 'Get-CSInstalledAppCompatShimDatabase', 'Get-CSAppCompatCache', + 'Get-CSUserAssist', 'Get-CSBitlockerKeyProtector', 'Get-CSDeviceGuardStatus' ) From 3d348d7210cfbb939329d47dc1c58160588f0914 Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Mon, 22 May 2017 13:47:17 -0700 Subject: [PATCH 09/19] Added UserAssist Sweep --- CimSweep/ArtifactRetrieval/UserAssist.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CimSweep/ArtifactRetrieval/UserAssist.ps1 b/CimSweep/ArtifactRetrieval/UserAssist.ps1 index 5ea52d9..87d918c 100644 --- a/CimSweep/ArtifactRetrieval/UserAssist.ps1 +++ b/CimSweep/ArtifactRetrieval/UserAssist.ps1 @@ -9,7 +9,7 @@ License: BSD 3-Clause .DESCRIPTION -Get-CSNetworkProfile retrieves and parses user assist entry information stored in the registry. +Get-CSUserAssist retrieves and parses user assist entry information stored in the registry. .PARAMETER CimSession From 9cc78e83840358faa2025bca15ae4408aa799e1e Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Wed, 24 May 2017 12:08:41 -0700 Subject: [PATCH 10/19] Live Tests Showed Errs - Fixed --- CimSweep/ArtifactRetrieval/AppCompatCache.ps1 | 26 +++---- .../ArtifactRetrieval/NetworkProfiles.ps1 | 67 +++++++++++++------ CimSweep/ArtifactRetrieval/UserAssist.ps1 | 10 ++- 3 files changed, 68 insertions(+), 35 deletions(-) diff --git a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 index 4ec4423..c418006 100644 --- a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 +++ b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 @@ -65,19 +65,22 @@ Outputs objects consisting of the application's file path and that file's last m if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - $Parameters = @{ - ClassName = 'Win32_OperatingSystem' - Property = @('Version','OSArchitecture') - } + $OS = Get-CimInstance -ClassName Win32_OperatingSystem @CommonArgs - $OS = Get-CimInstance @Parameters @CommonArgs - - $Parameters = @{ - Hive = 'HKLM' - SubKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache' - ValueName = 'AppCompatCache' + if ($OS.Version -like "5.1*") { + $Parameters = @{ + Hive = 'HKLM' + SubKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility' + } } - + else { + $Parameters = @{ + Hive = 'HKLM' + SubKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache' + ValueName = 'AppCompatCache' + } + } + $AppCompatCache = Get-CSRegistryValue @Parameters @CommonArgs ConvertFrom-ByteArray -CacheBytes $AppCompatCache.ValueContent -OSVersion $OS.Version -OSArchitecture $OS.OSArchitecture @@ -130,7 +133,6 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $OSVersion, [Parameter()] - [ValidateSet('32-bit','64-bit')] [string] $OSArchitecture ) diff --git a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 index 07407ad..aa78acf 100644 --- a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 +++ b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 @@ -71,34 +71,59 @@ Outputs objects consisting of relevant network profile information. Note: the ti } Get-CSRegistryKey @Parameters @CommonArgs | ForEach-Object { + $Properties = @{} + Get-CSRegistryValue -Hive $_.Hive -SubKey $_.SubKey @CommonArgs | ForEach-Object { - if ($_.ValueName -like "Date*") { - $BinaryReader = New-Object IO.BinaryReader (New-Object IO.MemoryStream (,$_.ValueContent)) + + $ValueName = $_.ValueName + $ValueContent = $_.ValueContent + + switch ($ValueName) { - $Year = $BinaryReader.ReadInt16() - $Month = $BinaryReader.ReadInt16() - $null = $BinaryReader.ReadInt16() # skip week day - $Day = $BinaryReader.ReadInt16() - $Hour = $BinaryReader.ReadInt16() - $Minute = $BinaryReader.ReadInt16() - $Second = $BinaryReader.ReadInt16() - $Millisecond = $BinaryReader.ReadInt16() + { $_ -like "Date*" } { + $BinaryReader = New-Object IO.BinaryReader (New-Object IO.MemoryStream (,$ValueContent)) - $BinaryReader.BaseStream.Dispose() - $BinaryReader.Dispose() + $Year = $BinaryReader.ReadInt16() + $Month = $BinaryReader.ReadInt16() + $null = $BinaryReader.ReadInt16() # skip week day + $Day = $BinaryReader.ReadInt16() + $Hour = $BinaryReader.ReadInt16() + $Minute = $BinaryReader.ReadInt16() + $Second = $BinaryReader.ReadInt16() + $Millisecond = $BinaryReader.ReadInt16() + + $BinaryReader.BaseStream.Dispose() + $BinaryReader.Dispose() - $Properties.Add($_.ValueName, [datetime]::new($Year, $Month, $Day, $Hour, $Minute, $Second, $Millisecond, [DateTimeKind]::Utc).ToString('o')) - } - elseif ($_.ValueName -eq 'NameType') { - $Type = switch ($_.ValueContent) { - 6 { 'Ethernet' } - 23 { 'VPN' } - 71 { 'WiFi' } + $Date = New-Object datetime -ArgumentList @($Year, $Month, $Day, $Hour, $Minute, $Second, $Millisecond, 'Utc') + + $Properties.Add($ValueName, $Date.ToString('o')) } - $Properties.Add('Type',$Type) + + 'NameType' { + $Type = switch ($ValueContent) { + 6 { 'Wired' } + 23 { 'VPN' } + 71 { 'Wireless' } + default { $ValueContent } + } + $Properties.Add('Type',$Type) + } + + 'Category' { + $Category = switch ($ValueContent) { + 0 { 'Public' } + 1 { 'Private' } + 2 { 'Domain' } + } + $Properties.Add('Category',$Category) + } + + 'Managed' { $Properties.Add('Managed', [bool]$ValueContent) } + + default { $Properties.Add($ValueName, $ValueContent) } } - else { $Properties.Add($_.ValueName, $_.ValueContent) } } [PSCustomObject]$Properties } diff --git a/CimSweep/ArtifactRetrieval/UserAssist.ps1 b/CimSweep/ArtifactRetrieval/UserAssist.ps1 index 87d918c..461ee93 100644 --- a/CimSweep/ArtifactRetrieval/UserAssist.ps1 +++ b/CimSweep/ArtifactRetrieval/UserAssist.ps1 @@ -91,10 +91,16 @@ Outputs objects consisting of relevant user assist information. Note: the LastEx default { $PlainCharList.Add($CipherChar) } # Pass through symbols and numbers } } + + $ValueContent = $_.ValueContent # Parse LastExecutedTime from binary data - $FileTime = [datetime]::FromFileTime([BitConverter]::ToInt64($_.ValueContent[60..67],0)) - + $FileTime = switch ($ValueContent.Count) { + 8 { [datetime]::MinValue } + 16 { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[8..15],0)) } + 72 { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[60..67],0)) } + } + [PSCustomObject]@{ PSTypeName = 'CimSweep.UserAssistEntry' Name = -join $PlainCharList From 7b53ca0bdeee056aa0e6bd211b5767353b69179e Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Wed, 24 May 2017 12:39:48 -0700 Subject: [PATCH 11/19] Live Tests Showed Errs - Fixed --- CimSweep/ArtifactRetrieval/AppCompatCache.ps1 | 5 +- CimSweep/ArtifactRetrieval/UserAssist.ps1 | 58 +++++++++---------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 index c418006..48d9c58 100644 --- a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 +++ b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 @@ -137,8 +137,7 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $OSArchitecture ) - $MemoryStream = New-Object IO.MemoryStream -ArgumentList @(,$CacheBytes) - $BinaryReader = New-Object IO.BinaryReader -ArgumentList $MemoryStream + $BinaryReader = New-Object IO.BinaryReader (New-Object IO.MemoryStream (,$CacheBytes)) $ASCIIEncoding = [Text.Encoding]::ASCII $UnicodeEncoding = [Text.Encoding]::Unicode @@ -324,8 +323,8 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch } until ($EntryPosition -eq $NumberOfEntries) } } + $BinaryReader.BaseStream.Dispose() $BinaryReader.Dispose() - $MemoryStream.Dispose() } Export-ModuleMember -Function Get-CSAppCompatCache \ No newline at end of file diff --git a/CimSweep/ArtifactRetrieval/UserAssist.ps1 b/CimSweep/ArtifactRetrieval/UserAssist.ps1 index 461ee93..d16b96c 100644 --- a/CimSweep/ArtifactRetrieval/UserAssist.ps1 +++ b/CimSweep/ArtifactRetrieval/UserAssist.ps1 @@ -75,42 +75,38 @@ Outputs objects consisting of relevant user assist information. Note: the LastEx Recurse = $true } - Get-CSRegistryKey @Parameters @CommonArgs | ForEach-Object { - if ($_.SubKey -like "*Count") { - Get-CSRegistryValue -Hive $_.Hive -SubKey $_.SubKey @CommonArgs | ForEach-Object { + Get-CSRegistryKey @Parameters @CommonArgs | Where-Object { $_.SubKey -like "*Count" } | Get-CSRegistryValue @CommonArgs | ForEach-Object { - # Decrypt Rot13 from https://github.com/StackCrash/PoshCiphers - # truncated && streamlined algorithm a little + # Decrypt Rot13 from https://github.com/StackCrash/PoshCiphers + # truncated && streamlined algorithm a little - $PlainCharList = New-Object Collections.Generic.List[char] - foreach ($CipherChar in $_.ValueName.ToCharArray()) { + $PlainCharList = New-Object Collections.Generic.List[char] + foreach ($CipherChar in $_.ValueName.ToCharArray()) { - switch ($CipherChar) { - { $_ -ge 65 -and $_ -le 90 } { $PlainCharList.Add((((($_ - 65 - 13) % 26 + 26) % 26) + 65)) } # Uppercase characters - { $_ -ge 97 -and $_ -le 122 } { $PlainCharList.Add((((($_ - 97 - 13) % 26 + 26) % 26) + 97)) } # Lowercase characters - default { $PlainCharList.Add($CipherChar) } # Pass through symbols and numbers - } - } - - $ValueContent = $_.ValueContent - - # Parse LastExecutedTime from binary data - $FileTime = switch ($ValueContent.Count) { - 8 { [datetime]::MinValue } - 16 { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[8..15],0)) } - 72 { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[60..67],0)) } - } - - [PSCustomObject]@{ - PSTypeName = 'CimSweep.UserAssistEntry' - Name = -join $PlainCharList - UserSid = $Sid - LastExecutedTime = $FileTime.ToUniversalTime().ToString('o') - } + switch ($CipherChar) { + { $_ -ge 65 -and $_ -le 90 } { $PlainCharList.Add((((($_ - 65 - 13) % 26 + 26) % 26) + 65)) } # Uppercase characters + { $_ -ge 97 -and $_ -le 122 } { $PlainCharList.Add((((($_ - 97 - 13) % 26 + 26) % 26) + 97)) } # Lowercase characters + default { $PlainCharList.Add($CipherChar) } # Pass through symbols and numbers } - } + } + + $ValueContent = $_.ValueContent + + # Parse LastExecutedTime from binary data + $FileTime = switch ($ValueContent.Count) { + 8 { [datetime]::MinValue } + 16 { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[8..15],0)) } + default { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[60..67],0)) } + } + + [PSCustomObject]@{ + PSTypeName = 'CimSweep.UserAssistEntry' + Name = -join $PlainCharList + UserSid = $Sid + LastExecutedTime = $FileTime.ToUniversalTime().ToString('o') + } } - } + } } } end {} From 6efc6094af47c22e0af3e41af3d1bc192b718cb0 Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Fri, 26 May 2017 10:17:39 -0700 Subject: [PATCH 12/19] Conformance to Matt's style --- CimSweep/ArtifactRetrieval/AppCompatCache.ps1 | 71 ++++++++++++++----- .../ArtifactRetrieval/NetworkProfiles.ps1 | 19 ++--- CimSweep/ArtifactRetrieval/UserAssist.ps1 | 7 +- 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 index 48d9c58..d1bbee2 100644 --- a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 +++ b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 @@ -81,9 +81,8 @@ Outputs objects consisting of the application's file path and that file's last m } } - $AppCompatCache = Get-CSRegistryValue @Parameters @CommonArgs - - ConvertFrom-ByteArray -CacheBytes $AppCompatCache.ValueContent -OSVersion $OS.Version -OSArchitecture $OS.OSArchitecture + $AppCompatCacheValue = Get-CSRegistryValue @Parameters @CommonArgs + ConvertFrom-ByteArray -CacheValue $AppCompatCacheValue -OSVersion $OS.Version -OSArchitecture $OS.OSArchitecture } } end {} @@ -105,7 +104,7 @@ Thanks to @ericrzimmerman for these test files https://github.com/EricZimmerman/ ConvertFrom-ByteArray converts bytes from the AppCompatCache registry key into objects. -.PARAMETER CacheBytes +.PARAMETER CacheValue Byte array from the AppCompatCache registry key. @@ -124,8 +123,8 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] - [byte[]] - $CacheBytes, + [Object] + $CacheValue, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] @@ -137,7 +136,7 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $OSArchitecture ) - $BinaryReader = New-Object IO.BinaryReader (New-Object IO.MemoryStream (,$CacheBytes)) + $BinaryReader = New-Object IO.BinaryReader (New-Object IO.MemoryStream (,$CacheValue.ValueContent)) $ASCIIEncoding = [Text.Encoding]::ASCII $UnicodeEncoding = [Text.Encoding]::Unicode @@ -162,11 +161,17 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - [PSCustomObject]@{ + $ObjectProperties = @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } + + [PSCustomObject]$ObjectProperties + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') } @@ -187,12 +192,18 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - - [PSCustomObject]@{ + + $ObjectProperties = @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } + + [PSCustomObject]$ObjectProperties + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') } @@ -212,12 +223,18 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - - [PSCustomObject]@{ + + $ObjectProperties = @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } + + [PSCustomObject]$ObjectProperties + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '00ts') } @@ -252,12 +269,18 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $Path = $UnicodeEncoding.GetString($BinaryReader.ReadBytes($PathSize)) $null = $BinaryReader.BaseStream.Seek($Position, [IO.SeekOrigin]::Begin) - - [PSCustomObject]@{ + + $ObjectProperties = @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } + + [PSCustomObject]$ObjectProperties + } until ($EntryPosition -eq $NumberOfEntries) } @@ -283,12 +306,18 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $Path = $UnicodeEncoding.GetString($BinaryReader.ReadBytes($PathSize)) $null = $BinaryReader.BaseStream.Seek($Position, [IO.SeekOrigin]::Begin) - - [PSCustomObject]@{ + + $ObjectProperties = @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } + + [PSCustomObject]$ObjectProperties + } until ($EntryPosition -eq $NumberOfEntries) } } @@ -314,12 +343,18 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch if (($LastModifiedTime.Year -eq 1600) -and !$Path) { break } # empty entries == end $null = $BinaryReader.BaseStream.Seek(16, [IO.SeekOrigin]::Current) # skip some bytes - - [PSCustomObject]@{ + + $ObjectProperties = @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } + + [PSCustomObject]$ObjectProperties + } until ($EntryPosition -eq $NumberOfEntries) } } diff --git a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 index aa78acf..b21d258 100644 --- a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 +++ b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 @@ -72,7 +72,7 @@ Outputs objects consisting of relevant network profile information. Note: the ti Get-CSRegistryKey @Parameters @CommonArgs | ForEach-Object { - $Properties = @{} + $ObjectProperties = @{} Get-CSRegistryValue -Hive $_.Hive -SubKey $_.SubKey @CommonArgs | ForEach-Object { @@ -98,34 +98,35 @@ Outputs objects consisting of relevant network profile information. Note: the ti $Date = New-Object datetime -ArgumentList @($Year, $Month, $Day, $Hour, $Minute, $Second, $Millisecond, 'Utc') - $Properties.Add($ValueName, $Date.ToString('o')) + $ObjectProperties[$ValueName] = $Date.ToString('o') } 'NameType' { - $Type = switch ($ValueContent) { + $ObjectProperties['Type'] = switch ($ValueContent) { 6 { 'Wired' } 23 { 'VPN' } 71 { 'Wireless' } default { $ValueContent } } - $Properties.Add('Type',$Type) } 'Category' { - $Category = switch ($ValueContent) { + $ObjectProperties['Category'] = switch ($ValueContent) { 0 { 'Public' } 1 { 'Private' } 2 { 'Domain' } } - $Properties.Add('Category',$Category) } - 'Managed' { $Properties.Add('Managed', [bool]$ValueContent) } + 'Managed' { $ObjectProperties['Managed'] = [bool]$ValueContent } - default { $Properties.Add($ValueName, $ValueContent) } + default { $ObjectProperties[$ValueName] = $ValueContent } } } - [PSCustomObject]$Properties + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } + if ($_.CimSession) { $ObjectProperties['CimSession'] = $_.CimSession } + + [PSCustomObject]$ObjectProperties } } } diff --git a/CimSweep/ArtifactRetrieval/UserAssist.ps1 b/CimSweep/ArtifactRetrieval/UserAssist.ps1 index d16b96c..5566a7f 100644 --- a/CimSweep/ArtifactRetrieval/UserAssist.ps1 +++ b/CimSweep/ArtifactRetrieval/UserAssist.ps1 @@ -99,12 +99,17 @@ Outputs objects consisting of relevant user assist information. Note: the LastEx default { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[60..67],0)) } } - [PSCustomObject]@{ + $ObjectProperties = @{ PSTypeName = 'CimSweep.UserAssistEntry' Name = -join $PlainCharList UserSid = $Sid LastExecutedTime = $FileTime.ToUniversalTime().ToString('o') } + + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } + if ($_.CimSession) { $ObjectProperties['CimSession'] = $_.CimSession } + + [PSCustomObject]$ObjectProperties } } } From 14d4ac66f377432d2943019c5ff1f227af8919fb Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Fri, 26 May 2017 11:09:43 -0700 Subject: [PATCH 13/19] Conforming to Matt's style --- CimSweep/ArtifactRetrieval/AppCompatCache.ps1 | 56 +++++-------------- .../ArtifactRetrieval/NetworkProfiles.ps1 | 6 +- CimSweep/ArtifactRetrieval/UserAssist.ps1 | 9 +-- 3 files changed, 18 insertions(+), 53 deletions(-) diff --git a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 index d1bbee2..dc8d630 100644 --- a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 +++ b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 @@ -160,18 +160,13 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - - $ObjectProperties = @{ + + [PSCustomObject] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + PSComputerName = $CacheValue.PSComputerName } - - if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } - if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } - - [PSCustomObject]$ObjectProperties - } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') } @@ -193,17 +188,12 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - $ObjectProperties = @{ + [PSCustomObject] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + PSComputerName = $CacheValue.PSComputerName } - - if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } - if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } - - [PSCustomObject]$ObjectProperties - } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') } @@ -224,17 +214,12 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - $ObjectProperties = @{ + [PSCustomObject] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + PSComputerName = $CacheValue.PSComputerName } - - if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } - if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } - - [PSCustomObject]$ObjectProperties - } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '00ts') } @@ -270,17 +255,12 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.BaseStream.Seek($Position, [IO.SeekOrigin]::Begin) - $ObjectProperties = @{ + [PSCustomObject] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + PSComputerName = $CacheValue.PSComputerName } - - if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } - if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } - - [PSCustomObject]$ObjectProperties - } until ($EntryPosition -eq $NumberOfEntries) } @@ -307,17 +287,12 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.BaseStream.Seek($Position, [IO.SeekOrigin]::Begin) - $ObjectProperties = @{ + [PSCustomObject] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + PSComputerName = $CacheValue.PSComputerName } - - if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } - if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } - - [PSCustomObject]$ObjectProperties - } until ($EntryPosition -eq $NumberOfEntries) } } @@ -344,17 +319,12 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.BaseStream.Seek(16, [IO.SeekOrigin]::Current) # skip some bytes - $ObjectProperties = @{ + [PSCustomObject] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') + PSComputerName = $CacheValue.PSComputerName } - - if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } - if ($CacheValue.CimSession) { $ObjectProperties['CimSession'] = $CacheValue.CimSession } - - [PSCustomObject]$ObjectProperties - } until ($EntryPosition -eq $NumberOfEntries) } } diff --git a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 index b21d258..4c29055 100644 --- a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 +++ b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 @@ -73,7 +73,8 @@ Outputs objects consisting of relevant network profile information. Note: the ti Get-CSRegistryKey @Parameters @CommonArgs | ForEach-Object { $ObjectProperties = @{} - + $ObjectProperties['PSComputerName'] = $_.PSComputerName + Get-CSRegistryValue -Hive $_.Hive -SubKey $_.SubKey @CommonArgs | ForEach-Object { $ValueName = $_.ValueName @@ -123,9 +124,6 @@ Outputs objects consisting of relevant network profile information. Note: the ti default { $ObjectProperties[$ValueName] = $ValueContent } } } - if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } - if ($_.CimSession) { $ObjectProperties['CimSession'] = $_.CimSession } - [PSCustomObject]$ObjectProperties } } diff --git a/CimSweep/ArtifactRetrieval/UserAssist.ps1 b/CimSweep/ArtifactRetrieval/UserAssist.ps1 index 5566a7f..3d1f712 100644 --- a/CimSweep/ArtifactRetrieval/UserAssist.ps1 +++ b/CimSweep/ArtifactRetrieval/UserAssist.ps1 @@ -99,17 +99,14 @@ Outputs objects consisting of relevant user assist information. Note: the LastEx default { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[60..67],0)) } } - $ObjectProperties = @{ + + [PSCustomObject] @{ PSTypeName = 'CimSweep.UserAssistEntry' Name = -join $PlainCharList UserSid = $Sid LastExecutedTime = $FileTime.ToUniversalTime().ToString('o') + PSComputerName = $_.PSComputerName } - - if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } - if ($_.CimSession) { $ObjectProperties['CimSession'] = $_.CimSession } - - [PSCustomObject]$ObjectProperties } } } From 3dce708e3a4c39d82e3ef2b81a25f4c702ed7b69 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Mon, 29 May 2017 06:29:04 -0700 Subject: [PATCH 14/19] Removing signed catalog until the next release cuts. --- CimSweep/CimSweep.cat | Bin 12655 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 CimSweep/CimSweep.cat diff --git a/CimSweep/CimSweep.cat b/CimSweep/CimSweep.cat deleted file mode 100644 index 84b5ae931cbb50c3af0f760a90759581cdf45013..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12655 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 From 2676fab7cb43eee862c7d59d9771079950bf244a Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Mon, 29 May 2017 06:29:52 -0700 Subject: [PATCH 15/19] Adding Get-CSEventLogPermission Used to audit potential ACL misconfigurations in event logs. --- CimSweep/Auditing/ACLAudits.ps1 | 139 +++++++++++++++++++++++++++++++- CimSweep/CimSweep.psd1 | 6 ++ 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/CimSweep/Auditing/ACLAudits.ps1 b/CimSweep/Auditing/ACLAudits.ps1 index 71c68f6..e255672 100644 --- a/CimSweep/Auditing/ACLAudits.ps1 +++ b/CimSweep/Auditing/ACLAudits.ps1 @@ -208,4 +208,141 @@ Service ACL sweep across a large amount of hosts will take a long time. } } -Export-ModuleMember -Function Get-CSVulnerableServicePermission \ No newline at end of file +function Get-CSEventLogPermission { +<# +.SYNOPSIS + +List event log permissions granted for each defined group. + +Author: Matthew Graeber (@mattifestation) +License: BSD 3-Clause + +.DESCRIPTION + +Get-CSEventLogPermission is used to perform event log ACL audits at scale. For each computer, it iterates through each event log security descriptor and groups potentially vulnerable access rights granted to each group. Event log security descriptors are stored in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels. + +.PARAMETER CimSession + +Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. + +.EXAMPLE + +Get-CSEventLogPermission + +.OUTPUTS + +CimSweep.EventLogACLAudit + +Outputs objects representing each group granted event log access rights. + +.NOTES + +Event log ACL sweep across a large amount of hosts will take a long time. +#> + + [CmdletBinding()] + [OutputType('CimSweep.EventLogACLAudit')] + param ( + [Alias('Session')] + [ValidateNotNullOrEmpty()] + [Microsoft.Management.Infrastructure.CimSession[]] + $CimSession + ) + + BEGIN { + if (-not $PSBoundParameters['CimSession']) { + $CimSession = '' + $CIMSessionCount = 1 + } else { + $CIMSessionCount = $CimSession.Count + } + + $CurrentCIMSession = 0 + } + + PROCESS { + foreach ($Session in $CimSession) { + $ComputerName = $Session.ComputerName + if (-not $Session.ComputerName) { $ComputerName = 'localhost' } + + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Event log ACL sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ + + $CommonArgs = @{} + + if ($Session.Id) { $CommonArgs['CimSession'] = $Session } + + $UserGrouping = @{} + + $EventChannels = Get-CSRegistryKey -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels' @CommonArgs + + $ChannelCount = $EventChannels.Count + $CurrentChannelCount = 0 + + $EventChannels | Get-CSRegistryValue -ValueName ChannelAccess @CommonArgs | ForEach-Object { + $ChannelName = $_.Subkey.Split('\')[-1] + + Write-Progress -Id 2 -ParentId 1 -Activity "Current event channel:" -Status $ChannelName -PercentComplete (($CurrentChannelCount / $ChannelCount) * 100) + + $CurrentChannelCount++ + + $AccessString = $_.ValueContent + $SecurityDescriptor = ConvertFrom-SddlString -Sddl $AccessString + + foreach ($ACE in $SecurityDescriptor.RawDescriptor.DiscretionaryAcl) { + if ($ACE.AceQualifier -eq [Security.AccessControl.AceQualifier]::AccessAllowed) { + $Account = $null + + $SID = [Security.Principal.SecurityIdentifier] $ACE.SecurityIdentifier + + try { $Account = $SID.Translate([Security.Principal.NTAccount]).ToString() } catch { + $Account = $ACE.SecurityIdentifier + } + + if (-not $UserGrouping.ContainsKey($Account)) { + $Permissions = [PSCustomObject] @{ + EventCanRead = (New-Object 'Collections.ObjectModel.Collection`1[System.String]') + EventCanWrite = (New-Object 'Collections.ObjectModel.Collection`1[System.String]') + EventCanClear = (New-Object 'Collections.ObjectModel.Collection`1[System.String]') + EventCanWriteDAC = (New-Object 'Collections.ObjectModel.Collection`1[System.String]') + EventCanWriteOwner = (New-Object 'Collections.ObjectModel.Collection`1[System.String]') + } + } else { + $Permissions = $UserGrouping[$Account] + } + + $UserGrouping[$Account] = $Permissions + + if (($ACE.AccessMask -band 1) -eq 1) { $UserGrouping[$Account].EventCanRead.Add($ChannelName) } + if (($ACE.AccessMask -band 2) -eq 2) { $UserGrouping[$Account].EventCanWrite.Add($ChannelName) } + if (($ACE.AccessMask -band 4) -eq 4) { $UserGrouping[$Account].EventCanClear.Add($ChannelName) } + if (($ACE.AccessMask -band 0x00040000) -eq 0x00040000) { $UserGrouping[$Account].EventCanWriteDAC.Add($ChannelName) } + if (($ACE.AccessMask -band 0x00080000) -eq 0x00080000) { $UserGrouping[$Account].EventCanWriteOwner.Add($ChannelName) } + } + } + } + + foreach ($Group in $UserGrouping.Keys) { + $Permissions = $UserGrouping[$Group] + + $ObjectProperties = [Ordered] @{ + PSTypeName = 'CimSweep.EventLogACLAudit' + GroupName = $Group + EventCanRead = $Permissions.EventCanRead + EventCanWrite = $Permissions.EventCanWrite + EventCanClear = $Permissions.EventCanClear + EventCanWriteDAC = $Permissions.EventCanWriteDAC + EventCanWriteOwner = $Permissions.EventCanWriteOwner + } + + if ($Session.ComputerName) { $ObjectProperties['PSComputerName'] = $Session.ComputerName } + + [PSCustomObject] $ObjectProperties + } + } + } +} + +Export-ModuleMember -Function 'Get-CSVulnerableServicePermission', + 'Get-CSEventLogPermission' \ No newline at end of file diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index d057c61..74308ff 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -34,6 +34,7 @@ FunctionsToExport = @( 'Get-CSWmiPersistence', 'Get-CSWmiNamespace', 'Get-CSVulnerableServicePermission', + 'Get-CSEventLogPermission', 'Get-CSAVInfo', 'Get-CSProxyConfig', 'Get-CSInstalledAppCompatShimDatabase', @@ -51,6 +52,11 @@ PrivateData = @{ ProjectUri = 'https://github.com/PowerShellMafia/CimSweep' ReleaseNotes = @' +0.6.1 +----- +Enhacements: +* Add Get-CSEventLogPermission + 0.6.0 ----- Enhancements: From 146f07b4bb18dc692549734a40d46210e6d53d66 Mon Sep 17 00:00:00 2001 From: Jesse Davis Date: Tue, 30 May 2017 10:26:26 -0700 Subject: [PATCH 16/19] Still need to parse AppX Values --- CimSweep/ArtifactRetrieval/AppCompatCache.ps1 | 44 +++++++++++++------ .../ArtifactRetrieval/NetworkProfiles.ps1 | 30 ++++++++++--- CimSweep/ArtifactRetrieval/UserAssist.ps1 | 9 ++-- 3 files changed, 59 insertions(+), 24 deletions(-) diff --git a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 index dc8d630..b189aa5 100644 --- a/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 +++ b/CimSweep/ArtifactRetrieval/AppCompatCache.ps1 @@ -161,12 +161,15 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - [PSCustomObject] @{ + $ObjectProperties = [ordered] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') - PSComputerName = $CacheValue.PSComputerName } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + [PSCustomObject]$ObjectProperties + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') } @@ -187,13 +190,16 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $LastModifiedTime = [DateTimeOffset]::FromFileTime($BinaryReader.ReadInt64()).DateTime $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - - [PSCustomObject] @{ + + $ObjectProperties = [ordered] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') - PSComputerName = $CacheValue.PSComputerName } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + [PSCustomObject]$ObjectProperties + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '10ts') } @@ -214,12 +220,15 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.ReadBytes($BinaryReader.ReadInt32()) # skip some bytes - [PSCustomObject] @{ + $ObjectProperties = [ordered] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') - PSComputerName = $CacheValue.PSComputerName } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + [PSCustomObject]$ObjectProperties + } until ($ASCIIEncoding.GetString($BinaryReader.ReadBytes(4)) -ne '00ts') } @@ -255,12 +264,15 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.BaseStream.Seek($Position, [IO.SeekOrigin]::Begin) - [PSCustomObject] @{ + $ObjectProperties = [ordered] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') - PSComputerName = $CacheValue.PSComputerName } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + [PSCustomObject]$ObjectProperties + } until ($EntryPosition -eq $NumberOfEntries) } @@ -287,12 +299,15 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.BaseStream.Seek($Position, [IO.SeekOrigin]::Begin) - [PSCustomObject] @{ + $ObjectProperties = [ordered] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') - PSComputerName = $CacheValue.PSComputerName } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + [PSCustomObject]$ObjectProperties + } until ($EntryPosition -eq $NumberOfEntries) } } @@ -319,12 +334,15 @@ ConvertFrom-ByteArray -CacheBytes $AppCompatCacheKeyBytes -OSVersion 6.1 -OSArch $null = $BinaryReader.BaseStream.Seek(16, [IO.SeekOrigin]::Current) # skip some bytes - [PSCustomObject] @{ + $ObjectProperties = [ordered] @{ PSTypeName = 'CimSweep.AppCompatCacheEntry' Path = $Path LastModifiedTime = $LastModifiedTime.ToUniversalTime().ToString('o') - PSComputerName = $CacheValue.PSComputerName } + + if ($CacheValue.PSComputerName) { $ObjectProperties['PSComputerName'] = $CacheValue.PSComputerName } + [PSCustomObject]$ObjectProperties + } until ($EntryPosition -eq $NumberOfEntries) } } diff --git a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 index 4c29055..b361550 100644 --- a/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 +++ b/CimSweep/ArtifactRetrieval/NetworkProfiles.ps1 @@ -64,7 +64,22 @@ Outputs objects consisting of relevant network profile information. Note: the ti $CommonArgs = @{} if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - + + $Parameters = @{ + Hive = 'HKLM' + SubKey = 'SYSTEM\CurrentControlSet\Control\TimeZoneInformation' + ValueName = 'TimeZoneKeyName' + ValueType = 'REG_SZ' + } + + $TimeZoneName = Get-CSRegistryValue @Parameters @CommonArgs + + # TimeZoneKeyName doesn't exist on XP, but CimSweep still returns an object as though it did + # NetworkList also doesn't exist on XP, so might as well bail now. + + try { $TimeZoneInfo = [TimeZoneInfo]::FindSystemTimeZoneById($TimeZoneName.ValueContent) } + catch { break } + $Parameters = @{ Hive = 'HKLM' SubKey = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles' @@ -72,8 +87,7 @@ Outputs objects consisting of relevant network profile information. Note: the ti Get-CSRegistryKey @Parameters @CommonArgs | ForEach-Object { - $ObjectProperties = @{} - $ObjectProperties['PSComputerName'] = $_.PSComputerName + $ObjectProperties = [ordered] @{ PSTypeName = 'CimSweep.NetworkProfile' } Get-CSRegistryValue -Hive $_.Hive -SubKey $_.SubKey @CommonArgs | ForEach-Object { @@ -94,12 +108,13 @@ Outputs objects consisting of relevant network profile information. Note: the ti $Second = $BinaryReader.ReadInt16() $Millisecond = $BinaryReader.ReadInt16() - $BinaryReader.BaseStream.Dispose() $BinaryReader.Dispose() - $Date = New-Object datetime -ArgumentList @($Year, $Month, $Day, $Hour, $Minute, $Second, $Millisecond, 'Utc') - - $ObjectProperties[$ValueName] = $Date.ToString('o') + # dates are stored in local timezone + $DateTime = New-Object datetime -ArgumentList @($Year, $Month, $Day, $Hour, $Minute, $Second, $Millisecond, 'Unspecified') + $CorrectedTime = [TimeZoneInfo]::ConvertTimeToUtc($DateTime, $TimeZoneInfo) + + $ObjectProperties[$ValueName] = $CorrectedTime.ToString('o') } 'NameType' { @@ -124,6 +139,7 @@ Outputs objects consisting of relevant network profile information. Note: the ti default { $ObjectProperties[$ValueName] = $ValueContent } } } + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } [PSCustomObject]$ObjectProperties } } diff --git a/CimSweep/ArtifactRetrieval/UserAssist.ps1 b/CimSweep/ArtifactRetrieval/UserAssist.ps1 index 3d1f712..603bff1 100644 --- a/CimSweep/ArtifactRetrieval/UserAssist.ps1 +++ b/CimSweep/ArtifactRetrieval/UserAssist.ps1 @@ -94,19 +94,20 @@ Outputs objects consisting of relevant user assist information. Note: the LastEx # Parse LastExecutedTime from binary data $FileTime = switch ($ValueContent.Count) { - 8 { [datetime]::MinValue } + 8 { [datetime]::FromFileTime(0) } 16 { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[8..15],0)) } default { [datetime]::FromFileTime([BitConverter]::ToInt64($ValueContent[60..67],0)) } } - - [PSCustomObject] @{ + $ObjectProperties = [ordered] @{ PSTypeName = 'CimSweep.UserAssistEntry' Name = -join $PlainCharList UserSid = $Sid LastExecutedTime = $FileTime.ToUniversalTime().ToString('o') - PSComputerName = $_.PSComputerName } + + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } + [PSCustomObject]$ObjectProperties } } } From f5ec320d94452efebbc1741076ceecf0d6f43b19 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Thu, 1 Jun 2017 08:55:22 -0700 Subject: [PATCH 17/19] Updating manifest to reflect new CimSweep additions. --- CimSweep/CimSweep.psd1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index 367d1ee..fc27d83 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -57,8 +57,9 @@ PrivateData = @{ ReleaseNotes = @' 0.6.1 ----- -Enhacements: -* Add Get-CSEventLogPermission +Enhancements: +* Added Get-CSEventLogPermission +* Added the following from @secabstraction: Get-CSAppCompatCache, Get-CSNetworkProfile, Get-CSUserAssist 0.6.0 ----- From 2f7a8043d4fffb67d25ead46c0b015499b0f1a3e Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Thu, 8 Jun 2017 08:15:29 -0700 Subject: [PATCH 18/19] Bugfix: Remove PSv4 language dependency Addresses #26 --- CimSweep/CimSweep.psd1 | 5 +++-- CimSweep/Core/CoreFunctions.ps1 | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index fc27d83..bc028df 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -1,7 +1,7 @@ @{ RootModule = 'CimSweep.psm1' -ModuleVersion = '0.6.0.0' +ModuleVersion = '0.6.1.1' GUID = 'f347ef1c-d752-4d07-bf68-3197c0aa661a' @@ -60,6 +60,7 @@ PrivateData = @{ Enhancements: * Added Get-CSEventLogPermission * Added the following from @secabstraction: Get-CSAppCompatCache, Get-CSNetworkProfile, Get-CSUserAssist +* Bugfix: Removed .ForEach PSv4 language dependency 0.6.0 ----- @@ -105,7 +106,7 @@ Removed: 0.4.1 ----- -* Bigfix: Forgot to rename Set-DefaultDisplayProperty in Get-CSRegistryAutoStart. +* Bugfix: Forgot to rename Set-DefaultDisplayProperty in Get-CSRegistryAutoStart. * Enhancement: Addressed PSScriptAnalyzer warnings 0.4.0 diff --git a/CimSweep/Core/CoreFunctions.ps1 b/CimSweep/Core/CoreFunctions.ps1 index 63460bf..55e8ba8 100644 --- a/CimSweep/Core/CoreFunctions.ps1 +++ b/CimSweep/Core/CoreFunctions.ps1 @@ -469,7 +469,7 @@ Outputs a list of objects representing registry value names, their respective ty # Only progress if EnumValues returns actual value and type data if ($Result.Types.Length) { - $Types = $Result.Types.ForEach({$Type[$_]}) + $Types = foreach ($Value in $Result.Types) { $Type[$Value] } $ValueNames = $Result.sNames From b1f17c0f9d981e417d9b10e3fd02a8c84b7711dd Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Thu, 8 Jun 2017 08:21:10 -0700 Subject: [PATCH 19/19] Renaming Get-CSVulnerableServicePermission to Get-CSServicePermission --- CimSweep/Auditing/ACLAudits.ps1 | 8 ++++---- CimSweep/CimSweep.psd1 | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CimSweep/Auditing/ACLAudits.ps1 b/CimSweep/Auditing/ACLAudits.ps1 index e255672..2fa37c1 100644 --- a/CimSweep/Auditing/ACLAudits.ps1 +++ b/CimSweep/Auditing/ACLAudits.ps1 @@ -1,4 +1,4 @@ -function Get-CSVulnerableServicePermission { +function Get-CSServicePermission { <# .SYNOPSIS @@ -9,7 +9,7 @@ License: BSD 3-Clause .DESCRIPTION -Get-CSVulnerableServicePermission is used to perform service ACL audits at scale. For each computer, it iterates through the service and associated file permissions and groups potentially vulnerable access rights granted to each user. This can be used to quickly identify if members of lower privileged groups can elevate privileges via service misconfigurations. +Get-CSServicePermission is used to perform service ACL audits at scale. For each computer, it iterates through the service and associated file permissions and groups potentially vulnerable access rights granted to each user. This can be used to quickly identify if members of lower privileged groups can elevate privileges via service misconfigurations. .PARAMETER IncludeDrivers @@ -21,7 +21,7 @@ Specifies the CIM session to use for this cmdlet. Enter a variable that contains .EXAMPLE -Get-CSVulnerableServicePermission +Get-CSServicePermission Returns a list of groups and the services to which they are granted access to perform potentially vulnerable actions. @@ -344,5 +344,5 @@ Event log ACL sweep across a large amount of hosts will take a long time. } } -Export-ModuleMember -Function 'Get-CSVulnerableServicePermission', +Export-ModuleMember -Function 'Get-CSServicePermission', 'Get-CSEventLogPermission' \ No newline at end of file diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index bc028df..cfc0b75 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -33,7 +33,7 @@ FunctionsToExport = @( 'Get-CSTypedURL', 'Get-CSWmiPersistence', 'Get-CSWmiNamespace', - 'Get-CSVulnerableServicePermission', + 'Get-CSServicePermission', 'Get-CSEventLogPermission', 'Get-CSAVInfo', 'Get-CSProxyConfig', @@ -61,6 +61,7 @@ Enhancements: * Added Get-CSEventLogPermission * Added the following from @secabstraction: Get-CSAppCompatCache, Get-CSNetworkProfile, Get-CSUserAssist * Bugfix: Removed .ForEach PSv4 language dependency +* Renamed Get-CSVulnerableServicePermission to Get-CSServicePermission 0.6.0 -----