Skip to content

LDAP Overview

¿Qué es LDAP?

LDAP (Lightweight Directory Access Protocol) es el protocolo que usan las aplicaciones para comunicarse con servidores de directorio como Active Directory. La relación entre AD y LDAP es como la de Apache y HTTP: AD es el servidor de directorio y LDAP es el protocolo que usa para hablar.

Una sesión LDAP comienza conectándose a un LDAP server (también llamado Directory System Agent). En AD, el Domain Controller escucha activamente las solicitudes LDAP. Por defecto los mensajes LDAP viajan en texto claro, por lo que pueden ser capturados en la red si no se usa TLS.


Tipos de autenticación LDAP

Simple Authentication incluye autenticación anónima, autenticación no autenticada, y autenticación con usuario y contraseña. Crea un BIND request para autenticarse al servidor LDAP.

SASL Authentication (Simple Authentication and Security Layer) usa otros servicios de autenticación como Kerberos para hacer el bind al servidor LDAP, añadiendo una capa adicional de seguridad al separar los métodos de autenticación del protocolo de aplicación.


Queries LDAP básicas con Get-ADObject

Buscar todos los grupos del dominio

c
Get-ADObject -LDAPFilter '(objectClass=group)' | select name

Buscar todas las cuentas deshabilitadas

c
Get-ADObject -LDAPFilter '(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))' -Properties * | select samaccountname,useraccountcontrol

El valor 2 en userAccountControl:1.2.840.113556.1.4.803:=2 corresponde al bit ACCOUNTDISABLE en el atributo userAccountControl. La cadena 1.2.840.113556.1.4.803 es el OID del operador de bit AND que permite filtrar por flags individuales dentro del atributo.

Buscar todos los usuarios

c
Get-ADObject -LDAPFilter '(&(objectCategory=person)(objectClass=user))' | select name

#Contar usuarios
(Get-ADObject -LDAPFilter '(&(objectCategory=person)(objectClass=user))').Count

Buscar todas las computadoras

c
Get-ADObject -LDAPFilter '(objectCategory=computer)' | select name

Buscar todos los Domain Controllers

c
Get-ADObject -LDAPFilter '(&(objectCategory=Computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))' | select name

El valor 8192 corresponde al bit SERVER_TRUST_ACCOUNT que identifica a los DCs en el atributo userAccountControl.


Referencias de queries LDAP para AD

Queries relacionadas a computadoras en AD: https://ldapwiki.com/wiki/Wiki.jsp?page=Active Directory Computer Related LDAP Query

Queries relacionadas a usuarios en AD: https://ldapwiki.com/wiki/Wiki.jsp?page=Active Directory User Related Searches

Queries relacionadas a grupos en AD: https://ldapwiki.com/wiki/Wiki.jsp?page=Active Directory Group Related Searches

Active Directory Search Filters

¿Qué son los filtros en Active Directory?

Los filtros permiten realizar búsquedas específicas dentro de Active Directory utilizando cmdlets de PowerShell.

Son especialmente útiles cuando no disponemos de herramientas como PowerView y necesitamos enumerar el dominio utilizando únicamente funcionalidades nativas de Windows.


Filtros en PowerShell

Los filtros ayudan a reducir grandes cantidades de resultados para obtener únicamente la información necesaria.

Enumerar software instalado

powershell
Get-CimInstance Win32_Product | fl

Excluir software de Microsoft

powershell
Get-CimInstance Win32_Product -Filter "NOT Vendor like '%Microsoft%'" | fl

Este filtro puede ser útil para identificar software de terceros durante una búsqueda de vectores de escalación de privilegios.


Operadores más utilizados

text
-eq        Igual a
-ne        Distinto de
-gt        Mayor que
-lt        Menor que
-ge        Mayor o igual que
-le        Menor o igual que
-like      Coincide con patrón
-notlike   No coincide con patrón
-and       AND lógico
-or        OR lógico
-not       NOT lógico
-band      Bitwise AND
-bor       Bitwise OR

Sintaxis de filtros

Todas las siguientes consultas son equivalentes:

powershell
Get-ADUser -Filter "name -eq 'sally jones'"

Get-ADUser -Filter {name -eq 'sally jones'}

Get-ADUser -Filter 'name -eq "sally jones"'

