Obtener controladores de dominio del dominio actual
Herramienta
Comando
PowerView
AD Module
CMD
Obtener controladores de dominio del otro dominio
Herramienta
Comando
PowerView
AD Module
Usuarios
Obtener una lista de usuarios del dominio actual
Herramienta
Comando
PowerView
AD Module
Net
Obtener información/propiedades de un usuario
Herramienta
Comando
PowerView
AD Module
Net
Obtener los usuarios no administradores con permisos de edición de GPOs
Import-Module ActiveDirectory
$Results = @()
# Obtener todos los objetos GPO
$GPOs = Get-ADObject -Filter { ObjectClass -eq 'groupPolicyContainer' } -Properties nTSecurityDescriptor
foreach ($GPO in $GPOs) {
$acls = $GPO.nTSecurityDescriptor.DiscretionaryAcl
foreach ($acl in $acls) {
if ($acl.AccessControlType -eq "Allow") {
$sid = New-Object System.Security.Principal.SecurityIdentifier($acl.SecurityIdentifier)
$account = try { $sid.Translate([System.Security.Principal.NTAccount]).Value } catch { $null }
if ($account -and ($account -notmatch "Administrators")) {
if ($acl.ActiveDirectoryRights -match "WriteProperty|GenericWrite|WriteDacl|WriteOwner") {
$Results += [PSCustomObject]@{
GPOName = $GPO.Name
Account = $account
Rights = $acl.ActiveDirectoryRights
}
}
}
}
}
}
# Incluir la fecha en el nombre del archivo
$Date = Get-Date -Format "yyyyMMdd"
$FileName = ".\GPO_Permissions_Report_$Date.csv"
# Exportar resultados a CSV
$Results | Export-Csv -Path $FileName -NoTypeInformation
Write-Output "Reporte exportado a $FileName"
Obtener los usuarios privilegiados que no se encuentran en el grupo de usuarios protegidos
Import-Module ActiveDirectory
# Obtener miembros de grupos privilegiados
$PrivilegedGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators")
$PrivilegedUsers = foreach ($Group in $PrivilegedGroups) {
Get-ADGroupMember -Identity $Group -Recursive | Where-Object { $_.objectClass -eq 'user' }
}
# Obtener usuarios del grupo Protected Users
$ProtectedUsers = Get-ADGroupMember -Identity "Protected Users" -Recursive | Where-Object { $_.objectClass -eq 'user' }
# Preparar resultados
$Results = foreach ($User in $PrivilegedUsers) {
$adUser = Get-ADUser -Identity $User.SamAccountName -Properties adminCount
$isProtected = $ProtectedUsers.SamAccountName -contains $User.SamAccountName
$isVulnerable = if (-not $isProtected -or $adUser.adminCount -ne 1) { $true } else { $false }
[PSCustomObject]@{
Name = $User.Name
SamAccountName = $User.SamAccountName
DistinguishedName = $User.DistinguishedName
InProtectedUsers = $isProtected
AdminCount = $adUser.adminCount
IsVulnerable = $isVulnerable
}
}
# Incluir la fecha en el nombre del archivo
$Date = Get-Date -Format "yyyyMMdd"
$FileName = ".\Privileged_Users_Status_$Date.csv"
# Exportar resultados a CSV
$Results | Export-Csv -Path $FileName -NoTypeInformation
Write-Output "Reporte exportado a $FileName"
Obtiene los usuarios miembros de grupos privilegiados.
Compara contra los miembros del grupo Protected Users.
Consulta el atributo adminCount de cada usuario.
Agrega columnas:
Si pertenece o no a Protected Users.
El valor de adminCount.
Si es considerado vulnerable (por no estar en Protected Users o por no tener adminCount = 1).
Incluye la fecha en el nombre del CSV para trazabilidad.
Grupos
Obtener grupos
Herramienta
Comando
PowerView
Net
Obtener propiedades de un grupo
Herramienta
Comando
AD Module
Net
Obtener grupos a los que pertenece un grupo
Herramienta
Comando
AD Module
Obtener todos los miembros de todos los grupos de forma recursiva
# Obtener todos los grupos del dominio
$allGroups = Get-ADGroup -Filter *
# Crear lista para guardar resultados
$groupMembers = @()
# Iterar sobre cada grupo
foreach ($group in $allGroups) {
try {
$members = Get-ADGroupMember -Identity $group.SamAccountName -Recursive -ErrorAction Stop
foreach ($member in $members) {
$groupMembers += [PSCustomObject]@{
GroupName = $group.Name
GroupSamAccount = $group.SamAccountName
MemberName = $member.Name
MemberSamAccount = $member.SamAccountName
MemberObjectClass = $member.ObjectClass
DistinguishedName = $member.DistinguishedName
}
}
} catch {
Write-Warning "Error al enumerar miembros del grupo $($group.SamAccountName): $_"
}
}
# Mostrar en formato tabla en consola
$groupMembers | Format-Table -AutoSize
# Exportar a CSV
$groupMembers | Export-Csv -NoTypeInformation -Encoding UTF8 -Path ".\domain_group_members_recursive.csv"
Obtener los miembros recursivos del grupo "Domain Admins"
$domainAdmins = Get-DomainGroupMember -Identity "Domain Admins" -Recurse
# Mostrar los resultados en formato tabla
$domainAdmins | Select-Object Name, SamAccountName, ObjectClass, DistinguishedName | Format-Table -AutoSize
# Exportar todos los atributos disponibles a un fichero CSV
$domainAdmins | Select-Object * | Export-Csv -Path ".\domain_admins_members.csv" -NoTypeInformation -Encoding UTF8
Obtener todos los grupos con "admin" y sus miembros (si los hay)
# Enumerar grupos con "admin" en el nombre
$adminGroups = Get-DomainGroup -LDAPFilter "(name=*admin*)"
# Crear una lista para todos los resultados
$allAdminGroupMembers = @()
foreach ($group in $adminGroups) {
try {
# Intentar obtener los miembros del grupo
$members = Get-DomainGroupMember -Identity $group.DistinguishedName -Recurse -ErrorAction Stop
if ($members.Count -eq 0) {
# Grupo sin miembros
$entry = [PSCustomObject]@{
GroupName = $group.Name
Name = ''
SamAccountName = ''
ObjectClass = ''
DistinguishedName = ''
}
$allAdminGroupMembers += $entry
} else {
# Agregar cada miembro al array
foreach ($member in $members) {
$member | Add-Member -NotePropertyName GroupName -NotePropertyValue $group.Name -Force
$allAdminGroupMembers += $member
}
}
} catch {
# Si el grupo no permite consultar miembros, registrar igual el grupo vacío
Write-Warning "❌ Error en grupo '$($group.Name)': $_"
$entry = [PSCustomObject]@{
GroupName = $group.Name
Name = 'ERROR'
SamAccountName = ''
ObjectClass = ''
DistinguishedName = ''
}
$allAdminGroupMembers += $entry
}
}
# Mostrar en tabla los resultados clave
$allAdminGroupMembers |
Select-Object GroupName, Name, SamAccountName, ObjectClass, DistinguishedName |
Format-Table -AutoSize
# Exportar todo a CSV
$allAdminGroupMembers |
Select-Object * |
Export-Csv -Path ".\admin_groups_members_full.csv" -NoTypeInformation -Encoding UTF8
Equipos / Servidores
Obtener equipos/servidores
Herramienta
Comando
PowerView
Unidades organizativas
Obtener unidades organizativas
Herramienta
Comando
PowerView
Obtener todos los equipos asociados a una unidad organizativa
Herramienta
Comando
PowerView
Obtener GPLink asociada a una unidad organizativa
Herramienta
Comando
PowerView
El siguiente comando une los dos anteriores en uno:
Política de contraseñas
Herramienta
Comando
Net
ACL (Listas de control de acceso)
Obtener las ACLs
GUI con Out-GridView:
Invoke-ACLScanner -ResolveGUIDs | Out-GridView
PowerShell:
Herramienta
Comando
PowerView
Obtener los ACLs de un objeto, por ejemplo, "Administrator"
# Obtener los ACLs del objeto 'Administrator'
$acls = Get-DomainObjectAcl -SamAccountName Administrator -ResolveGUIDs
# Resolver el SID de cada ACL manualmente si no está ya resuelto
foreach ($acl in $acls) {
if (-not $acl.IdentityReference) {
try {
$sidObj = New-Object System.Security.Principal.SecurityIdentifier($acl.SecurityIdentifier)
$acl | Add-Member -NotePropertyName "IdentityReference" -NotePropertyValue $sidObj.Translate([System.Security.Principal.NTAccount]) -Force
} catch {
$acl | Add-Member -NotePropertyName "IdentityReference" -NotePropertyValue $acl.SecurityIdentifier -Force
}
}
}
# Mostrar campos clave
$acls | Select-Object IdentityReference, ActiveDirectoryRights, ObjectAceType, InheritanceFlags, AceType, IsInherited |
Format-Table -AutoSize
# Exportar todos los campos a CSV
$acls | Select-Object * | Export-Csv -Path ".\administrator_objectacls_full.csv" -NoTypeInformation -Encoding UTF8
Write-Host "`nExportación completada: administrator_objectacls_full.csv" -ForegroundColor Green
Obtener los ACLs de SYSVOL
# Ruta SYSVOL adaptada a tu dominio actual
$sysvolPath = "\\dc.xtormincorp.local\SYSVOL"
# Obtener ACL del recurso compartido
$acl = Get-PathAcl -Path $sysvolPath
# Mostrar campos clave en tabla
$acl | Select-Object IdentityReference, FileSystemRights, AccessControlType, IsInherited, InheritanceFlags, PropagationFlags |
Format-Table -AutoSize
# Exportar todos los datos a CSV
$acl | Select-Object * | Export-Csv -Path ".\sysvol_acl_full.csv" -NoTypeInformation -Encoding UTF8
Write-Host "`nExportación completada: sysvol_acl_full.csv" -ForegroundColor Green
Lo mismo, pero recursivo:
# Ruta SYSVOL adaptada a tu dominio
$rootPath = "\\dc.xtormincorp.local\SYSVOL"
# Array para almacenar todos los ACLs
$allACLs = @()
# Obtener recursivamente todos los archivos y carpetas
$items = Get-ChildItem -Path $rootPath -Recurse -Force -ErrorAction SilentlyContinue
# Añadir también la raíz
$items += Get-Item -Path $rootPath
foreach ($item in $items) {
try {
$acl = Get-PathAcl -Path $item.FullName
foreach ($entry in $acl) {
$entry | Add-Member -NotePropertyName Path -NotePropertyValue $item.FullName -Force
$allACLs += $entry
}
} catch {
Write-Warning "❌ Error al obtener ACL de: $($item.FullName)"
}
}
# Mostrar en tabla campos clave
$allACLs |
Select-Object Path, IdentityReference, FileSystemRights, AccessControlType, IsInherited |
Format-Table -AutoSize
# Exportar todos los campos a CSV
$allACLs | Select-Object * | Export-Csv -Path ".\sysvol_recursive_acls.csv" -NoTypeInformation -Encoding UTF8
Write-Host "`nExportación completada: sysvol_recursive_acls.csv" -ForegroundColor Green
Obtener ACLs que podrían ser interesantes
Herramienta
Comando
PowerView
GPO
Se enumera información sobre las políticas de grupo e información de la configuración del usuario. Como los grupos de seguridad a los que pertenece, versión del sistema operativo, nombre de dominio, etc.
Herramienta
Comando
PowerView
CMD
Objetos AD
Obtener todos los objetos que hayan cambiado tras una determinada fecha
Herramienta
Comando
AD Module
Enumerar cuentas que cuenten con un badPwdCount > 0
Esto es útil para enumerar las cuentas que ya cuenten con intentos de contraseñas fallidas. ¿Y por qué es interesante este dato? Porque antes de hacer un ataque de password spraying, se pueden omitir estas cuentas de la prueba para evitar bloquearlas:
Herramienta
Comando
AD Module
Sesiones activas
Enumerar todas las sesiones usando el fichero CSV de equipos listado en el script anterior:
# Cargar equipos desde el CSV exportado anteriormente
$computers = Import-Csv -Path ".\domain_computers.csv"
# Array para almacenar resultados
$userSessions = @()
foreach ($computer in $computers) {
$hostname = $computer.dnshostname
if (-not $hostname) {
Write-Warning ("El equipo {0} no tiene un DNS hostname definido, se omite." -f $computer.name)
continue
}
Write-Host "`nObteniendo sesiones de: $hostname" -ForegroundColor Cyan
$result = [PSCustomObject]@{
Hostname = $hostname
NetLoggedOnUsers = $null
LocallyLoggedUsers = $null
LastLoggedUser = $null
}
try {
$netLogged = Get-NetLoggedon -ComputerName $hostname
if ($netLogged) {
$result.NetLoggedOnUsers = ($netLogged | Select-Object -ExpandProperty UserName) -join ', '
}
} catch {
$msg = $_.Exception.Message
Write-Warning ("Error en Get-NetLoggedon para {0}: {1}" -f $hostname, $msg)
}
try {
$localLogged = Get-LoggedonLocal -ComputerName $hostname
if ($localLogged) {
$result.LocallyLoggedUsers = ($localLogged | Select-Object -ExpandProperty UserName) -join ', '
}
} catch {
$msg = $_.Exception.Message
Write-Warning ("Error en Get-LoggedonLocal para {0}: {1}" -f $hostname, $msg)
}
try {
$lastLogged = Get-LastLoggedOn -ComputerName $hostname
if ($lastLogged) {
$result.LastLoggedUser = $lastLogged.UserName
}
} catch {
$msg = $_.Exception.Message
Write-Warning ("Error en Get-LastLoggedOn para {0}: {1}" -f $hostname, $msg)
}
$userSessions += $result
}
# Mostrar en tabla
$userSessions | Format-Table -AutoSize
# Exportar a CSV
$userSessions | Export-Csv -Path ".\user_sessions_all.csv" -NoTypeInformation -Encoding UTF8
Write-Host "`nSesiones exportadas a 'user_sessions_all.csv'" -ForegroundColor Green
Enumerar las sesiones de todas las máquinas remotas