Hack The Box: Puppy Machine Walkthrough β Medium Difficulty
Introduction to Puppy:

In this writeup, we will explore the βPuppyβ machine from Hack The Box, categorised as an Medium difficulty challenge. This walkthrough will cover the reconnaissance, exploitation, and privilege escalation steps required to capture the flag.
Objective on Puppy Machine:
The goal of this walkthrough is to complete the βPuppyβ machine from Hack The Box by achieving the following objectives:
User Flag:
Gaining the user flag on the Puppy machine was a calculated strike. Using levi.jamesβs credentials, I escalated access by adding the account to the DEVELOPERS group, unlocking the DEV share. Brute-forcing the recovery.kdbx file with the password βLiverpoolβ exposed ant.edwards:Antman2025!, which enabled resetting ADAM.SILVERβs password. A swift WinRM login as ADAM.SILVER and a quick βtype user.txtβ snagged the flag from the desktop.
Root Flag:
The root flag fell after a relentless push through credential exploitation. From a backup file in C:\Backups, I extracted steph.cooper:ChefSteph2025! and used it to access a WinRM shell. Exfiltrating DPAPI keys via an SMB share and decrypting them with Impacket unveiled steph.cooper_adm:FivethChipOnItsWay2025!. Logging in as this user opened the Administrator directory, where βtype root.txtβ delivered the final prize.
Enumerating the Puppy Machine
Reconnaissance:
Nmap Scan:
Begin with a network scan to identify open ports and running services on the target machine.
nmap -sC -sV -oA initial -Pn 10.10.11.70Nmap Output:
ββ[dark@parrot]β[~/Documents/htb/puppy]
ββββΌ $nmap -sC -sV -oA initial -Pn 10.10.11.70
# Nmap 7.94SVN scan initiated Fri Sep 26 16:50:55 2025 as: nmap -sC -sV -oA initial -Pn 10.10.11.70
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-09-27 03:25:03Z)
111/tcp open rpcbind 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 Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: PUPPY.HTB0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
2049/tcp open nlockmgr 1-4 (RPC #100021)
3260/tcp open iscsi?
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: PUPPY.HTB0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: 6h33m43s
| smb2-time:
| date: 2025-09-27T03:26:54
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and requiredAnalysis:
- 53/tcp: DNS (Simple DNS Plus) for name resolution.
- 88/tcp: Kerberos authentication service for AD logins.
- 135/tcp & 593/tcp: Microsoft RPC endpoints for service enumeration.
- 139/tcp & 445/tcp: NetBIOS and SMB for file shares and potential lateral movement.
- 389/tcp & 3268/tcp: LDAP and Global Catalog for AD enumeration.
- 464/tcp: Kerberos password change service.
- 111/tcp & 2049/tcp: NFS and RPC services (mountd, nlockmgr) for file system access.
- 636/tcp & 3269/tcp: Encrypted LDAP services (LDAPS/GC).
- 3260/tcp: Potential iSCSI storage interface.
Enumeration:
Bloodhound

Executed bloodhound-python with levi.james credentials against puppy.htb (using 10.10.11.70 as the DNS/collector). The tool enumerated Active Directory data (users, groups, computers, sessions, ACLs, trusts, etc.) with -c All and packaged the results into a zipped bundle (--zip) ready for import into BloodHound to map privilege-escalation and lateral-movement paths.

levi.james is in HR and DEVELOPERS and holds GenericWrite β he can modify attributes/DACLs on writable objects; on HTB, use BloodHound to find those machines/groups/service accounts and abuse them (add users to privileged groups, change DACLs, or set an SPN) to escalate.
rpcclient β Enumerating domain users

Using rpcclient, we connected to the target machine as levi.james and enumerated the domain users. The enumeration output listed several accounts, including Administrator, Guest, service accounts such as krbtgt, and multiple regular users like levi.james, ant.edwards, adam.silver, jamie.williams, steph.cooper, and steph.cooper_adm. These findings provide a useful starting point for further steps, such as detailed enumeration or potential password spraying attacks.
SMBclient enumeration

Running netexec smb against 10.10.11.70 with levi.jamesβs credentials successfully enumerated SMB shares. The results show IPC$, NETLOGON, and SYSVOL are accessible with read-only permissions, while ADMIN$, C$, and DEV shares are inaccessible. This read access can be useful for gathering domain information or extracting scripts and policies from SYSVOL and NETLOGON for further enumeration.

Running smbclient //10.10.11.70/DEV -U levi.james attempted to access the DEV share using levi.jamesβs credentials. The connection was successful, but when trying to list the contents (ls), the server returned NT_STATUS_ACCESS_DENIED, indicating that the account does not have the required permissions to view or access files in this share.

Using bloodyAD, we connected to the domain controller (dc.puppy.htb) with levi.jamesβs credentials and successfully added the user levi.james to the DEVELOPERS group, granting him all privileges associated with the group. After re-authenticating, we reconnected to the DEV share with smbclient and were able to list its contents. The share contained several notable items, including KeePassXC-2.7.9-Win64.msi, a Projects folder, recovery.kdbx (a KeePass database), and tiCPYdaK.exe. These files provide valuable leads for further enumeration, with the KeePass database being a strong candidate for extracting credentials to escalate privileges or move laterally within the network.

Downloaded the recovery.kdbx file from the DEV share to the local machine for offline analysis.
KDBX cracking β offline KeePass recovery

The file command identified recovery.kdbx as a KeePass 2.x KDBX password database.

We ran keepass2john on the file to extract password hashes, but it failed with an error indicating that the file version 40000 is not supported, so no hashes could be generated.
keepass4brute β running KDBX brute-force responsibly

Cloning that repository downloads the keepass4brute project from GitHub to your local machine, giving you the scripts, tools, and documentation included by the author for attempting offline recovery or brute-force against KeePass databases. After cloning, check the README for dependencies and usage instructions, verify the tool supports your KDBX version, and run it on a local copy of the database only with explicit authorization β misuse may be illegal or unethical.

The repository we cloned to our machine contains four items: .gitignore (ignored files), LICENSE (project license), README.md (usage and setup instructions), and keepass4brute.sh (the main brute-force script). Review the README and LICENSE before running the script, confirm dependencies, and scan any downloaded executables for malware.

Run the script like this: ./keepass4brute.sh <kdbx-file> <wordlist> to attempt brute-forcing the KeePass database with a specified wordlist.

The script aborted because keepassxc-cli is not installed. Install keepassxc-cli and rerun the script to continue the brute-force attempt.

I found a solution online: run sudo apt update then sudo apt install keepassxc to install KeepassXC (which provides keepassxc-cli). After installation, rerun the script.

The script is working and currently running.

Funny enough, it seems the machine creator might be a Liverpool fan, given that the recovered password is liverpool.
KeePassXC reveal β stored passwords recovered

We unlocked recovery.kdbx in KeepassXC using the password Liverpool.

Discovered a KeePass password database associated with the machine.

The user account that can be leveraged for privilege escalation or access.





The screenshots above show each userβs password.

The screenshot above displays the list of usernames.

Above displays the list of usernames along with their passwords.

I ran nxc smb against 10.10.11.70 with user list user.txt and password list password.txt using βcontinue-on-success; only the credential pair ant.edwards:Antman2025! succeeded.

ant.edwards sits in the SeniorDevs group and has GenericAll over adam.silver β meaning ant.edwards has full control of that account (reset password, change group membership, modify attributes or SPNs).

Using bloodyAD against dc.puppy.htb with the credentials ant.edwards:Antman2025!, we reset ADAM.SILVERβs password to p@ssw0d123! The tool reported the change succeeded, giving us direct access to the ADAM.SILVER account for follow-up enumeration or lateral movement.

ADAM.SILVER is currently disabled, so interactive logons with that account will fail until itβs re-enabled. Because ant.edwards has GenericAll over ADAM.SILVER, that account could be re-enabled and its password reset (or userAccountControl changed) to gain access β a straightforward takeover path once permissions are abused.
LDAP enumeration & ldapmodify β abusing recovered credentials

The bind failed because the LDAP server rejected the credentials β LDAP error code 49 (Invalid credentials). The extra text AcceptSecurityContext ... data 52e specifically indicates a bad username/password. Common causes are an incorrect password, wrong account name format (try DOMAIN\user or user@domain), or the account being locked or disabled. Verify the credentials and account status, then retry the bind.

The server returned an Operations error saying a successful bind is required before performing the search. In short: the LDAP query ran without an authenticated session (or the previous bind failed), so the server refused the operation. Fix by performing a successful bind first β supply valid credentials (try correct UPN or DOMAIN\user format), confirm the account is not locked/disabled, and then rerun the ldapsearch. If the server disallows anonymous/simple binds, use an authenticated bind method.

The LDAP errors were resolved after synchronizing the system clock using ntpdate. Kerberos and Active Directory require closely matched time between client and domain controller; even a small time drift can cause bind failures or βinvalid credentialsβ errors. After correcting the time, the bind succeeded and LDAP queries worked as expected.

A userAccountControl value of 66050 indicates that the account is disabled in Active Directory.

The ldapmodify command was used to connect to the LDAP server with ANT.EDWARDS@PUPPY.HTB and modify Adam D. Silverβs account. It updated the userAccountControl attribute from 66050 (disabled) to 66048, enabling the account while keeping other flags intact. This change allows Adam D. Silver to log in and use his assigned permissions.

Start a WinRM session to 10.10.11.70 using ADAM.SILVER with password p@ssw0rd123! to obtain a remote Windows shell via evil-winrm.


Grab the user flag by running type user.txt in the WinRM shell.
Escalate to Root Privileges Access
Privilege Escalation:

There is a Backups directory located inside C:\ on the target machine.

The Backups directory contains a file named site-backup-2024-12-30.zip.

Downloaded the backup file to our local machine.
Backup triage β uncovering secrets in site-backup

Next, the backup file is extracted to inspect and analyse its contents in detail.

The extracted backup contains two directories, assets and images, along with two files: index.html and nms-auth-config.xml.bak.

The file nms-auth-config.xml.bak caught my attention; it is an XML 1.0 document in ASCII text format.
User access obtained β steph.cooper

The nms-auth-config.xml.bak file contains LDAP authentication details, including a bind account cn=steph.cooper,dc=puppy,dc=htb with password ChefSteph2025!, which can be used to query the LDAP server at DC.PUPPY.HTB:389. It also defines how user attributes (uid, givenName, sn, mail) and group attributes (cn, member) are mapped, along with a search filter for querying users. This makes the file both a sensitive credential source and a guide for LDAP enumeration.

Authenticated to 10.10.11.70 over WinRM using steph.cooper:ChefSteph2025! and obtained an interactive shell β host compromised (Pwn3d!)

Established a WinRM session to 10.10.111.70 using steph.cooper:ChefSteph2025! via vil-winrm and obtained an interactive shell β host compromised.

Ran bloodhound-python with steph.cooper:ChefSteph2025! against puppy.htb (collector DNS 10.10.11.70), which enumerated AD objects (users, groups, computers, sessions, ACLs, trusts, etc.) and packaged the output into a zipped bundle ready for import into BloodHound to map privilege-escalation and lateral-movement paths.

STEPH.COOPER@PUPPY.HTB holds DOMAIN ADMINS and ADMINISTRATORS membership, giving full domain-level control, while STEPH.COOPER_ADM@PUPPY.HTB belongs to ENTERPRISE ADMINS, granting top-level, forest-wide privileges across the entire network.
Decrypting DPAPI master key for root access

The script iterates every profile under C:\Users and, for each user, prints headings then lists full paths to DPAPI βMaster Keyβ files (under AppData\Roaming\Microsoft\Protect and AppData\Local\Microsoft\Protect) and credential blobs (under AppData\Roaming\Microsoft\Credentials and AppData\Local\Microsoft\Credentials). It suppresses errors when folders donβt exist and outputs the exact file pathsβuseful for locating DPAPI keys and credential files for offline extraction and decryption.

That command starts an SMB server that exposes the local ./share directory as a network share named share with SMB2 support enabled, allowing remote hosts to connect and retrieve or push files (commonly used to serve payloads or collect exfiltrated data during engagements).

I noticed several directories under C:\Users\steph.cooper\AppData\Roaming\Microsoft that can be leveraged.

Permission denied when attempting to access that path.

After some time, I realised we need to create a local directory share on our machine.

Finally, it worked as expected.

Downloaded the files to the local machine successfully.

An error occurred: X509_V_FLAG_NOTIFY_POLICY appeared. This typically relates to SSL/TLS certificate verification issues during the connection or handshake process.

After investigating on my machine, I discovered that the installed PyOpenSSL version is 23.0.0.

To resolve the issue, PyOpenSSL was first uninstalled using sudo pip3 uninstall pyOpenSSL and then reinstalled with the latest version via sudo pip3 install --upgrade pyOpenSSL.

To my surprise, the process worked successfully and produced the following decrypted master key:0xd9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84.
I can now use this key for further analysis or to decrypt stored credentials.

Impacket decoded a domain credential: the Username is steph.cooper_adm and the Unknown field contains the cleartext password FivethChipOnItsWay2025!. Use these credentials to attempt an interactive logon, then assess the accountβs privileges and restrictions before pivoting.

Authenticated to 10.10.11.70 over WinRM with steph.cooper_adm:FivethChipOnItsWay2025! and obtained an interactive shell β host compromised (Pwn3d!).

It completed successfully.

Checked steph.cooper_admβs desktop and did not find the root flag.

An Administrator directory is present β we can explore it for sensitive files and potential privilege escalation.


Grab the root flag by running type root.txt in the shell.
The post Hack The Box: Puppy Machine Walkthrough β Medium Difficulty appeared first on Threatninja.net.