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