Skip to content

Enumeration with NetExec and WinRM

After obtaining initial credentials on an HTB Windows / Active Directory machine, this guide walks through what to check with NetExec and where to investigate after connecting through WinRM.

It covers:

  • Initial SMB, LDAP, and WinRM checks with netexec / nxc.
  • How to assess shares, users, groups, computers, and WinRM candidates.
  • Manual enumeration of the user, host, files, credentials, domain, and shares after connecting through WinRM.
  • Using winPEAS to catch gaps in manual enumeration.

Related pages cover individual mechanisms such as AD ACLs and Kerberos delegation in more detail.

First, establish name resolution for the target, domain, and DC.

<dc-ip> <dc-fqdn> <domain> <hostname>

Example:

10.129.13.247 DC01.checkpoint.htb checkpoint.htb DC01

The following command examples use these values.

Terminal window
DC='<dc-fqdn-or-ip>'
DC_FQDN='<dc-fqdn>'
DOMAIN='<domain>'
REALM='<DOMAIN uppercase>'
USER='<user>'
PASS='<password>'
HASH='<nt-hash>'

For Kerberos, prefer an FQDN over an IP address. Even if /etc/hosts resolves the name, obtaining a TGT or TGS may fail if MIT Kerberos has the wrong realm mapping.

Before using netexec, read the Nmap output for clues about the environment.

ObservationInterpretation
53, 88, 389, 445, 464, 3268, 9389Evidence that the host is a Domain Controller (DC).
Domain: <domain> on 389 / 3268LDAP / Global Catalog has revealed the domain name.
5985/tcp openWinRM is worth trying once you have valid credentials. The port alone does not imply authorization.
smb2-security-mode: signing requiredPrioritize authenticated SMB/LDAP/Kerberos enumeration instead of SMB relay as the main path.
Large clock-skewCan cause failures in Kerberos, BloodHound/RustHound, and TGS requests.
LDAP signing / channel binding / NTLM:FalseClues about LDAP authentication, relay feasibility, and whether Kerberos is required.

If Kerberos returns KRB_AP_ERR_SKEW, align the attack machine’s clock with the target. HTB notes include use of ntpdate <dc-fqdn> and faketime.

Terminal window
sudo ntpdate "$DC_FQDN"
FAKETIME_DONT_FAKE_MONOTONIC=1 faketime '+7 hours' <kerberos-command>

After obtaining initial credentials, examine authentication and authorization separately for each protocol.

Terminal window
netexec smb "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS"
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS"
netexec winrm "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS"

Distinguish these results:

ResultMeaning
SMB +The credentials were accepted by SMB. This does not necessarily mean a share is readable.
LDAP +The credentials can be used for authenticated AD object enumeration. This does not imply WinRM access.
WinRM + / Pwn3d!A candidate for a WinRM shell. Obtain a prompt with evil-winrm to confirm it.
WinRM -Does not necessarily mean the password is wrong. Suspect insufficient authorization, such as lack of Remote Management Users membership, or an authentication mechanism mismatch.
STATUS_NOT_SUPPORTED with NTLM:FalseNTLM is probably disabled or unavailable. Switch to Kerberos.
No Kerberos credentials availableA ccache selection problem, not a password problem.

In Puppy, Pirate, and Checkpoint, SMB/LDAP succeeded but the initial user could not use WinRM. In Administrator, the initial user could use WinRM too. Check separately that port 5985 is open, the credentials are valid, and the account is authorized for WinRM.

If NTLM is unavailable, the account belongs to Protected Users, or you want to use Kerberos explicitly, obtain a TGT and use the cache.

Terminal window
getTGT.py "$DOMAIN/$USER:$PASS" -dc-ip '<dc-ip>'
export KRB5CCNAME="$USER.ccache"
netexec smb "$DC_FQDN" --use-kcache --shares --rid-brute
netexec ldap "$DC_FQDN" --use-kcache --users --groups --computers
netexec winrm "$DC_FQDN" --use-kcache

WinRM / WSMan uses a TGS for the HTTP/<host> service principal (SPN). A TGT shows that the user authenticated to the KDC; it is not the ticket presented directly to the WinRM server. For KRB_AP_ERR_MODIFIED, check the hostname, SPN, realm, and ccache.

Adding an FQDN to /etc/hosts alone may not tell MIT Kerberos that <dc-fqdn> belongs to the correct realm. If needed, create a target-specific krb5.conf and specify it with KRB5_CONFIG.

For temporary use, put it under /tmp.