Uso de comodines

Buscar usuarios cuyo nombre empiece por "joe":

powershell
Get-ADUser -Filter {name -like "joe*"}

Ejemplos:

text
joe
joel
joesmith

Caracteres especiales

text
"     -> `"
'     -> \'
\     -> \5c
*     -> \2a
(     -> \28
)     -> \29
/     -> \2f
NUL   -> \00

El asterisco normalmente no requiere escape cuando se utiliza con -like.


Buscar servidores SQL

Los SQL Servers suelen ser objetivos interesantes porque frecuentemente ejecutan cuentas de servicio privilegiadas.

c
Get-ADComputer -Filter "DNSHostName -like 'SQL*'"

Ejemplo:

c
SQL01
SQL02
SQL-PROD

Buscar grupos administrativos

El atributo adminCount=1 identifica objetos protegidos por AdminSDHolder.

powershell
Get-ADGroup -Filter "adminCount -eq 1" | Select Name

Ejemplo:

c
Administrators
Domain Admins
Enterprise Admins
Schema Admins
Backup Operators

Buscar usuarios ASREPRoastables privilegiados

c
Get-ADUser -Filter { adminCount -eq '1' -and DoesNotRequirePreAuth -eq 'True'}

Este filtro busca usuarios privilegiados que pueden ser vulnerables a AS-REP Roasting.


Buscar usuarios privilegiados con SPN

c
Get-ADUser -Filter "adminCount -eq '1'" -Properties * |
Where-Object {$_.ServicePrincipalName -ne $null} |
Select SamAccountName,MemberOf,ServicePrincipalName | fl

Este filtro permite identificar cuentas privilegiadas potencialmente vulnerables a Kerberoasting.


Herramientas relacionadas

PowerView

c
Get-DomainUser
Get-DomainComputer
Get-DomainGroup
Get-DomainSPNTicket

Rubeus

ASREPRoasting:

c
Rubeus asreproast

Kerberoasting:

c
Rubeus kerberoast

Cheatsheet

Buscar SQL Servers

powershell
Get-ADComputer -Filter "DNSHostName -like 'SQL*'"

Buscar grupos protegidos

powershell
Get-ADGroup -Filter "adminCount -eq 1"

Buscar usuarios ASREPRoastables

powershell
Get-ADUser -Filter {
    DoesNotRequirePreAuth -eq 'True'
}

Buscar usuarios con SPN

powershell
Get-ADUser -Filter * -Properties ServicePrincipalName |
Where-Object {$_.ServicePrincipalName -ne $null}

Buscar usuarios privilegiados con SPN

powershell
Get-ADUser -Filter "adminCount -eq '1'" -Properties * |
Where-Object {$_.ServicePrincipalName -ne $null}

LDAP Search Filters

Sintaxis básica

Los filtros LDAP usan notación polaca, es decir los operadores van al frente de los criterios. Cada criterio va entre paréntesis.

AND:  (& (criterio1) (criterio2) (criterio3))
OR:   (| (criterio1) (criterio2) (criterio3))
NOT:  (! (criterio))

Anidado: (|(& (C1) (C2))(& (C3) (C4))) equivale a (C1 AND C2) OR (C3 AND C4)


Operadores de comparación en filtros LDAP

(atributo=valor)     Igual a
(!(atributo=valor))  No igual a
(atributo=*)         Presente (tiene cualquier valor)
(!(atributo=*))      No presente (campo vacío)
(atributo>valor)     Mayor que
(atributo<valor)     Menor que
(atributo~=valor)    Aproximadamente igual
(atributo=*algo)     Wildcard

OIDs de matching rules más importantes

1.2.840.113556.1.4.803 es el AND a nivel de bits. Se usa para verificar si un bit específico está activo en userAccountControl. Es el más usado en filtros LDAP de AD.

1.2.840.113556.1.4.804 es el OR a nivel de bits. Devuelve match si cualquiera de los bits coincide.

1.2.840.113556.1.4.1941 es el recursive match. Recorre la cadena de ancestros de un objeto hasta encontrar coincidencia. Se usa para encontrar membresía en grupos de forma recursiva incluyendo grupos anidados.

Referencia completa de sintaxis de filtros: https://docs.microsoft.com/en-us/windows/win32/adsi/search-filter-syntax

