Create tombstone module
Description
This new module allows users to list, restore objects from "Deleted Objects" container, and delete active objects.
-
Listing deleted objects:
The module queries deleted objects using the LDAP filter(isDeleted=TRUE)along with the controlLDAP_SERVER_SHOW_DELETED_OID, which is required to retrieve tombstoned entries. The query targets the DNCN=Deleted Objects,DC=.... By default, the first entry is skipped as it represents the container itself, not a real AD object (e.g., user or computer). -
Restoring objects:
To restore a deleted object, the module uses the ID obtained during the query and:- Removes the
isDeletedattribute. - Replaces the
distinguishedNamewith the value oflastKnownParent.
This only works if the AD Recycle Bin is enabled and the user has the necessary permissions.
- Removes the
-
Deleting objects:
The module also supports deleting objects to return to their "tombstoned form" using the.delete()method fromldap3. This is useful in scenarios where multiple objects with similar names exist (e.g., multiple versions of a user), and selective restoration or cleanup is needed.
Type of change
- [x] New feature (non-breaking change which adds functionality)
How Has This Been Tested?
Tested on a local lab that I created and HTB, tried to test at my work but I don't have the privs to do that ;)
Screenshots (if appropriate):
After removing the user from this OU the query option (default) can be used to recover all the necessary informations from the Deleted Objects container.
Right now the user has no way to confirm if he has or not privileges (this is something that in a future update a DACL parser can be added but I don't know how to do that now).
To restore an object from the Deleted Objects the user needs to call the "restore" action and pass the ID value recovered from the query action.
The first call to ldap fail since the user is not active, after the restore action the ldap connection worked again.
To delete the object the DN must be passed to the deleted action.
Checklist:
- [x] I have ran Ruff against my changes (via poetry:
poetry run python -m ruff check . --preview, use--fixto automatically fix what it can) - [x] If reliant on changes of third party dependencies, such as Impacket, dploot, lsassy, etc, I have linked the relevant PRs in those projects
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
References
To perform this attack some actions must be performed at the domain:
https://nettools.net/how-to-delegate-object-restoration-rights/ https://learn.microsoft.com/pt-br/troubleshoot/windows-server/active-directory/non-administrators-view-deleted-object-container
By default only DA can restore and list objects from the Deleted Objects, I created this module after doing some machines from htb and vulnlab that AD Recycle Bin was active and you need to do a winrm / rdp session to execute the Restore-ADObject cmdlet, with this module you don't need to have a valid windows session anymore.
tombstone module name would be ideal i guess
I can change the name with no problem if everyone agrees
Probably a less terrifying module name😅
I like the name :P
Name changed
First of all amazing work mate! one thing i noticed
it doesnt work with where machine only allows kerberos auth (NO NTLM) i used same syntax with -k option & it breaks , can you add kerberos support too ?
Hi, yes this is a known issue by me, but the problem is at impacket itself, I pushed a pr to impacket that fix something that was made when calling get_machine_name:
https://github.com/fortra/impacket/pull/1997
but netexec uses another impacket, https://github.com/Pennyw0rth/impacket, when the pr that I made from impacket gets merged to the impacket that netexec use, then I can make the changes and the script will work again even when ntlm is not suported.
(I think I will try to make the changes here already but it will not work while impacket does not get merged)
Done, but remember at the time that I'm writting this, impacket from netexec don't have the updated version, I know what machine you are doing and I used as a test example, if you want to test before the merge happens you need to modify this file:
/impacket/examples (line 241)
This is the same pr that I did for impacket to fix this problem when ntlm is disabled
New modules need to be added to the e2e tests
Just to be sure I need to edit e2e_commands.txt right? But I think my fork has a different e2e because it is saying "This branch has conflicts that must be resolved"
Just to be sure I need to edit e2e_commands.txt right? But I think my fork has a different e2e because it is saying "This branch has conflicts that must be resolved"
Then resolve them?
First time doing that, learned something new
but netexec uses another impacket, https://github.com/Pennyw0rth/impacket, when the pr that I made from impacket gets merged to the impacket that netexec use, then I can make the changes and the script will work again even when ntlm is not suported.
Gonna update our impacket fork, give me a bit
Done, our impacket should be up-to-date now
Tested here again, working against domains where ntlm is disabled