Terminal window
cat > /tmp/krb5-example.conf <<'EOF'
[libdefaults]
default_realm = EXAMPLE.HTB
dns_lookup_realm = false
dns_lookup_kdc = false
rdns = false
udp_preference_limit = 1
[realms]
EXAMPLE.HTB = {
kdc = dc01.example.htb
admin_server = dc01.example.htb
}
[domain_realm]
.example.htb = EXAMPLE.HTB
example.htb = EXAMPLE.HTB
dc01.example.htb = EXAMPLE.HTB
EOF
export KRB5_CONFIG=/tmp/krb5-example.conf

Obtain a TGT and explicitly select the ccache to use.

Terminal window
getTGT.py 'example.htb/<user>:<password>' -dc-ip '<dc-ip>'
export KRB5CCNAME='<user>.ccache'
klist

Check that you can obtain a TGS for the service principal you will actually use, not just a TGT.

Terminal window
KRB5_TRACE=/dev/stderr kvno "ldap/dc01.example.htb"
KRB5_TRACE=/dev/stderr kvno "cifs/dc01.example.htb"
KRB5_TRACE=/dev/stderr kvno "http/dc01.example.htb"
klist
SPNMain use
ldap/<dc-fqdn>LDAP queries, BloodHound / RustHound, and ADSI tools.
cifs/<dc-fqdn>SMB shares and netexec smb --use-kcache.
http/<dc-fqdn>WinRM / WSMan and Evil-WinRM Kerberos.

If a TGS request resolves to another realm or cannot find the KDC, check [domain_realm], default_realm, and which file KRB5_CONFIG references.

For a persistent setup, place each target’s configuration under ~/.config/krb5/.

Terminal window
mkdir -p ~/.config/krb5 ~/.ccache
cat > ~/.config/krb5/example.htb.conf <<'EOF'
[libdefaults]
default_realm = EXAMPLE.HTB
dns_lookup_realm = false
dns_lookup_kdc = false
rdns = false
udp_preference_limit = 1
[realms]
EXAMPLE.HTB = {
kdc = dc01.example.htb
admin_server = dc01.example.htb
}
[domain_realm]
.example.htb = EXAMPLE.HTB
example.htb = EXAMPLE.HTB
dc01.example.htb = EXAMPLE.HTB
EOF

Aliases in ~/.zshrc or ~/.bashrc make it easy to switch Kerberos configuration and ccaches for each box.

Terminal window
alias krb_example='export KRB5_CONFIG=$HOME/.config/krb5/example.htb.conf; export KRB5CCNAME=$HOME/.ccache/example.htb.ccache; klist'
alias krb_off='unset KRB5_CONFIG KRB5CCNAME'

Reload the profile.

Terminal window
source ~/.zshrc
# Or
source ~/.bashrc

Usage:

Terminal window
krb_example
# If kinit is available, create the TGT directly at the KRB5CCNAME location
kinit '<user>@EXAMPLE.HTB'
klist

With Impacket’s getTGT.py, move the resulting ccache to the location referenced by the alias.

Terminal window
getTGT.py 'example.htb/<user>:<password>' -dc-ip '<dc-ip>'
mv '<user>.ccache' "$HOME/.ccache/example.htb.ccache"
krb_example
netexec ldap dc01.example.htb --use-kcache --users --groups
netexec smb dc01.example.htb --use-kcache --shares
evil-winrm -i dc01.example.htb -r example.htb --ccache "$HOME/.ccache/example.htb.ccache"
krb_off

Do not put passwords in the profile. Store only the switches for KRB5_CONFIG and KRB5CCNAME.

When you obtain an NT hash, test it with both SMB and WinRM first.

Terminal window
netexec smb "$DC" -d "$DOMAIN" -u "$USER" -H "$HASH" --shares
netexec winrm "$DC" -d "$DOMAIN" -u "$USER" -H "$HASH"
evil-winrm-py -i "$DC" -u "$USER" -H "$HASH"

Quote machine accounts and gMSAs so the shell does not expand the trailing $.

Terminal window
evil-winrm-py -i "$DC" -u 'gMSA_ADCS_prod$' -H '<nt-hash>'

Use --local-auth only when testing a standalone host or local administrator credentials. Do not confuse it with normal domain authentication on a Domain Controller.

Terminal window
netexec smb '<host>' -u '<local-user>' -p '<password>' --local-auth
netexec winrm '<host>' -u '<local-user>' -p '<password>' --local-auth
Terminal window
netexec smb "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" --shares --rid-brute