Referencia de atributos de usuario en AD: https://docs.microsoft.com/en-us/windows/win32/adschema/attributes-all


Valores clave de userAccountControl

2       ACCOUNTDISABLE           Cuenta deshabilitada
32      PASSWD_NOTREQD           No requiere contraseña
524288  TRUSTED_FOR_DELEGATION   Unconstrained Delegation habilitado
8192    SERVER_TRUST_ACCOUNT     Domain Controller
4194304 DONT_REQ_PREAUTH         No requiere pre-autenticación Kerberos (ASREPRoasteable)

Queries LDAP prácticas por escenario

Cuentas deshabilitadas

c
Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2)' | select name

Usuarios con campo description no vacío (buscar contraseñas)

c
Get-ADUser -Properties * -LDAPFilter '(&(objectCategory=user)(description=*))' | select samaccountname,description

Muy útil en cada assessment. Es común encontrar contraseñas de cuentas de servicio en el campo description.

Usuarios o computadoras con Unconstrained Delegation

c
Get-ADUser -Properties * -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' | select Name,memberof,servicePrincipalName,TrustedForDelegation | fl
c
Get-ADComputer -Properties * -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' | select DistinguishedName,servicePrincipalName,TrustedForDelegation | fl

Los DCs siempre aparecen aquí porque tienen Unconstrained Delegation por diseño. Lo interesante es encontrar otros hosts o cuentas con este flag.

Usuarios admin con PASSWD_NOTREQD

c
Get-ADUser -LDAPFilter '(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))(adminCount=1)' -Properties * | select name,memberof | fl

Combina dos filtros: busca cuentas sin requisito de contraseña que además son cuentas administrativas protegidas por AdminSDHolder.

Todos los grupos de un usuario incluyendo grupos anidados (via OID recursivo)

c
Get-ADGroup -LDAPFilter '(member:1.2.840.113556.1.4.1941:=CN=Harry Jones,OU=Network Ops,OU=IT,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL)' | select Name

Todos los grupos de un usuario incluyendo grupos anidados (via RecursiveMatch)

c
Get-ADGroup -Filter 'member -RecursiveMatch "CN=Harry Jones,OU=Network Ops,OU=IT,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL"' | select name

Ambos comandos devuelven lo mismo. El OID funciona con -LDAPFilter y RecursiveMatch funciona con -Filter. Importante para descubrir membresía indirecta en grupos privilegiados como Domain Admins a través de grupos anidados.


SearchBase y SearchScope

Sirven para limitar el alcance de las búsquedas en dominios grandes y mejorar el rendimiento.

SearchBase define el punto de inicio de la búsqueda usando el Distinguished Name de una OU.

SearchScope define qué tan profundo buscar:

Base (0) devuelve solo el objeto especificado en SearchBase, no sus contenidos. Con Get-ADUser no devuelve nada porque una OU no es un usuario. Con Get-ADObject devuelve el objeto OU en sí.

OneLevel (1) busca solo dentro del contenedor directo definido en SearchBase, sin bajar a sub-OUs.

SubTree (2) busca en el SearchBase y todos los contenedores hijo de forma recursiva hasta el fondo de la jerarquía.

Contar todos los usuarios bajo una OU y sus sub-OUs

c
(Get-ADUser -SearchBase "OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -Filter *).count

Buscar solo en la OU directa sin bajar a sub-OUs

c
Get-ADUser -SearchBase "OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -SearchScope OneLevel -Filter *

Buscar en la OU y todas sus sub-OUs recursivamente

c
Get-ADUser -SearchBase "OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -SearchScope SubTree -Filter *

Buscar usuarios en una OU específica como IT

c
Get-ADUser -SearchBase "OU=IT,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -SearchScope SubTree -Filter * | measure

Caracteres que requieren escape en filtros LDAP

*   →  \2a
(   →  \28
)   →  \29
\   →  \5c
NUL →  \00

Cmdlets de búsqueda en AD

Cada cmdlet apunta a un tipo de objeto distinto. PowerShell agrega automáticamente el filtro de tipo de objeto por debajo, no necesitas especificarlo manualmente.

c
Get-ADUser      # busca objetos de tipo usuario
Get-ADGroup     # busca objetos de tipo grupo
Get-ADComputer  # busca objetos de tipo computadora
Get-ADObject    # busca cualquier tipo de objeto

Tanto -Filter como -LDAPFilter funcionan con todos ellos. La diferencia es que -Filter usa sintaxis PowerShell y -LDAPFilter usa sintaxis LDAP pura.

c
# Cuándo usar -Filter
Get-ADUser -Filter "adminCount -eq 1"           # condición simple

# Cuándo usar -LDAPFilter
Get-ADUser -LDAPFilter '(adminCount=1)'          # mismo resultado
Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2)'  # bits, solo posible con LDAPFilter

