RID cycling
En Active Directory cada cuenta (usuario, equipo o grupo) tiene un SID con la forma S-1-5-21-<domain-id>-<RID>, donde el RID (Relative Identifier) es el número que distingue a esa cuenta dentro del dominio. Los RID se asignan de forma predecible: 500 es el Administrador integrado, 501 el invitado, 502 el krbtgt, y a partir de 1000 se reparten secuencialmente entre las cuentas creadas. El RID cycling (o fuerza bruta de RID) consiste en recorrer ese rango preguntando al controlador de dominio, vía SMB/MS-RPC (LSAR/SAMR), qué nombre corresponde a cada RID, reconstruyendo así la lista de usuarios.
La gracia es que, en muchas configuraciones, este sondeo funciona con una sesión de invitado o nula, sin credenciales válidas (ver smb-guest-enum). Cuando la enumeración directa de usuarios (--users, enum4linux --U) está capada pero la cuenta guest no está deshabilitada, el RID brute suele seguir abierto porque resuelve SID a nombre por un camino distinto.
Mecanismo
netexec/crackmapexec recorre el rango de RID de un tirón; con sesión nula o guest:
netexec smb <dc> -u guest -p '' --rid-brute
netexec smb <dc> -u '' -p '' --rid-brute 20000 # ampliando el rango por defecto (4000)La salida lista cada RID con su cuenta y el tipo (SidTypeUser, SidTypeGroup, SidTypeAlias). Filtrando por SidTypeUser se obtiene la lista de usuarios del dominio:
498: <DOM>\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: <DOM>\Administrator (SidTypeUser)
1104: <DOM>\jsmith (SidTypeUser)
1105: <DOM>\mholliday (SidTypeUser)impacket-lookupsid hace lo mismo por SAMR/LSAR y admite el rango como último argumento; rpcclient lo permite a mano combinando lookupnames, enumdomusers y queryuser:
impacket-lookupsid.py 'guest@<dc>' 20000 # con creds: <domain>/<user>:<pass>@<dc>
impacket-lookupsid.py '<domain>/<user>:<pass>@<dc>' | grep SidTypeUser
rpcclient -U "" -N <dc> -c "enumdomusers" # si la enum directa esta abierta
rpcclient -U "" -N <dc> -c "queryuser 0x457" # detalle de un RID concreto (hex)
enum4linux-ng -R <dc> # RID cycling integrado, salida YAML/JSONCon enum4linux-ng el barrido va integrado (-R) y la salida sale ya normalizada. Ese listado es materia prima para un password-spraying o para buscar pistas en el campo description. La lista también incluye cuentas de máquina (HOST$), válidas para otros ataques (RBCD, coacción, Delegate to me).
Requisitos
Acceso SMB/RPC al DC y una sesión que resuelva SID a nombre: normalmente nula o guest, aunque cualquier credencial válida sirve y suele devolver más. No requiere el permiso de enumeración directa de usuarios, por eso funciona donde --users falla.
Cómo detectarlo. El barrido resuelve SID a nombre en bloque, y ese patrón es la firma. En el DC, con la auditoría de acceso a SAM activa, aparecen Event ID 4661 (se solicitó un identificador para un objeto) en serie, y las operaciones SamrLookupIdsInDomain/LsarLookupSids sobre RIDs consecutivos (1000, 1001, 1002…). Suele venir precedido de un 4624 anónimo o de guest (ver smb-guest-enum). La clave no es una consulta suelta (legítima) sino cientos secuenciales desde un mismo origen en segundos. En red, el tráfico MS-RPC a \samr/\lsarpc con lookups incrementales es igual de reconocible.
Defensa. Deshabilitar la cuenta guest (net user guest /active:no) y restringir el acceso anónimo/invitado a SAMR (RestrictAnonymous, RestrictAnonymousSAM = 1 en la GPO de Domain Controllers). Windows Server 2019/2022 ya lo restringe por defecto, pero muchas migraciones lo dejan abierto. Se apoya en la enumeración guest/nula y alimenta el password-spraying y la enumeración de usuarios.