Skip to content
This repository was archived by the owner on Jan 21, 2021. It is now read-only.

Commit f00e3fc

Browse files
committed
Added Set-DomainObjectOwner to modify an object's owner
Modified Convert-LDAPProperty to break out sections of ntsecuritydescriptor
1 parent f4f5fb1 commit f00e3fc

File tree

4 files changed

+431
-20
lines changed

4 files changed

+431
-20
lines changed

Recon/PowerView.ps1

Lines changed: 195 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,7 +2741,20 @@ A custom PSObject with LDAP hashtable properties translated.
27412741
$ObjectProperties[$_] = (New-Object Guid (,$Properties[$_][0])).Guid
27422742
}
27432743
elseif ($_ -eq 'ntsecuritydescriptor') {
2744-
$ObjectProperties[$_] = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $Properties[$_][0], 0
2744+
# $ObjectProperties[$_] = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $Properties[$_][0], 0
2745+
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $Properties[$_][0], 0
2746+
if ($Descriptor.Owner) {
2747+
$ObjectProperties['Owner'] = $Descriptor.Owner
2748+
}
2749+
if ($Descriptor.Group) {
2750+
$ObjectProperties['Group'] = $Descriptor.Group
2751+
}
2752+
if ($Descriptor.DiscretionaryAcl) {
2753+
$ObjectProperties['DiscretionaryAcl'] = $Descriptor.DiscretionaryAcl
2754+
}
2755+
if ($Descriptor.SystemAcl) {
2756+
$ObjectProperties['SystemAcl'] = $Descriptor.SystemAcl
2757+
}
27452758
}
27462759
elseif ( ($_ -eq 'lastlogon') -or ($_ -eq 'lastlogontimestamp') -or ($_ -eq 'pwdlastset') -or ($_ -eq 'lastlogoff') -or ($_ -eq 'badPasswordTime') ) {
27472760
# convert timestamps
@@ -4898,7 +4911,7 @@ function Set-DomainUserPassword {
48984911
<#
48994912
.SYNOPSIS
49004913

4901-
Sets the password for a given user identity and returns the user object.
4914+
Sets the password for a given user identity.
49024915

49034916
Author: Will Schroeder (@harmj0y)
49044917
License: BSD 3-Clause
@@ -4994,7 +5007,6 @@ http://richardspowershellblog.wordpress.com/2008/05/25/system-directoryservices-
49945007

49955008
$Null = $User.Save()
49965009
Write-Verbose "[Set-DomainUserPassword] Password for user '$Identity' successfully reset"
4997-
$User
49985010
}
49995011
catch {
50005012
Write-Warning "[Set-DomainUserPassword] Error setting password for user '$Identity' : $_"
@@ -6186,22 +6198,10 @@ Get-DomainUser -Identity testuser -Properties scriptpath
61866198
scriptpath
61876199
----------
61886200
\\EVIL\program2.exe
6189-
6190-
.OUTPUTS
6191-
6192-
PowerView.ADObject
6193-
6194-
Custom PSObject with translated AD object property fields, if -PassThru is enabled.
6195-
6196-
PowerView.ADObject.Raw
6197-
6198-
The raw DirectoryServices.SearchResult object, if -PassThru and -Raw are enabled.
61996201
#>
62006202

62016203
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
62026204
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
6203-
[OutputType('PowerView.ADObject')]
6204-
[OutputType('PowerView.ADObject.Raw')]
62056205
[CmdletBinding()]
62066206
Param(
62076207
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
@@ -6253,10 +6253,6 @@ The raw DirectoryServices.SearchResult object, if -PassThru and -Raw are enabled
62536253
[Int]
62546254
$ServerTimeLimit,
62556255

6256-
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')]
6257-
[String]
6258-
$SecurityMasks,
6259-
62606256
[Switch]
62616257
$Tombstone,
62626258

@@ -6336,6 +6332,186 @@ The raw DirectoryServices.SearchResult object, if -PassThru and -Raw are enabled
63366332
}
63376333

63386334

6335+
function Set-DomainObjectOwner {
6336+
<#
6337+
.SYNOPSIS
6338+
6339+
Modifies the owner for a specified active directory object.
6340+
6341+
Author: Will Schroeder (@harmj0y)
6342+
License: BSD 3-Clause
6343+
Required Dependencies: Get-DomainObject
6344+
6345+
.DESCRIPTION
6346+
6347+
Retrieves the Active Directory object specified by -Identity by splatting to
6348+
Get-DomainObject, returning the raw searchresult object. Retrieves the raw
6349+
directoryentry for the object, and sets the object owner to -OwnerIdentity.
6350+
6351+
.PARAMETER Identity
6352+
6353+
A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local),
6354+
SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201)
6355+
of the AD object to set the owner for.
6356+
6357+
.PARAMETER OwnerIdentity
6358+
6359+
A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local),
6360+
SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201)
6361+
of the owner to set for -Identity.
6362+
6363+
.PARAMETER Domain
6364+
6365+
Specifies the domain to use for the query, defaults to the current domain.
6366+
6367+
.PARAMETER LDAPFilter
6368+
6369+
Specifies an LDAP query string that is used to filter Active Directory objects.
6370+
6371+
.PARAMETER SearchBase
6372+
6373+
The LDAP source to search through, e.g. "LDAP://OU=secret,DC=testlab,DC=local"
6374+
Useful for OU queries.
6375+
6376+
.PARAMETER Server
6377+
6378+
Specifies an Active Directory server (domain controller) to bind to.
6379+
6380+
.PARAMETER SearchScope
6381+
6382+
Specifies the scope to search under, Base/OneLevel/Subtree (default of Subtree).
6383+
6384+
.PARAMETER ResultPageSize
6385+
6386+
Specifies the PageSize to set for the LDAP searcher object.
6387+
6388+
.PARAMETER ServerTimeLimit
6389+
6390+
Specifies the maximum amount of time the server spends searching. Default of 120 seconds.
6391+
6392+
.PARAMETER Tombstone
6393+
6394+
Switch. Specifies that the searcher should also return deleted/tombstoned objects.
6395+
6396+
.PARAMETER Credential
6397+
6398+
A [Management.Automation.PSCredential] object of alternate credentials
6399+
for connection to the target domain.
6400+
6401+
.EXAMPLE
6402+
6403+
Set-DomainObjectOwner -Identity dfm -OwnerIdentity harmj0y
6404+
6405+
Set the owner of 'dfm' in the current domain to 'harmj0y'.
6406+
6407+
.EXAMPLE
6408+
6409+
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
6410+
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)
6411+
Set-DomainObjectOwner -Identity dfm -OwnerIdentity harmj0y -Credential $Cred
6412+
6413+
Set the owner of 'dfm' in the current domain to 'harmj0y' using the alternate credentials.
6414+
#>
6415+
6416+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
6417+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
6418+
[CmdletBinding()]
6419+
Param(
6420+
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
6421+
[Alias('DistinguishedName', 'SamAccountName', 'Name')]
6422+
[String]
6423+
$Identity,
6424+
6425+
[Parameter(Mandatory = $True)]
6426+
[ValidateNotNullOrEmpty()]
6427+
[Alias('Owner')]
6428+
[String]
6429+
$OwnerIdentity,
6430+
6431+
[ValidateNotNullOrEmpty()]
6432+
[String]
6433+
$Domain,
6434+
6435+
[ValidateNotNullOrEmpty()]
6436+
[Alias('Filter')]
6437+
[String]
6438+
$LDAPFilter,
6439+
6440+
[ValidateNotNullOrEmpty()]
6441+
[Alias('ADSPath')]
6442+
[String]
6443+
$SearchBase,
6444+
6445+
[ValidateNotNullOrEmpty()]
6446+
[Alias('DomainController')]
6447+
[String]
6448+
$Server,
6449+
6450+
[ValidateSet('Base', 'OneLevel', 'Subtree')]
6451+
[String]
6452+
$SearchScope = 'Subtree',
6453+
6454+
[ValidateRange(1, 10000)]
6455+
[Int]
6456+
$ResultPageSize = 200,
6457+
6458+
[ValidateRange(1, 10000)]
6459+
[Int]
6460+
$ServerTimeLimit,
6461+
6462+
[Switch]
6463+
$Tombstone,
6464+
6465+
[Management.Automation.PSCredential]
6466+
[Management.Automation.CredentialAttribute()]
6467+
$Credential = [Management.Automation.PSCredential]::Empty
6468+
)
6469+
6470+
BEGIN {
6471+
$SearcherArguments = @{}
6472+
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain }
6473+
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $LDAPFilter }
6474+
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase }
6475+
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server }
6476+
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope }
6477+
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize }
6478+
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
6479+
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone }
6480+
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential }
6481+
6482+
$OwnerSid = Get-DomainObject @SearcherArguments -Identity $OwnerIdentity -Properties objectsid | Select-Object -ExpandProperty objectsid
6483+
if ($OwnerSid) {
6484+
$OwnerIdentityReference = [System.Security.Principal.SecurityIdentifier]$OwnerSid
6485+
}
6486+
else {
6487+
Write-Warning "[Set-DomainObjectOwner] Error parsing owner identity '$OwnerIdentity'"
6488+
}
6489+
}
6490+
6491+
PROCESS {
6492+
if ($OwnerIdentityReference) {
6493+
$SearcherArguments['Raw'] = $True
6494+
$SearcherArguments['Identity'] = $Identity
6495+
6496+
# splat the appropriate arguments to Get-DomainObject
6497+
$RawObject = Get-DomainObject @SearcherArguments
6498+
6499+
ForEach ($Object in $RawObject) {
6500+
try {
6501+
Write-Verbose "[Set-DomainObjectOwner] Attempting to set the owner for '$Identity' to '$OwnerIdentity'"
6502+
$Entry = $RawObject.GetDirectoryEntry()
6503+
$Entry.PsBase.ObjectSecurity.SetOwner($OwnerIdentityReference)
6504+
$Entry.PsBase.CommitChanges()
6505+
}
6506+
catch {
6507+
Write-Warning "[Set-DomainObjectOwner] Error setting owner: $_"
6508+
}
6509+
}
6510+
}
6511+
}
6512+
}
6513+
6514+
63396515
function Get-DomainObjectAcl {
63406516
<#
63416517
.SYNOPSIS

Recon/Recon.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ FunctionsToExport = @(
5151
'Get-DomainComputer',
5252
'Get-DomainObject',
5353
'Set-DomainObject',
54+
'Set-DomainObjectOwner',
5455
'Get-DomainObjectAcl',
5556
'Add-DomainObjectAcl',
5657
'Find-InterestingDomainAcl',

0 commit comments

Comments
 (0)