Cómo construir filtros desde cero

Paso 1 — Explora un objeto real para ver qué atributos existen

c
Get-ADUser -Filter * -Properties * | select -First 1 | fl

Todo lo que aparece en esa salida es un atributo que puedes usar en un filtro. Toma nota de los nombres que te interesan.

Paso 2 — Busca atributos por nombre si no los recuerdas

c
Get-ADUser -Filter * -Properties * | Get-Member | where {$_.Name -like "*mail*"}

Cambia *mail* por cualquier palabra clave para encontrar atributos relacionados.

Paso 3 — Construye la condición para cada atributo

¿Que tenga cualquier valor?     (atributo=*)
¿Que sea igual a algo?          (atributo=valor)
¿Que NO tenga valor?            (!(atributo=*))
¿Que contenga algo?             (atributo=*texto*)

Paso 4 — Combina condiciones con AND si necesitas varias

(&  (condicion1)  (condicion2)  (condicion3)  )

Paso 5 — Ver valores únicos de un atributo antes de filtrar

c
Get-ADUser -Filter * -Properties department | select department | sort department -Unique

Así sabes qué valores existen en ese atributo en tu entorno antes de construir el filtro.


Trampa importante — nombres PowerShell vs nombres LDAP reales

El nombre que PowerShell muestra en la salida no siempre es el nombre real del atributo en LDAP. Si tu filtro no devuelve nada, verifica el nombre real.

PowerShell muestra       LDAP real
EmailAddress          →  mail
SamAccountName        →  sAMAccountName
ServicePrincipalNames →  servicePrincipalName
DistinguishedName     →  distinguishedName

Dentro de -LDAPFilter el valor va sin comillas dobles:

c
# Incorrecto
Get-ADUser -LDAPFilter '(mail="admin@dominio.local")'

# Correcto
Get-ADUser -LDAPFilter '(mail=admin@dominio.local)'

Enumerating Active Directory with Built-in Tools

UAC — User Account Control Attributes

Los flags de userAccountControl controlan el comportamiento de las cuentas de dominio. Valores clave:

64        PASSWD_CANT_CHANGE
512       NORMAL_ACCOUNT
65536     DONT_EXPIRE_PASSWORD
262144    SMARTCARD_REQUIRED
4194304   DONT_REQ_PREAUTH      (ASREPRoasteable)
32        PASSWD_NOTREQD
2         ACCOUNTDISABLE
524288    TRUSTED_FOR_DELEGATION (Unconstrained Delegation)
8388608   PASSWORD_EXPIRED

Los valores en el campo useraccountcontrol son sumas de los flags activos. Por ejemplo 4260384 = 32 + 512 + 65536 + 4194304 que corresponde a PASSWD_NOTREQD + NORMAL_ACCOUNT + DONT_EXPIRE_PASSWORD + DONT_REQ_PREAUTH.


Enumerar valores UAC con módulo AD nativo

c
Get-ADUser -Filter {adminCount -gt 0} -Properties admincount,useraccountcontrol | select Name,useraccountcontrol

Devuelve los valores numéricos de useraccountcontrol para cuentas administrativas. Hay que convertirlos manualmente o con un script para saber qué flags están activos.

Convertir un valor UAC a sus flags

c
.\Convert-UserAccountControlValues.ps1
# Ingresar el valor numérico cuando lo solicite

Enumerar UAC con PowerView (muestra flags legibles directamente)

c
Get-DomainUser * -AdminCount | select samaccountname,useraccountcontrol

PowerView convierte los valores numéricos a nombres de flags legibles automáticamente, lo que facilita identificar cuentas con configuraciones peligrosas como PASSWD_NOTREQD o DONT_REQ_PREAUTH.


