From b568271d57be6d850906a8c14d5222b81c477daa Mon Sep 17 00:00:00 2001 From: Harmj0y Date: Sun, 22 May 2016 14:07:37 -0400 Subject: Get-LoggedOnLocal now handles the situation when multiple SIDs are returned Get-LoggedOnLocal turned into a filter and given additional error handling Standardized tab/line spacing Removed Invoke-PSLoggedOn --- Recon/PowerView.ps1 | 134 +++++++++++++--------------------------------------- 1 file changed, 33 insertions(+), 101 deletions(-) (limited to 'Recon/PowerView.ps1') diff --git a/Recon/PowerView.ps1 b/Recon/PowerView.ps1 index c10cbed..6ad1c9d 100755 --- a/Recon/PowerView.ps1 +++ b/Recon/PowerView.ps1 @@ -8147,25 +8147,23 @@ filter Get-NetSession { } -function Get-LoggedOnLocal { +filter Get-LoggedOnLocal { <# .SYNOPSIS This function will query the HKU registry values to retrieve the local logged on users SID and then attempt and reverse it. Adapted technique from Sysinternal's PSLoggedOn script. Benefit over - using the NetWkstaUserEnum API (Get-NetLoggedon) of less user privileges - required (NetWkstaUserEnum requires remote admin access). + using the NetWkstaUserEnum API (Get-NetLoggedon) of less user privileges + required (NetWkstaUserEnum requires remote admin access). - Note: This function requires only domain user rights on the - machine you're enumerating. - - Function: Get-LoggedOnLocal - Author: Matt Kelly, @BreakersAll; - Required Dependencies: @harmj0y's Powerview. - - .PARAMETER ComputerName + machine you're enumerating, but remote registry must be enabled. + + Function: Get-LoggedOnLocal + Author: Matt Kelly, @BreakersAll + + .PARAMETER ComputerName The ComputerName to query for active sessions. @@ -8187,105 +8185,39 @@ function Get-LoggedOnLocal { param( [Parameter(ValueFromPipeline=$True)] [Alias('HostName')] - [String] + [Object[]] + [ValidateNotNullOrEmpty()] $ComputerName = 'localhost' ) - begin { - if ($PSBoundParameters['Debug']) { - $DebugPreference = 'Continue' - } - } - - process { - - # process multiple host object types from the pipeline - $ComputerName = Get-NameField -Object $ComputerName - # retrieve HKU remote registry values - $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('Users', "$ComputerName") - - # sort out bogus sid's like _class - $UserSID = $Reg.GetSubKeyNames() | ? { $_ -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' } - - # if successful, convert sid and print output - if ($UserSID) { - $UserName = Convert-SidToName $UserSID - - $LocalLoggedOnUser = New-Object PSObject - $LocalLoggedOnUser | Add-Member Noteproperty 'ComputerName' $ComputerName - $LocalLoggedOnUser | Add-Member Noteproperty 'UserName' $UserName - $LocalLoggedOnUser | Add-Member Noteproperty 'UserSID' $UserSID - $LocalLoggedOnUser - } - else { - Write-Debug "Could not retrieve values for $ComputerName" - } - - Write-Debug "UserSIDs retrieved result: $Reg.GetSubKeyNames()" - } -} - - -function Invoke-PSLoggedOn { -<# - .SYNOPSIS - - This function replicates PSLoggedOn functionality, and leverages - Get-NetSession (netsessionenum) and remote registry values. - Same actions as PSLoggedOn except in PowerShell. - - Note: This function requires only domain user rights on the - machine you're enumerating. - - Function: Invoke-PSLoggedOn - Author: Matt Kelly, @BreakersAll; - Required Dependencies: PowerView. PSv2 - - .PARAMETER ComputerName - - The ComputerName to query for active sessions. - - .EXAMPLE - - PS C:\> Invoke-PSLoggedOn - - Returns active sessions on the local host. + # process multiple host object types from the pipeline + $ComputerName = Get-NameField -Object $ComputerName - .EXAMPLE + try { + # retrieve HKU remote registry values + $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('Users', "$ComputerName") - PS C:\> Invoke-PSLoggedOn -ComputerName sqlserver + # sort out bogus sid's like _class + $Reg.GetSubKeyNames() | Where-Object { $_ -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' } | ForEach-Object { + $UserName = Convert-SidToName $_ - Returns active sessions on the 'sqlserver' host. - -#> + $Parts = $UserName.Split('\') + $UserDomain = $Null + $UserName = $Parts[-1] + if ($Parts.Length -eq 2) { + $UserDomain = $Parts[0] + } - [CmdletBinding()] - param( - [Parameter(ValueFromPipeline=$True)] - [Alias('HostName')] - [String] - $ComputerName = 'localhost' - ) - - begin { - if ($PSBoundParameters['Debug']) { - $DebugPreference = 'Continue' + $LocalLoggedOnUser = New-Object PSObject + $LocalLoggedOnUser | Add-Member Noteproperty 'ComputerName' "$ComputerName" + $LocalLoggedOnUser | Add-Member Noteproperty 'UserDomain' $UserDomain + $LocalLoggedOnUser | Add-Member Noteproperty 'UserName' $UserName + $LocalLoggedOnUser | Add-Member Noteproperty 'UserSID' $_ + $LocalLoggedOnUser } } - - process { - - # process multiple host object types from the pipeline - $ComputerName = Get-NameField -Object $ComputerName - - $LoggedOnLocal = Get-LoggedOnLocal $ComputerName - $NetSessionUsers = Get-NetSession $ComputerName - - Write-Host "Users logged on locally to $ComputerName:" - $LoggedOnLocal - Write-Host "" - Write-Host "Users logged on via resource shares to $ComputerName:" - $NetSessionUsers + catch { + Write-Verbose "Error opening remote registry on '$ComputerName'" } } -- cgit v1.2.3