Hashdump without the DC using DCSync (because we all wanted it)
Update: It was brought to our attention that we mistakenly forgot to credit a few of the researchers who contributed to the code used in this post. In fact, these contributors really did the heavy lifting and we simply combined various aspects of their work to create a hashdump script. Will Schroeder (@harmjoy), Joseph Bialek (@JosephBialek), Matt Graeber (@mattifestation), Vincent Le Toux (vincent.letoux [at] gmail.com), and Benjamin Delpy (@gentilkiwi) all contributed to this effort. Check the source for their specific contributions. We write a lot of code for internal use, and are still new at the process for public release.We apologize for the oversight!
This is a short blog post (and a script) to release a PowerShell invoker for DCSync. If you haven’t heard of “DCSync”, it is essentially a feature within Mimikatz that allows you to impersonate a domain controller to synchronize domain account credentials with other domain controllers. The underlying technology is obviously necessary so when a domain user changes his or her account password, the change gets synchronized across all domain controllers. Here’s the catch…the synchronization request doesn’t have to be made from an actual domain controller. Leveraging this “feature” in Active Directory, Mimikatz impersonates a domain controller to perform a password synchronization request to another domain controller. Add in some user enumeration and we can effectively perform a domain hashdump without ever actually being on a domain controller! Even better…on a recent assessment we found an organization had enabled the “Store passwords using reversible encryption” GPO. We were pleasantly surprised to find that DCSync not only pulled the hashes, but also the clear-text passwords for the accounts with that option enabled!
Now, there are a few noteworthy items. Of course there are some limitations to this. First (and hopefully this is obvious), you need to be a domain or enterprise administrator. Also, it may not be a good idea from an opsec perspective to run this on a non-domain controller host. Obviously, this is meant to synchronize DC to DC, not DC to workstation, or even DC to server. Sean Metcalf has a lot of good information on the opsec impact and even detection of this type of traffic here. Now on to the good stuff..
The PowerShell script leverages Invoke-ReflectivePEInjection with some help from the PowerView project to enumerate domain users. Basically, the script uses a DLL wrapper for the PowerKatz build of the Mimikatz project with an exported “powershell_reflective_mimikatz” function to execute the commands. Short synopsis:
- Users and/or machines are enumerated from the network. (They are also passable as an argument.)
- The DLL is loaded into memory, and the DCSync function location is found.
- The DCSync command is generated and the function is called iteratively.
- The output is parsed and formatted for your viewing and cracking pleasure.

Link to the ps1: https://gist.github.com/monoxgas/9d238accd969550136db
Here is the the full help for the command:
NAME
Invoke-DCSync
SYNOPSIS
Uses dcsync from mimikatz to collect NTLM hashes from the domain.
SYNTAX
Invoke-DCSync [[-Users] <Array[]>] [-GetComputers] [-OnlyActive] [-PWDumpFormat] [-AllData] []
DESCRIPTION
Uses a mimikatz dll in memory to call dcsync against a domain. By default, it will enumerate all active domain users along with the krbtgt, and print out their current NTLM hash. Big ups to @harmj0y for the powerview project. The Get-NetUser and Get-NetComputer code is ripped for this script.
PARAMETERS
-Users <Array[]>
Optional, An array of usernames to query hashes for (Passable on the Pipeline). krbtgt will automatically get added
Required? false
Position? 1
Default value
Accept pipeline input? true (ByValue)
Accept wildcard characters?
-GetComputers []
Will pull the machine hashes as well. Default is false
Required? false
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters?
-OnlyActive []
Will only pull users whos account is active on the domain. Default is true
Required? false
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters?
-PWDumpFormat []
Formats the output in 'user:id:lm:ntlm:::' format. Default is false
Required? false
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters?
-AllData []
Prints out raw mimikatz output. Default is false
Required? false
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters?
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer and OutVariable. For more information, type,
"get-help about_commonparameters".
INPUTS
OUTPUTS
-------------------------- EXAMPLE 1 --------------------------
>Invoke-DCSync -PWDumpFormat
Returns all active user hashes in 'user:id:lm:ntlm:::' format.
-------------------------- EXAMPLE 2 --------------------------
>Invoke-DCSync -OnlyActive:$false -GetComputers
Returns all user and computer object hashes in the domain
-------------------------- EXAMPLE 3 --------------------------
>Get-NetGroup -GroupName "EvilPeople" | % {$_.MemberName} | Invoke-DCSync
Returns the user hashes for account in the EvilPeople group
Explore More Blog Posts
Turning Regulation into a Resilience Advantage: 6 Top Pentesting Tips for CISOs
Regulations and cyber threats are moving at breakneck speed. And so are expectations from boards, regulators, and auditors. For today’s CISOs, the real question isn’t “Are we compliant?” it’s “Are we resilient?”
Webinar Recap: How to Keep Your CISO Out of Jail
Learn how CISOs can reduce legal risk by documenting decisions, fostering security culture, and aligning cybersecurity with business goals.
Decrypting VM Extension Settings with Azure WireServer
The Azure WireServer service provides configuration data to Azure Virtual Machines. Join us as we walkthrough the process of decrypting that data to find sensitive information.