DS Tools — dsquery y dsget

Disponibles por defecto en todos los Windows modernos. Requieren conectividad al dominio.

Buscar usuarios con contraseña que no expira dentro de una OU

c
dsquery user "OU=Employees,DC=inlanefreight,DC=local" -name * -scope subtree -limit 0 | dsget user -samid -pwdneverexpires | findstr /V no

dsquery busca los objetos y pasa el resultado a dsget que extrae atributos específicos. El findstr /V no filtra solo los que tienen yes en pwdneverexpires. El flag -limit 0 elimina el límite de 100 resultados por defecto.


Módulo PowerShell AD — SearchBase

c
# Buscar usuarios dentro de una OU específica
Get-ADUser -Filter * -SearchBase 'OU=Admin,DC=inlanefreight,DC=local'

# Buscar en una OU y todas sus sub-OUs
Get-ADUser -Filter * -SearchBase 'OU=Employees,DC=inlanefreight,DC=local' -SearchScope SubTree

-SearchBase limita la búsqueda a una OU específica en lugar de buscar en todo el dominio. Útil en dominios grandes para afinar resultados.


WMI — Windows Management Instrumentation

WMI puede usarse para consultar objetos de AD desde PowerShell.

c
# Listar grupos del dominio via WMI
Get-WmiObject -Class win32_group -Filter "Domain='INLANEFREIGHT'" | Select Caption,Name

Útil como alternativa cuando no tienes el módulo AD instalado. WMI está disponible en todos los sistemas Windows sin dependencias adicionales.


ADSI — Active Directory Service Interfaces

ADSI es un conjunto de interfaces COM para consultar AD. PowerShell permite usarlas directamente con el tipo [adsisearcher].

c
# Buscar todas las computadoras del dominio
([adsisearcher]"(&(objectClass=Computer))").FindAll() | select Path

# Buscar todos los usuarios
([adsisearcher]"(&(objectClass=user))").FindAll() | select Path

# Buscar usuarios en una OU específica
([adsisearcher]"(&(objectClass=user)(distinguishedName=*OU=Pentest*))").FindAll() | select Path

# Buscar un usuario específico
([adsisearcher]"(sAMAccountName=forend)").FindOne()

[adsisearcher] no requiere el módulo AD instalado ni PowerView. Funciona con las interfaces nativas de Windows y es difícil de detectar porque usa COM directamente.


Consideraciones importantes al usar SearchBase

El DistinguishedName se lee de derecha a izquierda

El path de una OU en AD va desde lo más específico a la izquierda hasta la raíz a la derecha. Si ves OU=Pentest,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL significa:

DC=INLANEFREIGHT,DC=LOCAL   ← raíz del dominio
  └── OU=Employees          ← OU padre
        └── OU=Pentest      ← OU hija (la que buscas)

Si pones solo OU=Pentest,DC=INLANEFREIGHT,DC=LOCAL vas a obtener Directory object not found porque le estás diciendo que Pentest está directamente en la raíz del dominio, cuando en realidad está anidada dentro de Employees.

Buscar el path exacto de una OU antes de usarlo como SearchBase

c
# Buscar una OU por nombre para obtener su DistinguishedName completo
Get-ADOrganizationalUnit -Filter {Name -like "*Pentest*"} | select DistinguishedName

# Listar todas las OUs del dominio
Get-ADOrganizationalUnit -Filter * | select Name,DistinguishedName

# Con dsquery
dsquery ou -name "Pentest"

Siempre busca el DistinguishedName completo antes de usarlo en SearchBase, nunca asumas la ruta.

Errores comunes con SearchBase

Directory object not found casi siempre significa que el path del SearchBase está incompleto o tiene una OU padre que no incluiste. Busca el DN completo con Get-ADOrganizationalUnit primero.

SearhScope con un solo c es un typo — el parámetro correcto es -SearchScope con doble c.

SearchScope — cuándo agregarlo

Si la OU tiene sub-OUs y quieres buscar en todas ellas, agrega -SearchScope SubTree. Si solo quieres los objetos directamente dentro de esa OU sin bajar más, usa -SearchScope OneLevel. Sin especificarlo, el comportamiento por defecto es SubTree.

