ADTIER-005: Cuentas de servicio de SQL / base de datos en grupos privilegiados
- Plataforma
- Active Directory
- Categoría
- Tier-0 Hygiene & Hybrid Identity Surface
- Severidad
- High
- Pilar de Zero Trust
- Identity (peso 2)
- Fixtures de referencia
- 3
- Cobertura de ramas
- Observada: los fixtures prueban los veredictos que ejercitan
- Procedencia
- baseline
Qué comprueba
Las cuentas de servicio de SQL Server / MySQL / PostgreSQL en Domain Admins son comunes en entornos donde el equipo de DBA instaló SQL con la guía predeterminada 'Usar cuenta de AD existente' y eligió una cuenta de administrador por comodidad. Una vez que el servidor de base de datos es accesible en la red, el compromiso de una credencial de SQL o una vulnerabilidad de SQL Server otorga al atacante Domain Admin directamente.
Por qué importa
A SQL Server installation that selected "Use existing AD account" during setup and was handed a Domain Admin credential by the DBA team creates two compounding problems. First, the credential is loaded into the LSASS process and the SQL Server service process on every host the database runs on, which means any local administrator on that host (which routinely includes server-team operators, monitoring agents, backup software, and the DBAs themselves) can pull the cleartext or NT hash via mimikatz sekurlsa::logonpasswords, lsadump, or a procdump-then-offline-pypykatz pass. Second, the SPN registered against the account (MSSQLSvc/sql01.corp.contoso.com:1433) is queryable by any Domain Users principal, so the account is trivially discoverable as a Kerberoasting target. A weak password on a Domain Admin SQL service account is the canonical SpecterOps red-team finding. The blast radius is total. A Kerberoast against svc_sql with a crackable password yields Domain Admin. An unauthenticated SQL Server CVE (CVE-2020-0618 Reporting Services RCE, CVE-2021-1636 SQL Server elevation of privilege, CVE-2023-21528, the historical xp_cmdshell-as-sa abuses) executed against a database whose service runs as Domain Admin yields Domain Admin without any credential phase. A SQL injection in any application that connects to the database, when xp_cmdshell is enabled and the service account is privileged, yields the same result. The principle being violated is Tier-Zero containment: a Tier-1 application host (the database server) is being granted Tier-0 trust because the service account is a Tier-0 principal, and any compromise of the Tier-1 host therefore compromises Tier-0. Microsoft has stated since the Windows Server 2008 R2 era that SQL Server service accounts should never be members of any privileged Active Directory group and that the installer should provision per-instance virtual service accounts (NT SERVICE\MSSQLSERVER, NT SERVICE\MSSQL$INSTANCE) or, where domain authentication is needed, a Group Managed Service Account. The persistence of Domain Admin SQL accounts in audited environments is almost always traceable to a single DBA who needed the service to "just work" against a clustered file share or a linked-server topology and reached for the highest-privilege account that would solve the immediate problem.
Ruta de ataque
1. Discovery: the attacker authenticates with any Domain Users credential and enumerates privileged group membership. With PowerView: Get-DomainGroupMember -Identity "Domain Admins" -Recurse | Select MemberName, MemberObjectClass Or natively: Get-ADGroupMember -Identity "Domain Admins" -Recursive | Where-Object objectClass -eq user 2. SPN filtering: the attacker reads servicePrincipalName on every privileged-group user member and keeps those with database SPNs. Get-DomainUser -SPN -LDAPFilter "(servicePrincipalName=MSSQLSvc/*)" | Where-Object { (Get-DomainGroupMember "Domain Admins" -Recurse).MemberSID -contains $_.objectSid } 3. Kerberoast: the attacker requests a TGS for the SQL SPN using any Domain Users TGT. The TGS is encrypted with the service account NT hash, which is the password hash for svc_sql. Rubeus.exe kerberoast /user:svc_sql /outfile:hashes.txt /nowrap 4. Offline crack: hashcat mode 13100 against rockyou.txt with corp-specific rules cracks the typical "CompanyName2024!" or "SQLAdmin#1" password within minutes on a single GPU. The 2023 Verizon DBIR notes that 86 percent of cracked Kerberoast hashes fall to rules-based attacks against common wordlists. hashcat -m 13100 -a 0 hashes.txt rockyou.txt -r OneRuleToRuleThemAll.rule 5. Pass-the-ticket or direct logon: armed with the cleartext, the attacker authenticates as svc_sql, which is now a Domain Admin. From any joined workstation: runas /netonly /user:CORP\svc_sql cmd.exe net group "Domain Admins" attacker /add /domain 6. Alternate path without cracking: the attacker pivots to the SQL host through any of: a SQL injection in a connected application, an unauthenticated SQL Server CVE, an authenticated SQL login plus xp_cmdshell, or a Reporting Services exposure. Once they have OS execution on the SQL host as the database service account, they already have Domain Admin and skip steps 3 and 4 entirely. 7. LSASS extraction (no-Kerberoast path): if the attacker reaches the SQL host as local admin by any other route (RDP, WMI, PsExec, vulnerable backup agent), they dump LSASS and extract the cleartext or NT hash of the running service account: procdump.exe -accepteula -ma lsass.exe lsass.dmp pypykatz lsa minidump lsass.dmp 8. Persistence: with Domain Admin in hand, the attacker performs a DCSync (T1003.006) against any DC to harvest krbtgt and all account hashes, forges a Golden Ticket, and is now resident at Tier-0 indefinitely.
Cómo lo evalúa Guerrilla
Guerrilla uses System.DirectoryServices.Protocols to bind to the domain root, reads RootDSE -> defaultNamingContext, then issues a single paged LDAP search per privileged group using the LDAP_MATCHING_RULE_IN_CHAIN OID (1.2.840.113556.1.4.1941) against the member attribute. That extended match returns every transitive member in one round trip, including nested groups and primaryGroupID = 512 attachments that a naive member-attribute walk would miss. For each returned user-class principal, the check pulls sAMAccountName, servicePrincipalName, description, userAccountControl, objectClass, msDS-SupportedEncryptionTypes, and adminCount in a single attribute list to minimize wire chatter. Classification of "database service account" is performed against three signals (any one is sufficient): SPN prefix match against the regex ^(MSSQLSvc|MSOLAPSvc\.3|MySQL|postgres)\/, sAMAccountName regex match, or a description-field literal match. The check is read-only, requires only Domain Users membership, and runs against any reachable DC. False-positive suppression is applied to gMSA accounts (objectClass contains msDS-GroupManagedServiceAccount) and to computer accounts. The finding severity is escalated to Critical when the matched account also has a Kerberoastable SPN and the account password has not changed in the past 365 days (read from pwdLastSet), because that combination converts a misconfiguration into an immediately exploitable Kerberoast target.
Valor recomendado
Las cuentas de servicio de base de datos se ejecutan como gMSA o identidades de servicio dedicadas sin pertenencia a grupos privilegiados.
Remediación
Migre las cuentas de servicio de SQL a gMSA donde esté soportado. Para las cuentas que deban seguir basándose en usuario, elimine la pertenencia a grupos privilegiados y conceda únicamente los derechos locales que requiere el motor de base de datos (Iniciar sesión como servicio, Omitir la comprobación de recorrido, Ajustar las cuotas de memoria para un proceso, consulte la documentación de Microsoft para conocer los derechos específicos).
Veredictos probados con fixtures
Cada veredicto de esta tabla está probado por un fixture de referencia en la suite de pruebas que valida el módulo. La tabla se deriva de la última ejecución en verde; no puede editarse a mano.
| Escenario | Veredicto esperado |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Mapeos a marcos de referencia
- NIST SP 800-53
- AC-6
- CIS AD Benchmark
- 8.2.4
- MITRE ATT&CK
- T1078.002