Private/Kinds/NetworkDependencyElevated.ps1
|
# The NetworkDependencyElevated Kind: where the running processes are from, and the # modules they loaded that are not on the machine's own drives, read with admin rights. # # The NetworkDependency Kind runs in the Main Part, where the drives of the person at the # machine are known, and may not open a process of the system or of another account: its # program path stays unread, and so do the modules of every process that hosts a service. # A Report then said "not examined ... only readable with admin rights" of a Run that had # them. This Kind reads the same with admin rights and judges nothing: the # NetworkDependency Check is handed its reading as $Observed['NetworkDependencyElevated'] # and fills in what it could not read itself. # # It places nothing. The Elevated Part has its own logon and does not know what K: is, so # a path is kept as the process has it and the Check in the Main Part resolves it. # # Its one Finding says that the reading was taken, so that the Check is accounted for in # the Report like any other. $script:NetworkDependencyElevatedNeedsAdmin = $true # What Get-NetworkDependencyElevatedData hands its Judge. See Private/DataShape.ps1. $script:NetworkDependencyElevatedDataShape = @{ Processes = 'List' ModuleTraces = 'List' ModuleUnexamined = 'List' } function Get-NetworkDependencyElevatedData { <# .SYNOPSIS Every running process with where its program is, and the modules they loaded from anywhere but the machine's own drives, as an administrator may read them. Decides nothing. #> [CmdletBinding()] [OutputType([psobject])] param([hashtable]$Parameters = @{}) $processes = @(Get-Process -ErrorAction SilentlyContinue | ForEach-Object { $path = $null try { $path = $_.Path } catch { } [pscustomobject]@{ Name = "$($_.ProcessName)"; Id = [int]$_.Id; SessionId = [int]$_.SessionId; Path = "$path" } }) # Every process, and not only those that host a service: with admin rights all of them # can be opened, and the Main Part asks for the ones it could not. $ids = @($processes | ForEach-Object { $_.Id } | Sort-Object -Unique) # An administrator may open any process, but Windows hands that right out switched # off (SeDebugPrivilege): without it the processes of the system refuse an # administrator as they refuse anybody. A Run with admin rights was refused 126 # service processes that way. Switched on for this reading and off again after it; # what is still refused then, Windows protects from administrators too. $debug = $false try { [System.Diagnostics.Process]::EnterDebugMode(); $debug = $true } catch { } try { $read = ConvertTo-NetworkDependencyModuleTrace -LocalDrive @(Get-NetworkDependencyDriveLetter) ` -ProcessModule @(Get-NetworkDependencyProcessModule -ServiceProcessId $ids) } finally { if ($debug) { try { [System.Diagnostics.Process]::LeaveDebugMode() } catch { } } } [pscustomobject]@{ PSTypeName = 'Gutcheck.Data.NetworkDependencyElevated' Processes = $processes ModuleTraces = @($read.Traces) # What even an administrator could not open: a protected process of Windows. ModuleUnexamined = @($read.Unexamined) } } function ConvertTo-NetworkDependencyElevatedFinding { <# .SYNOPSIS One Finding saying how much was read with admin rights. Pure. .DESCRIPTION No judgement: what a program depends on is the NetworkDependency Check's to say. #> [CmdletBinding()] [OutputType([psobject])] param([AllowNull()]$Data, [hashtable]$Parameters = @{}) $processes = @((Get-DataCollection $Data 'Processes') | ForEach-Object { $_ }) if (-not $processes.Count) { return New-UnavailableFinding -Category Network -Check (Get-Text 'Check.NetworkDependencyElevated.Reading') ` -Hint (Get-Text 'Hint.Program.NothingRead') } $withPath = @($processes | Where-Object { "$(Get-DataProperty $_ 'Path')" }).Count New-Finding -Category Network -Check (Get-Text 'Check.NetworkDependencyElevated.Reading') -Severity OK ` -Value ((Get-Text 'Value.NetworkDependencyElevated.Reading') -f $processes.Count, $withPath, (Get-DataCollection $Data 'ModuleTraces').Count) } |