c
# Solo usuarios directamente en Pentest (sin sub-OUs)
Get-ADUser -Filter * -SearchBase 'OU=Pentest,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL' -SearchScope OneLevel

# Usuarios en Pentest y todas sus sub-OUs
Get-ADUser -Filter * -SearchBase 'OU=Pentest,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL' -SearchScope SubTree

Casos prácticos de enumeración

Buscar usuario por valor exacto de userAccountControl

c
# Con módulo AD
Get-ADUser -Filter {userAccountControl -eq 262656} -Properties userAccountControl | select SamAccountName,userAccountControl
 
# Con LDAPFilter
Get-ADUser -LDAPFilter '(userAccountControl=262656)' | select SamAccountName

El valor exacto 262656 = 512 + 262144 = NORMAL_ACCOUNT + SMARTCARD_REQUIRED. Si no sabes qué flags componen el valor, descomponlo sumando los valores de la tabla UAC hasta llegar al número.

Buscar usuario con PASSWD_NOTREQD

c
Get-ADUser -Filter {PasswordNotRequired -eq $true} | select SamAccountName
 
# Con LDAPFilter
Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=32)' | select SamAccountName

Buscar en qué grupo está anidado un grupo

c
Get-ADGroup -Identity "IT Support" -Properties MemberOf | select MemberOf
 
# Más limpio
(Get-ADGroup -Identity "IT Support" -Properties MemberOf).MemberOf

Quién es miembro de un grupo a través de membresía anidada

c
Get-ADGroupMember -Identity "IT Support" -Recursive | select Name,SamAccountName,ObjectClass

-Recursive resuelve toda la cadena de grupos anidados y devuelve solo los usuarios finales.

Contar usuarios en una OU específica

c
# Primero encontrar el DN completo de la OU
Get-ADOrganizationalUnit -Filter {Name -like "*Former*"} | select DistinguishedName
 
# Luego contar
(Get-ADUser -SearchBase "OU=Former Employees,DC=INLANEFREIGHT,DC=LOCAL" -Filter *).Count

Buscar computadora por nombre parcial (obtener FQDN)

c
Get-ADComputer -Filter {Name -like "RD*"} -Properties DNSHostName | select Name,DNSHostName

Contar grupos con adminCount = 1

c
(Get-ADGroup -Filter {adminCount -eq 1}).Count
 
# Con LDAPFilter
(Get-ADGroup -LDAPFilter '(adminCount=1)').Count

Buscar usuario ASREPRoasteable que NO sea Protected User

c
# Paso 1 — usuarios ASREPRoasteables
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} | select SamAccountName
 
# Paso 2 — usuarios en Protected Users
Get-ADGroupMember -Identity "Protected Users" | select SamAccountName
 
# Cruzar ambas listas y encontrar el que NO esté en Protected Users
$asrep = Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} | select -ExpandProperty SamAccountName
$protected = Get-ADGroupMember -Identity "Protected Users" | select -ExpandProperty SamAccountName
$asrep | Where-Object {$_ -notin $protected}

Buscar la cuenta con un SPN configurado

c
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName | select SamAccountName,ServicePrincipalName
 
# Con LDAPFilter
Get-ADUser -LDAPFilter '(servicePrincipalName=*)' | select SamAccountName

Ver privilegios no estándar del usuario actual

c
whoami /priv

Compara la salida con los privilegios por defecto de un usuario normal. Cualquier privilegio adicional como SeBackupPrivilege, SeImpersonatePrivilege, SeDebugPrivilege o SeTakeOwnershipPrivilege es no estándar y potencialmente explotable.


Cuándo usar cada herramienta

DS Tools (dsquery/dsget) son útiles cuando estás en CMD sin PowerShell disponible o cuando AppLocker bloquea scripts PS. Vienen instalados por defecto.

Módulo AD (Get-ADUser, Get-ADGroup) es la opción más cómoda cuando está instalado. Requiere ser miembro del dominio o tener conectividad al DC.

WMI (Get-WmiObject) sirve como alternativa cuando no tienes el módulo AD. Siempre disponible en Windows.

ADSI ([adsisearcher]) es la opción más sigilosa ya que usa interfaces COM nativas y no carga módulos adicionales que puedan disparar alertas.

PowerView y SharpView ofrecen las funciones más avanzadas y combinan todas las técnicas anteriores con mejor usabilidad.