READ on IPC$, NETLOGON, and SYSVOL is a normal baseline for a domain user. Prioritize shares with business-related names such as DEV, Logs, IT, VMBackups, DevDrop, or Finance.

Terminal window
smbclient "//$DC_FQDN/<share>" -U "$DOMAIN/$USER%$PASS" -m SMB3

With an NT hash:

Terminal window
smbclient "//$DC_FQDN/<share>" \
-U "$DOMAIN/$USER%$HASH" \
--pw-nt-hash -m SMB3

Seeing a share name does not mean you can read it. In Puppy, DEV was visible initially, but READ became available only after changing group membership. In Checkpoint, VMBackups was visible but unreadable to the initial user; it became useful after retrying as svc_deploy, a member of BackupAccess.

Once inside an SMB share, specify paths relative to the share root. When connected to //dc/IT, the remote path is already equivalent to C:\IT; specifying C:\IT\... may produce NT_STATUS_OBJECT_NAME_INVALID.

Inspect users, groups, and computers with LDAP

Section titled “Inspect users, groups, and computers with LDAP”
Terminal window
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" \
--users --groups --computers

Start with:

ObjectPoints to inspect
userssvc_*, *_adm, job titles, descriptions, password hints, and disabled status.
groupsRemote Management Users, business groups, and Backup/Recovery/IT/WSUS/Certificate-related groups.
computersServers besides the DC, pre-created computer accounts, and machine accounts.
gMSAmsDS-GroupMSAMembership and membership in Remote Management Users.
descriptionsPasswords, operational notes, owners, and clues about share names.

Narrow down candidate users with an LDAP query.

Terminal window
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" \
--query "(sAMAccountName=<target-user>)" \
"sAMAccountName memberOf description userAccountControl servicePrincipalName"

Membership in Remote Management Users indicates a WinRM candidate; it does not prove that a password or hash is valid. A name such as BackupAccess does not necessarily imply SeBackupPrivilege either. In Checkpoint, svc_deploy belonged to BackupAccess, but whoami /all showed no SeBackupPrivilege; its actual benefit was READ on the VMBackups share.

Kerberoasting and AS-REP Roasting candidates

Section titled “Kerberoasting and AS-REP Roasting candidates”

Trying AS-REP roasting or Kerberoasting with initial credentials can be worthwhile, but finding no candidates is common.

Terminal window
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" --asreproast asrep.hashes
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" --kerberoasting kerberoast.hashes

Or with Impacket:

Terminal window
GetNPUsers.py "$DOMAIN/$USER:$PASS" -dc-ip '<dc-ip>' -request -outputfile asrep.hashes
GetUserSPNs.py "$DOMAIN/$USER:$PASS" -dc-ip '<dc-ip>' -request -outputfile kerberoast.hashes

Targeted Kerberoasting is more than enumeration: it requires an ACL that permits temporarily changing the target’s servicePrincipalName. See the AD ACL guide for details.

Read relationships with BloodHound / RustHound

Section titled “Read relationships with BloodHound / RustHound”
Terminal window
rusthound-ce -d "$DOMAIN" -f "$DC_FQDN" -u "$USER" -p "$PASS" -c All --zip

Treat BloodHound as a map of LDAP attributes, group memberships, ACLs, SPNs, and delegation, not merely a tool for clicking the shortest path.

Separate these elements when reviewing a finding:

  • Principal: Who holds the right.
  • Object: Which user, group, computer, OU, or domain the right applies to.
  • Edge: What GenericAll, GenericWrite, WriteOwner, AddMember, WriteSPN, and similar edges mean.
  • Actual operation: Password reset, adding a group member or SPN, adding shadow credentials, and so on.
  • Readback: Whether LDAP / SMB / WinRM confirms the change afterward.

If BloodHound fails after falling back to LDAPS, the root cause may be Kerberos clock skew or realm resolution rather than LDAPS itself. In Checkpoint, clock skew caused Kerberos failure, fallback to NTLM LDAP, rejection by LDAP signing, and then an LDAPS reset.

Password:

Terminal window
evil-winrm -i "$DC_FQDN" -u "$USER" -p "$PASS"

Kerberos:

Terminal window
export KRB5CCNAME="$USER.ccache"
evil-winrm -i "$DC_FQDN" -r "$DOMAIN" --ccache "$USER.ccache"

NT hash:

Terminal window
evil-winrm-py -i "$DC_FQDN" -u "$USER" -H "$HASH"

