4104132150x02372886Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local4141 = field 0 UInt32 State = field 1 $WTSConnectState SessionId = field 2 UInt32 pSessionName = field 3 String -MarshalAs @('LPWStr') pHostName = field 4 String -MarshalAs @('LPWStr') pUserName = field 5 String -MarshalAs @('LPWStr') pDomainName = field 6 String -MarshalAs @('LPWStr') pFarmName = field 7 String -MarshalAs @('LPWStr') } # the particular WTSQuerySessionInformation result structure $WTS_CLIENT_ADDRESS = struct $mod WTS_CLIENT_ADDRESS @{ AddressFamily = field 0 UInt32 Address = field 1 Byte[] -MarshalAs @('ByValArray', 20) } # the NetShareEnum result structure $SHARE_INFO_1 = struct $Mod PowerView.ShareInfo @{ Name = field 0 String -MarshalAs @('LPWStr') Type = field 1 UInt32 Remark = field 2 String -MarshalAs @('LPWStr') } # the NetWkstaUserEnum result structure $WKSTA_USER_INFO_1 = struct $Mod PowerView.LoggedOnUserInfo @{ UserName = field 0 String -MarshalAs @('LPWStr') LogonDomain = field 1 String -MarshalAs @('LPWStr') AuthDomains = field 2 String -MarshalAs @('LPWStr') LogonServer = field 3 String -MarshalAs @('LPWStr') } # the NetSessionEnum result structure $SESSION_INFO_10 = struct $Mod PowerView.SessionInfo @{ CName = field 0 String -MarshalAs @('LPWStr') UserName = field 1 String -MarshalAs @('LPWStr') Time = field 2 UInt32 IdleTime = field 3 UInt32 } # enum used by $LOCALGROUP_MEMBERS_INFO_2 below $SID_NAME_USE = psenum $Mod SID_NAME_USE UInt16 @{ SidTypeUser = 1 SidTypeGroup = 2 SidTypeDomain = 3 SidTypeAlias = 4 SidTypeWellKnownGroup = 5 SidTypeDeletedAccount = 6 SidTypeInvalid = 7 SidTypeUnknown = 8 SidTypeComputer = 9 } # the NetLocalGroupEnum result structure $LOCALGROUP_INFO_1 = struct $Mod LOCALGROUP_INFO_1 @{ lgrpi1_name = field 0 String -MarshalAs @('LPWStr') lgrpi1_comment = field 1 String -MarshalAs @('LPWStr') } # the NetLocalGroupGetMembers result structure $LOCALGROUP_MEMBERS_INFO_2 = struct $Mod LOCALGROUP_MEMBERS_INFO_2 @{ lgrmi2_sid = field 0 IntPtr lgrmi2_sidusage = field 1 $SID_NAME_USE lgrmi2_domainandname = field 2 String -MarshalAs @('LPWStr') } # enums used in DS_DOMAIN_TRUSTS $DsDomainFlag = psenum $Mod DsDomain.Flags UInt32 @{ IN_FOREST = 1 DIRECT_OUTBOUND = 2 TREE_ROOT = 4 PRIMARY = 8 NATIVE_MODE = 16 DIRECT_INBOUND = 32 } -Bitfield $DsDomainTrustType = psenum $Mod DsDomain.TrustType UInt32 @{ DOWNLEVEL = 1 UPLEVEL = 2 MIT = 3 DCE = 4 } $DsDomainTrustAttributes = psenum $Mod DsDomain.TrustAttributes UInt32 @{ NON_TRANSITIVE = 1 UPLEVEL_ONLY = 2 FILTER_SIDS = 4 FOREST_TRANSITIVE = 8 CROSS_ORGANIZATION = 16 WITHIN_FOREST = 32 TREAT_AS_EXTERNAL = 64 } # the DsEnumerateDomainTrusts result structure $DS_DOMAIN_TRUSTS = struct $Mod DS_DOMAIN_TRUSTS @{ NetbiosDomainName = field 0 String -MarshalAs @('LPWStr') DnsDomainName = field 1 String -MarshalAs @('LPWStr') Flags = field 2 $DsDomainFlag ParentIndex = field 3 UInt32 TrustType = field 4 $DsDomainTrustType TrustAttributes = field 5 $DsDomainTrustAttributes DomainSid = field 6 IntPtr DomainGuid = field 7 Guid } # used by WNetAddConnection2W $NETRESOURCEW = struct $Mod NETRESOURCEW @{ dwScope = field 0 UInt32 dwType = field 1 UInt32 dwDisplayType = field 2 UInt32 dwUsage = field 3 UInt32 lpLocalName = field 4 String -MarshalAs @('LPWStr') lpRemoteName = field 5 String -MarshalAs @('LPWStr') lpComment = field 6 String -MarshalAs @('LPWStr') lpProvider = field 7 String -MarshalAs @('LPWStr') } # all of the Win32 API functions we need $FunctionDefinitions = @( (func netapi32 NetShareEnum ([Int]) @([String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), (func netapi32 NetWkstaUserEnum ([Int]) @([String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), (func netapi32 NetSessionEnum ([Int]) @([String], [String], [String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), (func netapi32 NetLocalGroupEnum ([Int]) @([String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), (func netapi32 NetLocalGroupGetMembers ([Int]) @([String], [String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), (func netapi32 DsGetSiteName ([Int]) @([String], [IntPtr].MakeByRefType())), (func netapi32 DsEnumerateDomainTrusts ([Int]) @([String], [UInt32], [IntPtr].MakeByRefType(), [IntPtr].MakeByRefType())), (func netapi32 NetApiBufferFree ([Int]) @([IntPtr])), (func advapi32 ConvertSidToStringSid ([Int]) @([IntPtr], [String].MakeByRefType()) -SetLastError), (func advapi32 OpenSCManagerW ([IntPtr]) @([String], [String], [Int]) -SetLastError), (func advapi32 CloseServiceHandle ([Int]) @([IntPtr])), (func advapi32 LogonUser ([Bool]) @([String], [String], [String], [UInt32], [UInt32], [IntPtr].MakeByRefType()) -SetLastError), (func advapi32 ImpersonateLoggedOnUser ([Bool]) @([IntPtr]) -SetLastError), (func advapi32 RevertToSelf ([Bool]) @() -SetLastError), (func wtsapi32 WTSOpenServerEx ([IntPtr]) @([String])), (func wtsapi32 WTSEnumerateSessionsEx ([Int]) @([IntPtr], [Int32].MakeByRefType(), [Int], [IntPtr].MakeByRefType(), [Int32].MakeByRefType()) -SetLastError), (func wtsapi32 WTSQuerySessionInformation ([Int]) @([IntPtr], [Int], [Int], [IntPtr].MakeByRefType(), [Int32].MakeByRefType()) -SetLastError), (func wtsapi32 WTSFreeMemoryEx ([Int]) @([Int32], [IntPtr], [Int32])), (func wtsapi32 WTSFreeMemory ([Int]) @([IntPtr])), (func wtsapi32 WTSCloseServer ([Int]) @([IntPtr])), (func Mpr WNetAddConnection2W ([Int]) @($NETRESOURCEW, [String], [String], [UInt32])), (func Mpr WNetCancelConnection2 ([Int]) @([String], [Int], [Bool])), (func kernel32 CloseHandle ([Bool]) @([IntPtr]) -SetLastError) ) $Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32' $Netapi32 = $Types['netapi32'] $Advapi32 = $Types['advapi32'] $Wtsapi32 = $Types['wtsapi32'] $Mpr = $Types['Mpr'] $Kernel32 = $Types['kernel32'] Set-Alias Get-IPAddress Resolve-IPAddress Set-Alias Convert-NameToSid ConvertTo-SID Set-Alias Convert-SidToName ConvertFrom-SID Set-Alias Request-SPNTicket Get-DomainSPNTicket Set-Alias Get-DNSZone Get-DomainDNSZone Set-Alias Get-DNSRecord Get-DomainDNSRecord Set-Alias Get-NetDomain Get-Domain Set-Alias Get-NetDomainController Get-DomainController Set-Alias Get-NetForest Get-Forest Set-Alias Get-NetForestDomain Get-ForestDomain Set-Alias Get-NetForestCatalog Get-ForestGlobalCatalog Set-Alias Get-NetUser Get-DomainUser Set-Alias Get-UserEvent Get-DomainUserEvent Set-Alias Get-NetComputer Get-DomainComputer Set-Alias Get-ADObject Get-DomainObject Set-Alias Set-ADObject Set-DomainObject Set-Alias Get-ObjectAcl Get-DomainObjectAcl Set-Alias Add-ObjectAcl Add-DomainObjectAcl Set-Alias Invoke-ACLScanner Find-InterestingDomainAcl Set-Alias Get-GUIDMap Get-DomainGUIDMap Set-Alias Get-NetOU Get-DomainOU Set-Alias Get-NetSite Get-DomainSite Set-Alias Get-NetSubnet Get-DomainSubnet Set-Alias Get-NetGroup Get-DomainGroup Set-Alias Find-ManagedSecurityGroups Get-DomainManagedSecurityGroup Set-Alias Get-NetGroupMember Get-DomainGroupMember Set-Alias Get-NetFileServer Get-DomainFileServer Set-Alias Get-DFSshare Get-DomainDFSShare Set-Alias Get-NetGPO Get-DomainGPO Set-Alias Get-NetGPOGroup Get-DomainGPOLocalGroup Set-Alias Find-GPOLocation Get-DomainGPOUserLocalGroupMapping Set-Alias Find-GPOComputerAdmin Get-DomainGPOComputerLocalGroupMapping Set-Alias Get-LoggedOnLocal Get-RegLoggedOn Set-Alias Invoke-CheckLocalAdminAccess Test-AdminAccess Set-Alias Get-SiteName Get-NetComputerSiteName Set-Alias Get-Proxy Get-WMIRegProxy Set-Alias Get-LastLoggedOn Get-WMIRegLastLoggedOn Set-Alias Get-CachedRDPConnection Get-WMIRegCachedRDPConnection Set-Alias Get-RegistryMountedDrive Get-WMIRegMountedDrive Set-Alias Get-NetProcess Get-WMIProcess Set-Alias Invoke-ThreadedFunction New-ThreadedFunction Set-Alias Invoke-UserHunter Find-DomainUserLocation Set-Alias Invoke-ProcessHunter Find-DomainProcess Set-Alias Invoke-EventHunter Find-DomainUserEvent Set-Alias Invoke-ShareFinder Find-DomainShare Set-Alias Invoke-FileFinder Find-InterestingDomainShareFile Set-Alias Invoke-EnumerateLocalAdmin Find-DomainLocalGroupMember Set-Alias Get-NetDomainTrust Get-DomainTrust Set-Alias Get-NetForestTrust Get-ForestTrust Set-Alias Find-ForeignUser Get-DomainForeignUser Set-Alias Find-ForeignGroup Get-DomainForeignGroupMember Set-Alias Invoke-MapDomainTrust Get-DomainTrustMapping Set-Alias Get-DomainPolicy Get-DomainPolicyData d123799e-550e-4321-b379-ad52712981c9C:\Tools\PowerSploit\Recon\PowerView.ps1 4104132150x02372853Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local841 } if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } $DNSSearcher = Get-DomainSearcher @SearcherArguments if ($DNSSearcher) { if ($PSBoundParameters['FindOne']) { $Results = $DNSSearcher.FindOne() } else { $Results = $DNSSearcher.FindAll() } $Results | Where-Object {$_} | ForEach-Object { try { $Out = Convert-LDAPProperty -Properties $_.Properties | Select-Object name,distinguishedname,dnsrecord,whencreated,whenchanged $Out | Add-Member NoteProperty 'ZoneName' $ZoneName # convert the record and extract the properties if ($Out.dnsrecord -is [System.DirectoryServices.ResultPropertyValueCollection]) { # TODO: handle multiple nested records properly? $Record = Convert-DNSRecord -DNSRecord $Out.dnsrecord[0] } else { $Record = Convert-DNSRecord -DNSRecord $Out.dnsrecord } if ($Record) { $Record.PSObject.Properties | ForEach-Object { $Out | Add-Member NoteProperty $_.Name $_.Value } } $Out.PSObject.TypeNames.Insert(0, 'PowerView.DNSRecord') $Out } catch { Write-Warning "[Get-DomainDNSRecord] Error: $_" $Out } } if ($Results) { try { $Results.dispose() } catch { Write-Verbose "[Get-DomainDNSRecord] Error disposing of the Results object: $_" } } $DNSSearcher.dispose() } } } function Get-Domain { <# .SYNOPSIS Returns the domain object for the current (or specified) domain. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: None .DESCRIPTION Returns a System.DirectoryServices.ActiveDirectory.Domain object for the current domain or the domain specified with -Domain X. .PARAMETER Domain Specifies the domain name to query for, defaults to the current domain. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. .EXAMPLE Get-Domain -Domain testlab.local .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-Domain -Credential $Cred .OUTPUTS System.DirectoryServices.ActiveDirectory.Domain A complex .NET domain object. .LINK http://social.technet.microsoft.com/Forums/scriptcenter/en-US/0c5b3f83-e528-4d49-92a4-dee31f4b481c/finding-the-dn-of-the-the-domain-without-admodule-in-powershell?forum=ITCG #> [OutputType([System.DirectoryServices.ActiveDirectory.Domain])] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [ValidateNotNullOrEmpty()] [String] $Domain, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { if ($PSBoundParameters['Credential']) { Write-Verbose '[Get-Domain] Using alternate credentials for Get-Domain' if ($PSBoundParameters['Domain']) { $TargetDomain = $Domain } else { # if no domain is supplied, extract the logon domain from the PSCredential passed $TargetDomain = $Credential.GetNetworkCredential().Domain Write-Verbose "[Get-Domain] Extracted domain '$TargetDomain' from -Credential" } $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $TargetDomain, $Credential.UserName, $Credential.GetNetworkCredential().Password) try { [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext) } catch { Write-Verbose "[Get-Domain] The specified domain '$TargetDomain' does not exist, could not be contacted, there isn't an existing trust, or the specified credentials are invalid: $_" } } elseif ($PSBoundParameters['Domain']) { $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $Domain) try { [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext) } catch { Write-Verbose "[Get-Domain] The specified domain '$Domain' does not exist, could not be contacted, or there isn't an existing trust : $_" } } else { try { [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() } catch { Write-Verbose "[Get-Domain] Error retrieving the current domain: $_" } } } } function Get-DomainController { <# .SYNOPSIS Return the domain controllers for the current (or specified) domain. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-DomainComputer, Get-Domain .DESCRIPTION Enumerates the domain controllers for the current or specified domain. By default built in .NET methods are used. The -LDAP switch uses Get-DomainComputer to search for domain controllers. .PARAMETER Domain The domain to query for domain controllers, defaults to the current domain. .PARAMETER Server Specifies an Active Directory server (domain controller) to bind to. .PARAMETER LDAP Switch. Use LDAP queries to determine the domain controllers instead of built in .NET methods. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. .EXAMPLE Get-DomainController -Domain 'test.local' Determine the domain controllers for 'test.local'. .EXAMPLE Get-DomainController -Domain 'test.local' -LDAP Determine the domain controllers for 'test.local' using LDAP queries. .EXAMPLE 'test.local' | Get-DomainController Determine the domain controllers for 'test.local'. .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-DomainController -Credential $Cred .OUTPUTS PowerView.Computer Outputs custom PSObjects with details about the enumerated domain controller if -LDAP is specified. System.DirectoryServices.ActiveDirectory.DomainController If -LDAP isn't specified. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType('PowerView.Computer')] [OutputType('System.DirectoryServices.ActiveDirectory.DomainController')] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [String] $Domain, [ValidateNotNullOrEmpty()] [Alias('DomainController')] [String] $Server, [Switch] $LDAP, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { $Arguments = @{} if ($PSBoundParameters['Domain']) { $Arguments['Domain'] = $Domain } if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } if ($PSBoundParameters['LDAP'] -or $PSBoundParameters['Server']) { if ($PSBoundParameters['Server']) { $Arguments['Server'] = $Server } # UAC specification for domain controllers $Arguments['LDAPFilter'] = '(userAccountControl:1.2.840.113556.1.4.803:=8192)' Get-DomainComputer @Arguments } else { $FoundDomain = Get-Domain @Arguments if ($FoundDomain) { $FoundDomain.DomainControllers } } } } function Get-Forest { <# .SYNOPSIS Returns the forest object for the current (or specified) forest. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: ConvertTo-SID .DESCRIPTION Returns a System.DirectoryServices.ActiveDirectory.Forest object for the current forest or the forest specified with -Forest X. .PARAMETER Forest The forest name to query for, defaults to the current forest. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target forest. .EXAMPLE Get-Forest -Forest external.domain .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-Forest -Credential $Cred .OUTPUTS System.Management.Automation.PSCustomObject Outputs a PSObject containing System.DirectoryServices.ActiveDirectory.Forest in addition to the forest root domain SID. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType('System.Management.Automation.PSCustomObject')] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [ValidateNotNullOrEmpty()] [String] $Forest, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { if ($PSBoundParameters['Credential']) { Write-Verbose "[Get-Forest] Using alternate credentials for Get-Forest" if ($PSBoundParameters['Forest']) { $TargetForest = $Forest } else { # if no domain is supplied, extract the logon domain from the PSCredential passed $TargetForest = $Credential.GetNetworkCredential().Domain Write-Verbose "[Get-Forest] Extracted domain '$Forest' from -Credential" } $ForestContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', $TargetForest, $Credential.UserName, $Credential.GetNetworkCredential().Password) try { $ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($ForestContext) } catch { Write-Verbose "[Get-Forest] The specified forest '$TargetForest' does not exist, could not be contacted, there isn't an existing trust, or the specified credentials are invalid: $_" $Null } } elseif ($PSBoundParameters['Forest']) { $ForestContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', $Forest) try { $ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($ForestContext) } catch { Write-Verbose "[Get-Forest] The specified forest '$Forest' does not exist, could not be contacted, or there isn't an existing trust: $_" return $Null } } else { # otherwise use the current forest $ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() } if ($ForestObject) { # get the SID of the forest root if ($PSBoundParameters['Credential']) { $ForestSid = (Get-DomainUser -Identity "krbtgt" -Domain $ForestObject.RootDomain.Name -Credential $Credential).objectsid } else { $ForestSid = (Get-DomainUser -Identity "krbtgt" -Domain $ForestObject.RootDomain.Name).objectsid } $Parts = $ForestSid -Split '-' $ForestSid = $Parts[0..$($Parts.length-2)] -join '-' $ForestObject | Add-Member NoteProperty 'RootDomainSid' $ForestSid $ForestObject } } } function Get-ForestDomain { <# .SYNOPSIS Return all domains for the current (or specified) forest. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-Forest .DESCRIPTION Returns all domains for the current forest or the forest specified by -Forest X. .PARAMETER Forest Specifies the forest name to query for domains. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target forest. .EXAMPLE Get-ForestDomain .EXAMPLE Get-ForestDomain -Forest external.local .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-ForestDomain -Credential $Cred .OUTPUTS System.DirectoryServices.ActiveDirectory.Domain #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType('System.DirectoryServices.ActiveDirectory.Domain')] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [ValidateNotNullOrEmpty()] [String] $Forest, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { $Arguments = @{} if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } $ForestObject = Get-Forest @Arguments if ($ForestObject) { $ForestObject.Domains } } } function Get-ForestGlobalCatalog { <# .SYNOPSIS Return all global catalogs for the current (or specified) forest. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-Forest .DESCRIPTION Returns all global catalogs for the current forest or the forest specified by -Forest X by using Get-Forest to retrieve the specified forest object and the .FindAllGlobalCatalogs() to enumerate the global catalogs. .PARAMETER Forest Specifies the forest name to query for global catalogs. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. .EXAMPLE Get-ForestGlobalCatalog .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-ForestGlobalCatalog -Credential $Cred .OUTPUTS System.DirectoryServices.ActiveDirectory.GlobalCatalog #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType('System.DirectoryServices.ActiveDirectory.GlobalCatalog')] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [ValidateNotNullOrEmpty()] [String] $Forest, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { $Arguments = @{} if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } $ForestObject = Get-Forest @Arguments if ($ForestObject) { $ForestObject.FindAllGlobalCatalogs() } } } function Get-ForestSchemaClass { <# .SYNOPSIS Helper that returns the Active Directory schema classes for the current (or specified) forest or returns just the schema class specified by -ClassName X. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-Forest .DESCRIPTION Uses Get-Forest to retrieve the current (or specified) forest. By default, the .FindAllClasses() method is executed, returning a collection of [DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass] results. If "-FindClass X" is specified, the [DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass] result for the specified class name is returned. .PARAMETER ClassName Specifies a ActiveDirectorySchemaClass name in the found schema to return. .PARAMETER Forest The forest to query for the schema, defaults to the current forest. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. .EXAMPLE Get-ForestSchemaClass Returns all domain schema classes for the current forest. .EXAMPLE Get-ForestSchemaClass -Forest dev.testlab.local Returns all domain schema classes for the external.local forest. .EXAMPLE Get-ForestSchemaClass -ClassName user -Forest external.local Returns the user schema class for the external.local domain. .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-ForestSchemaClass -ClassName user -Forest external.local -Credential $Cred Returns the user schema class for the external.local domain using the specified alternate credentials. .OUTPUTS [DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass] An ActiveDirectorySchemaClass returned from the found schema. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType([System.DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass])] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [Alias('Class')] [ValidateNotNullOrEmpty()] [String[]] $ClassName, [Alias('Name')] [ValidateNotNullOrEmpty()] [String] $Forest, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { $Arguments = @{} if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } $ForestObject = Get-Forest @Arguments if ($ForestObject) { if ($PSBoundParameters['ClassName']) { ForEach ($TargetClass in $ClassName) { $ForestObject.Schema.FindClass($TargetClass) } } else { $ForestObject.Schema.FindAllClasses() } } } } function Find-DomainObjectPropertyOutlierd123799e-550e-4321-b379-ad52712981c9C:\Tools\PowerSploit\Recon\PowerView.ps1 4104152150x01724225Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local11Get-ForestDomain91aecf9e-1a47-4eb3-b08f-0514aefcd6ac 4104132150x0715350Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local5555api32 RevertToSelf ([Bool]) @() -SetLastError), (func wtsapi32 WTSOpenServerEx ([IntPtr]) @([String])), (func wtsapi32 WTSEnumerateSessionsEx ([Int]) @([IntPtr], [Int32].MakeByRefType(), [Int], [IntPtr].MakeByRefType(), [Int32].MakeByRefType()) -SetLastError), (func wtsapi32 WTSQuerySessionInformation ([Int]) @([IntPtr], [Int], [Int], [IntPtr].MakeByRefType(), [Int32].MakeByRefType()) -SetLastError), (func wtsapi32 WTSFreeMemoryEx ([Int]) @([Int32], [IntPtr], [Int32])), (func wtsapi32 WTSFreeMemory ([Int]) @([IntPtr])), (func wtsapi32 WTSCloseServer ([Int]) @([IntPtr])), (func Mpr WNetAddConnection2W ([Int]) @($NETRESOURCEW, [String], [String], [UInt32])), (func Mpr WNetCancelConnection2 ([Int]) @([String], [Int], [Bool])), (func kernel32 CloseHandle ([Bool]) @([IntPtr]) -SetLastError) ) $Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32' $Netapi32 = $Types['netapi32'] $Advapi32 = $Types['advapi32'] $Wtsapi32 = $Types['wtsapi32'] $Mpr = $Types['Mpr'] $Kernel32 = $Types['kernel32'] Set-Alias Get-IPAddress Resolve-IPAddress Set-Alias Convert-NameToSid ConvertTo-SID Set-Alias Convert-SidToName ConvertFrom-SID Set-Alias Request-SPNTicket Get-DomainSPNTicket Set-Alias Get-DNSZone Get-DomainDNSZone Set-Alias Get-DNSRecord Get-DomainDNSRecord Set-Alias Get-NetDomain Get-Domain Set-Alias Get-NetDomainController Get-DomainController Set-Alias Get-NetForest Get-Forest Set-Alias Get-NetForestDomain Get-ForestDomain Set-Alias Get-NetForestCatalog Get-ForestGlobalCatalog Set-Alias Get-NetUser Get-DomainUser Set-Alias Get-UserEvent Get-DomainUserEvent Set-Alias Get-NetComputer Get-DomainComputer Set-Alias Get-ADObject Get-DomainObject Set-Alias Set-ADObject Set-DomainObject Set-Alias Get-ObjectAcl Get-DomainObjectAcl Set-Alias Add-ObjectAcl Add-DomainObjectAcl Set-Alias Invoke-ACLScanner Find-InterestingDomainAcl Set-Alias Get-GUIDMap Get-DomainGUIDMap Set-Alias Get-NetOU Get-DomainOU Set-Alias Get-NetSite Get-DomainSite Set-Alias Get-NetSubnet Get-DomainSubnet Set-Alias Get-NetGroup Get-DomainGroup Set-Alias Find-ManagedSecurityGroups Get-DomainManagedSecurityGroup Set-Alias Get-NetGroupMember Get-DomainGroupMember Set-Alias Get-NetFileServer Get-DomainFileServer Set-Alias Get-DFSshare Get-DomainDFSShare Set-Alias Get-NetGPO Get-DomainGPO Set-Alias Get-NetGPOGroup Get-DomainGPOLocalGroup Set-Alias Find-GPOLocation Get-DomainGPOUserLocalGroupMapping Set-Alias Find-GPOComputerAdmin Get-DomainGPOComputerLocalGroupMapping Set-Alias Get-LoggedOnLocal Get-RegLoggedOn Set-Alias Invoke-CheckLocalAdminAccess Test-AdminAccess Set-Alias Get-SiteName Get-NetComputerSiteName Set-Alias Get-Proxy Get-WMIRegProxy Set-Alias Get-LastLoggedOn Get-WMIRegLastLoggedOn Set-Alias Get-CachedRDPConnection Get-WMIRegCachedRDPConnection Set-Alias Get-RegistryMountedDrive Get-WMIRegMountedDrive Set-Alias Get-NetProcess Get-WMIProcess Set-Alias Invoke-ThreadedFunction New-ThreadedFunction Set-Alias Invoke-UserHunter Find-DomainUserLocation Set-Alias Invoke-ProcessHunter Find-DomainProcess Set-Alias Invoke-EventHunter Find-DomainUserEvent Set-Alias Invoke-ShareFinder Find-DomainShare Set-Alias Invoke-FileFinder Find-InterestingDomainShareFile Set-Alias Invoke-EnumerateLocalAdmin Find-DomainLocalGroupMember Set-Alias Get-NetDomainTrust Get-DomainTrust Set-Alias Get-NetForestTrust Get-ForestTrust Set-Alias Find-ForeignUser Get-DomainForeignUser Set-Alias Find-ForeignGroup Get-DomainForeignGroupMember Set-Alias Invoke-MapDomainTrust Get-DomainTrustMapping Set-Alias Get-DomainPolicy Get-DomainPolicyData 38b68196-2238-4551-8b75-48ec50160e82C:\tools\PowerSploit\Recon\PowerView.ps1 4104132150x0715306Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local1155 The forest name to query for, defaults to the current forest. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target forest. .EXAMPLE Get-Forest -Forest external.domain .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-Forest -Credential $Cred .OUTPUTS System.Management.Automation.PSCustomObject Outputs a PSObject containing System.DirectoryServices.ActiveDirectory.Forest in addition to the forest root domain SID. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType('System.Management.Automation.PSCustomObject')] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [ValidateNotNullOrEmpty()] [String] $Forest, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { if ($PSBoundParameters['Credential']) { Write-Verbose "[Get-Forest] Using alternate credentials for Get-Forest" if ($PSBoundParameters['Forest']) { $TargetForest = $Forest } else { # if no domain is supplied, extract the logon domain from the PSCredential passed $TargetForest = $Credential.GetNetworkCredential().Domain Write-Verbose "[Get-Forest] Extracted domain '$Forest' from -Credential" } $ForestContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', $TargetForest, $Credential.UserName, $Credential.GetNetworkCredential().Password) try { $ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($ForestContext) } catch { Write-Verbose "[Get-Forest] The specified forest '$TargetForest' does not exist, could not be contacted, there isn't an existing trust, or the specified credentials are invalid: $_" $Null } } elseif ($PSBoundParameters['Forest']) { $ForestContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', $Forest) try { $ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($ForestContext) } catch { Write-Verbose "[Get-Forest] The specified forest '$Forest' does not exist, could not be contacted, or there isn't an existing trust: $_" return $Null } } else { # otherwise use the current forest $ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() } if ($ForestObject) { # get the SID of the forest root if ($PSBoundParameters['Credential']) { $ForestSid = (Get-DomainUser -Identity "krbtgt" -Domain $ForestObject.RootDomain.Name -Credential $Credential).objectsid } else { $ForestSid = (Get-DomainUser -Identity "krbtgt" -Domain $ForestObject.RootDomain.Name).objectsid } $Parts = $ForestSid -Split '-' $ForestSid = $Parts[0..$($Parts.length-2)] -join '-' $ForestObject | Add-Member NoteProperty 'RootDomainSid' $ForestSid $ForestObject } } } function Get-ForestDomain { <# .SYNOPSIS Return all domains for the current (or specified) forest. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-Forest .DESCRIPTION Returns all domains for the current forest or the forest specified by -Forest X. .PARAMETER Forest Specifies the forest name to query for domains. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target forest. .EXAMPLE Get-ForestDomain .EXAMPLE Get-ForestDomain -Forest external.local .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-ForestDomain -Credential $Cred .OUTPUTS System.DirectoryServices.ActiveDirectory.Domain #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType('System.DirectoryServices.ActiveDirectory.Domain')] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [ValidateNotNullOrEmpty()] [String] $Forest, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { $Arguments = @{} if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } $ForestObject = Get-Forest @Arguments if ($ForestObject) { $ForestObject.Domains } } } function Get-ForestGlobalCatalog { <# .SYNOPSIS Return all global catalogs for the current (or specified) forest. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-Forest .DESCRIPTION Returns all global catalogs for the current forest or the forest specified by -Forest X by using Get-Forest to retrieve the specified forest object and the .FindAllGlobalCatalogs() to enumerate the global catalogs. .PARAMETER Forest Specifies the forest name to query for global catalogs. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. .EXAMPLE Get-ForestGlobalCatalog .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-ForestGlobalCatalog -Credential $Cred .OUTPUTS System.DirectoryServices.ActiveDirectory.GlobalCatalog #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType('System.DirectoryServices.ActiveDirectory.GlobalCatalog')] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [ValidateNotNullOrEmpty()] [String] $Forest, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { $Arguments = @{} if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } $ForestObject = Get-Forest @Arguments if ($ForestObject) { $ForestObject.FindAllGlobalCatalogs() } } } function Get-ForestSchemaClass { <# .SYNOPSIS Helper that returns the Active Directory schema classes for the current (or specified) forest or returns just the schema class specified by -ClassName X. Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-Forest .DESCRIPTION Uses Get-Forest to retrieve the current (or specified) forest. By default, the .FindAllClasses() method is executed, returning a collection of [DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass] results. If "-FindClass X" is specified, the [DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass] result for the specified class name is returned. .PARAMETER ClassName Specifies a ActiveDirectorySchemaClass name in the found schema to return. .PARAMETER Forest The forest to query for the schema, defaults to the current forest. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. .EXAMPLE Get-ForestSchemaClass Returns all domain schema classes for the current forest. .EXAMPLE Get-ForestSchemaClass -Forest dev.testlab.local Returns all domain schema classes for the external.local forest. .EXAMPLE Get-ForestSchemaClass -ClassName user -Forest external.local Returns the user schema class for the external.local domain. .EXAMPLE $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-ForestSchemaClass -ClassName user -Forest external.local -Credential $Cred Returns the user schema class for the external.local domain using the specified alternate credentials. .OUTPUTS [DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass] An ActiveDirectorySchemaClass returned from the found schema. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType([System.DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass])] [CmdletBinding()] Param( [Parameter(Position = 0, ValueFromPipeline = $True)] [Alias('Class')] [ValidateNotNullOrEmpty()] [String[]] $ClassName, [Alias('Name')] [ValidateNotNullOrEmpty()] [String] $Forest, [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty ) PROCESS { $Arguments = @{} if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } $ForestObject = Get-Forest @Arguments if ($ForestObject) { if ($PSBoundParameters['ClassName']) { ForEach ($TargetClass in $ClassName) { $ForestObject.Schema.FindClass($TargetClass) } } else { $ForestObject.Schema.FindAllClasses() } } } } function Find-DomainObjectPropertyOutlier { <# .SYNOPSIS Finds user/group/computer objects in AD that have 'outlier' properties set. Author: Will Schroeder (@harmj0y), Matthew Graeber (@mattifestation) License: BSD 3-Clause Required Dependencies: Get-Domain, Get-DomainUser, Get-DomainGroup, Get-DomainComputer .DESCRIPTION A 'reference' set of property names is calculated, either from a standard set preserved for user/group/computers, or from the array of names passed to -ReferencePropertySet, or from the property names of the passed -ReferenceObject. Every user/group/computer object (depending on determined class) are enumerated, and for each object, if the object has a 'non-standard' property set (meaning a property not held by the reference set), the object's samAccountName, property name, and property value are output to the pipeline. .PARAMETER ClassName Specifies the AD object class to find property outliers for, 'user', 'group', or 'computer'. If -ReferenceObject is specified, this will be automatically extracted, if possible. .PARAMETER ReferencePropertySet Specifies an array of property names to diff against the class schema. .PARAMETER ReferenceObject Specicifes the PowerView user/group/computer object to extract property names from to use as the reference set. .PARAMETER Domain Specifies the domain to use for the query, defaults to the current domain. .PARAMETER LDAPFilter Specifies an LDAP query string that is used to filter Active Directory objects. .PARAMETER SearchBase The LDAP source to search through, e.g. "LDAP://OU=secret,DC=testlab,DC=local" Useful for OU queries. .PARAMETER Server Specifies an Active Directory server (domain controller) to bind to. .PARAMETER SearchScope Specifies the scope to search under, Base/OneLevel/Subtree (default of Subtree). .PARAMETER ResultPageSize Specifies the PageSize to set for the LDAP searcher object. .PARAMETER ServerTimeLimit Specifies the maximum amount of time the server spends searching. Default of 120 seconds. .PARAMETER Tombstone Switch. Specifies that the searcher should also return deleted/tombstoned objects. .PARAMETER Credential A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. .EXAMPLE Find-DomainObjectPropertyOutlier -ClassName 'User' Enumerates users in the current domain with 'outlier' properties filled in. .EXAMPLE Find-DomainObjectPropertyOutlier -ClassName 'Group' -Domain external.local Enumerates groups in the external.local forest/domain with 'outlier' properties filled in. .EXAMPLE Get-DomainComputer -FindOne | Find-DomainObjectPropertyOutlier Enumerates computers in the current domain with 'outlier' properties filled in. .OUTPUTS PowerView.PropertyOutlier Custom PSObject with translated object property outliers. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType('PowerView.PropertyOutlier')] [CmdletBinding(DefaultParameterSetName = 'ClassName')] Param( [Parameter(Position = 0, Mandatory = $True, ParameterSetName = 'ClassName')] [Alias('Class')] [ValidateSet('User', 'Group', 'Computer')] [String] $ClassName, [ValidateNotNullOrEmpty()] [String[]] $ReferencePropertySet, [Parameter(ValueFromPipeline = $True, Mandatory = $True, ParameterSetName = 'ReferenceObject')] [PSCustomObject] $ReferenceObject, [ValidateNotNullOrEmpty()] [String] $Domain, [ValidateNotNullOrEmpty()] [Alias('Filter')] [String] $LDAPFilter, [ValidateNotNullOrEmpty()] [Alias('ADSPath')] [String] $SearchBase, [ValidateNotNullOrEmpty()] [Alias('DomainController')] [String] $Server, [ValidateSet('Base', 'OneLevel', 'Subtree')] [String] $SearchScope = 'Subtr38b68196-2238-4551-8b75-48ec50160e82C:\tools\PowerSploit\Recon\PowerView.ps1