After connecting, record the user and host shown in the prompt. Do not stop at a successful netexec winrm result; confirm the actual remote PowerShell prompt.

SymptomFirst things to suspect
SMB/LDAP is +, WinRM is -Missing WinRM authorization, lack of Remote Management Users membership, or a WinRM authentication mechanism mismatch.
No Kerberos credentials availableMissing KRB5CCNAME or --ccache selection.
KRB_AP_ERR_SKEWTime difference between the attack box and DC.
KRB_AP_ERR_MODIFIEDSPN, hostname, realm, or service ticket mismatch. For WinRM, consider HTTP/<host>.
STATUS_NOT_SUPPORTEDNTLM unavailable. Use a Kerberos cache.

Enumeration after connecting through WinRM

Section titled “Enumeration after connecting through WinRM”

First, establish the current security context.

Terminal window
whoami
whoami /upn
whoami /all
whoami /groups
whoami /priv
hostname

Points to examine:

ObservationInterpretation
BUILTIN\Remote Management UsersExplains why WinRM works; it does not itself grant administrator privileges.
SeImpersonatePrivilege / SeAssignPrimaryTokenPrivilegePotential token abuse paths.
SeBackupPrivilege / SeRestorePrivilegePotential backup reads past NTFS ACLs, or hive / NTDS acquisition.
SeDebugPrivilegePotential process memory / credential access.
Only privileges such as SeMachineAccountPrivilege, SeChangeNotifyPrivilege, and SeIncreaseWorkingSetPrivilegePrioritize files, shares, AD, and credentials rather than immediate local privilege escalation.
Custom groupCheck whether it grants operational access to shares, applications, certificates, WSUS, backups, or similar resources.

Always retain the whoami /all output. In Puppy’s final session, I did not record it, making it difficult to explain the final account’s exact groups and privileges afterward.

Terminal window
systeminfo
ipconfig /all
route print
netstat -ano

Services and tasks:

Terminal window
Get-CimInstance Win32_Service |
Select-Object Name,StartName,State,PathName
Get-ScheduledTask |
Select-Object TaskName,TaskPath,State

Processes:

Terminal window
Get-Process -ErrorAction SilentlyContinue |
Select-Object ProcessName,Id,Path

The aim here is to find run accounts, paths, writable directories, configuration files, and credentials rather than memorize everything.

Do not recurse through all of C:\ immediately. First inspect the root directory.

Terminal window
Get-ChildItem -LiteralPath 'C:\' -Force

Then investigate only the promising candidates.

Terminal window
$targets = @(
'C:\Backups',
'C:\inetpub',
'C:\IT',
'C:\Logs',
'C:\Shares',
'C:\StorageReports',
'C:\ProgramData'
) | Where-Object { Test-Path $_ }
if ($targets) {
Get-ChildItem -LiteralPath $targets -Force -ErrorAction SilentlyContinue
Get-ChildItem -LiteralPath $targets -Recurse -Force -ErrorAction SilentlyContinue
}

Names to prioritize:

NameSignificance
Backups, VMBackups, NightlyBackupPossible configuration, old databases, snapshots, memory dumps, or NTDS / hives.
inetpub, wwwroot, app directoryWeb configuration, LDAP bind passwords, or connection strings.
IT, Dev, DevDrop, LogsOperational shares, deployment artifacts, scripts, or leaked credentials.
StorageReports, WSUSTemp, vendor directoryTraces of nonstandard operations.
User profile archivePossible DPAPI data, SSH keys, browser data, or Credential Manager data.

Limit the search scope before searching.

Terminal window
if ($targets) {
Get-ChildItem -LiteralPath $targets -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { -not $_.PSIsContainer } |
Where-Object { $_.Length -lt 5MB } |
Select-String -Pattern 'password|passwd|pwd|secret|token|credential|ldap|bind|backup|winrm' `
-ErrorAction SilentlyContinue
}

Also limit searches for flags or known filenames.

Terminal window
Get-ChildItem -LiteralPath 'C:\Users' -Filter 'root.txt' -Recurse -Force -ErrorAction SilentlyContinue
Terminal window
Get-ChildItem -LiteralPath 'C:\Users' -Force
$userDirs = @(
"$env:USERPROFILE\Desktop",
"$env:USERPROFILE\Documents",
"$env:USERPROFILE\Downloads"
) | Where-Object { Test-Path $_ }
if ($userDirs) {
Get-ChildItem -LiteralPath $userDirs -Force -ErrorAction SilentlyContinue
}

PowerShell history:

Terminal window
Get-Content (Get-PSReadLineOption).HistorySavePath -ErrorAction SilentlyContinue

In Evil-WinRM, ls is an alias for Get-ChildItem and type is an alias for Get-Content. Rewrite commands you intend to reuse with their full names and -LiteralPath.

Terminal window
Get-Content -LiteralPath 'C:\Users\<user>\Desktop\user.txt'

First, check credentials saved by the current user.

Terminal window
cmdkey /list
Get-ChildItem "$env:APPDATA\Microsoft\Credentials" `
-Force -ErrorAction SilentlyContinue
Get-ChildItem "$env:LOCALAPPDATA\Microsoft\Credentials" `
-Force -ErrorAction SilentlyContinue
Get-ChildItem "$env:APPDATA\Microsoft\Protect" `
-Recurse -Force -ErrorAction SilentlyContinue

If other users’ profiles or archived profiles are readable, look for the following set:

AppData\Roaming\Microsoft\Credentials
AppData\Local\Microsoft\Credentials
AppData\Roaming\Microsoft\Protect\<SID>
AppData\Local\Microsoft\Vault

DPAPI requires more than the Credential Blob.

Credential Blob
|
| Referenced Master Key GUID
v
Protect\<SID>\<MasterKeyGUID>
|
| Decrypt using the user password + SID, or a domain backup key, etc.
v
decrypted masterkey
|
v
Decrypt the Credential Blob

In Puppy, winPEAS showed the relationship between Credentials and Protect\<SID>, and the Master Key was decrypted with the user’s password and SID. In Voleur, both Credentials and Protect\<SID> were recovered from an archived profile, and the SID was confirmed from a deleted AD object.

After connecting through WinRM, you can still verify AD facts through LDAP, the AD module, or ADSI.

Terminal window
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$root = [ADSI]'LDAP://RootDSE'
$root.defaultNamingContext

Current user’s group memberships:

Terminal window
$searcher = [adsisearcher]"(sAMAccountName=$env:USERNAME)"
$result = $searcher.FindOne()
$result.Properties.memberof

Find users:

Terminal window
$searcher = New-Object DirectoryServices.DirectorySearcher
$searcher.Filter = '(objectClass=user)'
$searcher.PageSize = 1000
$searcher.PropertiesToLoad.AddRange(@(
'samaccountname',
'distinguishedname',
'memberof',
'useraccountcontrol',
'description',
'serviceprincipalname'
))
$searcher.FindAll() |
ForEach-Object { $_.Properties }

If the AD module is available:

Terminal window
Import-Module ActiveDirectory
Get-ADUser '<user>' -Properties MemberOf,Description,ServicePrincipalName,UserAccountControl |
Select-Object SamAccountName,Enabled,Description,MemberOf,ServicePrincipalName,UserAccountControl
Get-ADPrincipalGroupMembership '<user>' |
Select-Object Name,DistinguishedName

Edges shown by BloodHound ultimately correspond to facts such as LDAP attributes, ACEs, group memberships, SPNs, and delegation. Do not rely on the graph alone; corroborate it with readable attributes and the results of actual operations.

After obtaining a new user, hash, or group membership, enumerate SMB shares again from the attack host.

Terminal window
netexec smb "$DC_FQDN" -d "$DOMAIN" -u "$USER" -p "$PASS" --shares
netexec smb "$DC_FQDN" -d "$DOMAIN" -u "$USER" -H "$HASH" --shares

From inside the WinRM target:

Terminal window
$dc = '<dc-fqdn>'
net view "\\$dc"
net use

Share ACLs behave differently with the current credentials. A share that denied access to the initial user may be readable with another user, group, or hash.

Use winPEAS as a baseline for spotting gaps in manual enumeration, rather than as a way to find the answer from the outset.

Terminal window
.\winPEASx64.exe *> C:\Windows\Temp\winpeas.txt

Compare these observations:

ObservationManual checkwinPEAS checkNext decision
Nonstandard directories at the rootC:\Backups, C:\IT, etc.Any additional candidates?Limit further investigation to relevant paths.
Credential Manager / DPAPICredentials, Protect\<SID>Relationship between Master Key and BlobCheck whether the material needed to decrypt them is available.
PowerShell historyHistory pathAny missed entries?Check for leaked commands or passwords.
Services / scheduled tasksService path, run accountCandidate writable pathsCheck execution context and ACLs.
Writable pathManual ACL / file writeAdditional candidatesCheck whether the path is executed.
Token privilegeswhoami /allPotential privilegesDo not confuse share access with token privileges.

Living off the Land (LOTL) is not necessarily undetectable. PowerShell command lines, Script Block Logging, AMSI, rapid large-scale file enumeration, WMI/CIM enumeration, access to credential directories, and processes under the WinRM provider host may all be monitored. Focus on what you read and how widely you searched, rather than whether you used a large tool or manual commands.

Obtain the same facts through multiple layers

Section titled “Obtain the same facts through multiple layers”

It helps to verify a fact at three layers: a dedicated tool, standard OS facilities, and LDAP / APIs.

Example: a user’s group memberships.

NetExec:

Terminal window
netexec ldap "$DC" -d "$DOMAIN" -u "$USER" -p "$PASS" \
--query "(sAMAccountName=<user>)" "sAMAccountName memberOf"

Standard Windows tools:

Terminal window
whoami /groups

AD module:

Terminal window
Get-ADPrincipalGroupMembership '<user>' |
Select-Object Name,DistinguishedName

ADSI:

Terminal window
$searcher = [adsisearcher]'(sAMAccountName=<user>)'
$searcher.FindOne().Properties.memberof

BloodHound, bloodyAD, and Impacket are powerful, but underneath they use LDAP, Kerberos, SMB, RPC, WinRM, and Windows APIs. Relate the facts you want to observe to the protocols and APIs used, rather than focusing on tool names.

GoalCommon toolsAlternative route
Enumerate SMB sharesnetexec smb --sharessmbclient, net view
LDAP users / groupsnetexec ldap --users --groupsADSI, Get-ADUser, ldapsearch
Kerberos TGT/TGSgetTGT.py, GetUserSPNs.pykinit, kvno, Rubeus
AD graphBloodHound / RustHoundLDAP query, AD module, ADSI
Change LDAP attributesbloodyADSet-ADUser, ADSI, ldapmodify
WinRM shellEvil-WinRMPowerShell Remoting, Metasploit WinRM module
BoxObservationGeneral lesson
PuppyPort 5985 was open, but Remote Management Users membership and the Kerberos ccache had to be checked separately. An LDAP bind password in C:\Backups led to another credential through DPAPI.Separate WinRM authentication from authorization. After gaining a foothold, search nonstandard root directories, backups, and DPAPI data within a narrow scope.
Checkpointsvc_deploy belonged to Remote Management Users and BackupAccess. It lacked SeBackupPrivilege; READ access to the VMBackups share was the main path.Do not mistake a group name for a privilege. Use whoami /all and re-enumerate shares to determine what it means.
PirateThe initial pentest account could use LDAP/SMB but not WinRM. A gMSA belonged to Remote Management Users and could use WinRM with its hash.Use machine accounts, gMSAs, and group memberships to find WinRM candidates.
CertifiedLDAP and BloodHound confirmed that management_svc belonged to Remote Management Users; its hash then worked with WinRM.Remote Management Users identifies a candidate; confirm it by obtaining a shell.
AdministratorWinRM returned Pwn3d! for the initial user Olivia. Kerberos clock skew also became a problem later.Initial credentials can sometimes work for WinRM. Record the identity and groups when access succeeds.
LoggingThe Logs share, Remote Management Users, Emergency Recovery, and msa_health$ were visible early on. After connecting with WinRM, whoami /groups confirmed authorization.Share and group names offer clues about operational design. A machine account may also be a WinRM candidate.
VoleurNTLM was unavailable and returned STATUS_NOT_SUPPORTED. A Kerberos cache enabled SMB/LDAP enumeration, leading to DPAPI data in an archived profile.Do not confuse an incorrect password with an unsupported authentication method. A profile archive can lead to DPAPI data.

After obtaining initial credentials:

  • Check smb, ldap, and winrm separately.
  • Run --shares --rid-brute and --users --groups --computers.
  • Identify Remote Management Users, custom groups, service accounts, machine accounts, and gMSAs.
  • Check SMB signing, LDAP signing, NTLM availability, and clock skew.
  • Use BloodHound/RustHound as a map of relationships, then verify findings with actual operations and fresh reads.

After connecting through WinRM:

  • Save whoami /all output first.
  • Look for nonstandard directories directly under C:\, then recurse only into promising candidates.
  • Check user profiles, PowerShell history, Credential Manager, DPAPI, backups, and app configuration.
  • Recheck SMB shares and WinRM whenever you obtain new credentials, hashes, or group memberships.
  • Use winPEAS to check for gaps in manual enumeration.