samrdump.py Impacket: Enumerate Windows Users via SAMR

Impacket's samrdump.py guide to enumerate Windows users via MS-SAMR over SMB, get RID and account attributes with passwords, NTLM or Kerberos hashes.
- Posted on 2026-07-25
- Reading time: 6 min
How to Enumerate Windows Accounts via SAMR with samrdump.py #
samrdump.py is part of Packet and uses the MS-SAMR protocol to enumerate user accounts and their attributes on a Windows system, via SMB. It queries the first SAM domain returned From the target, it lists its users and for each one it retrieves a set of attributes (full name, comments, bad password counter, account status). Does not list groups, aliases, group members, or shares — although some online guides (even well-known ones) take this for granted, the current code does not call any function to do so.
Unlike GetADUsers.py If you use LDAP and need to point to the DC, samrdump works against any Windows host—workstations, member servers, DCs—as long as the account you're authenticating with is authorized to make remote SAMR calls to that target. This isn't automatic; it depends on the policy. RestrictRemoteSAM of the target, which we will talk about below.
Official reference: fortra/impacket — samrdump.py
How it really works #
1. Connessione SMB (porta 445 o 139) verso la named pipe \pipe\samr
2. Bind sull'interfaccia MS-SAMR
3. hSamrConnect → apre l'handle al server SAM
4. hSamrEnumerateDomainsInSamServer → elenca TUTTI i domini SAM trovati (li stampa tutti)
5. hSamrOpenDomain sul PRIMO dominio della lista → apre solo quello
6. hSamrEnumerateUsersInDomain → elenca gli utenti di quel dominio
7. Per ogni utente:
hSamrOpenUser → apre il contesto utente
hSamrQueryInformationUser2 (UserAllInformation) → recupera gli attributi
8. Stampa i risultati (tabella o CSV)No calls to alias/group enumeration functions, no interaction with share. If you see output with Found alias: Domain Admins, rid = 512 somewhere online, it's not from this version of the tool.
Key difference from GetADUsers.py:
samrdump.py | GetADUsers.py | |
|---|---|---|
| Protocol | MS-SAMR via SMB (445/139) | LDAP (389) |
| Target | Any Windows host reachable via SAMR | Domain Controller Only |
| Show local accounts | Yes | No |
| Show domain accounts | Yes, if you are aiming for DC | Yes, always |
| Attributes shown | RID, full name, comments, counters, basic status | sAMAccountName, e-mail, pwdLastSet, lastLogon |
| Groups/OU | No | No (neither) |
Syntax and real options #
impacket-samrdump [opzioni] [[dominio/]utente[:password]@]target| Option | Description |
|---|---|
-csv | Output in CSV format (true CSV, comma separated) |
-dc-ip IP | Domain Controller IP |
-target-ip IP | Target IP — useful when the target is a non-resolvable NetBIOS name |
-port {139,445} | SMB Port (default: 445) — only these two values are accepted |
-hashes LM:NT | Pass the Hash |
-aesKey KEY | AES key for Kerberos — set it automatically -k |
-k | Kerberos Authentication |
-no-pass | Don't ask for password |
-ts | Timestamps in logs |
-debug | Verbose output |
Does not exist a positional argument type 139/SMB o 445/SMB at the end of the target — this is a bug that appears in some guides. The port can only be set with -port.
Practical use #
Base — with password #
# Domain Controller — utenti di dominio
impacket-samrdump corp.local/user:Password123@10.10.10.5
# Workstation — account locali (Administrator, utenti locali)
impacket-samrdump ./administrator:Password123@10.10.10.50Pass the Hash #
impacket-samrdump -hashes :NThash corp.local/administrator@10.10.10.5Kerberos, with separate hostname and IP #
export KRB5CCNAME=/path/to/ticket.ccache
impacket-samrdump \
-k -no-pass \
-dc-ip 10.10.10.5 \
-target-ip 10.10.10.50 \
corp.local/user@WS01.corp.local-target-ip This is important when you use a hostname as the target (required for Kerberos) but want to force the connection to a specific IP — if you omit it, the tool uses the same value as the target.
CSV output — for offline analysis #
impacket-samrdump -csv corp.local/user:pass@10.10.10.5 > samrdump_output.csvVia port 139 (fallback if 445 is blocked) #
impacket-samrdump -port 139 corp.local/user:'Password123!'@10.10.10.5Output and how to read it #
Normal size (without -csv):
Found domain(s):
. CORP
. Builtin
Found user: Administrator, uid = 500
Administrator (500)/FullName:
Administrator (500)/AdminComment: Account amministrativo predefinito
Administrator (500)/UserComment:
Administrator (500)/PrimaryGroupId: 513
Administrator (500)/BadPasswordCount: 0
Administrator (500)/LogonCount: 47
Administrator (500)/PasswordLastSet: 2024-01-15 10:23:11
Administrator (500)/PasswordDoesNotExpire: True
Administrator (500)/AccountIsDisabled: False
Administrator (500)/ScriptPath:Note: The print tool uid in the output, but technically that number is the RID (Relative Identifier).
CSV format (-csv), real header:
#Name,RID,FullName,PrimaryGroupId,BadPasswordCount,LogonCount,PasswordLastSet,PasswordDoesNotExpire,AccountIsDisabled,AdminComment,UserComment,ScriptPath
Administrator,500,,513,0,47,2024-01-15 10:23:11,True,False,Account amministrativo predefinito,,
svc_sql,1104,SQL Service,513,0,12,2019-03-10 12:00:00,False,False,,,How to interpret real fields:
| Countryside | Meaning |
|---|---|
RID (uid (in output) | Account Relative Identifier, last part of the SID |
FullName | Full name set on the account |
PrimaryGroupId | User's primary group RID |
BadPasswordCount | Failed attempt counter, reported by the queried target |
LogonCount | Number of registered logons |
PasswordLastSet | Last password setup — old does not automatically equal weak, only unrotated |
PasswordDoesNotExpire | The password is set to never expire — this does not mean it is weak or known. |
AccountIsDisabled | Account Disabled Status |
AdminComment / UserComment | Text comments — sometimes contain forgotten credentials |
ScriptPath | Associated logon script |
The tool does NOT return: groups, group members, shares, msDS-SupportedEncryptionTypes (RC4/AES supported), flag PasswordNotRequired, account lock status, or expiration date.
RID - what they are and what they don't demonstrate #
The RID identifies the account within the domain; combined with the domain SID it forms the complete SID (S-1-5-21-X-Y-Z-RID). Some RIDs are fixed by convention:
500 = Administrator incorporato
501 = Guest
502 = krbtgt (solo su DC, in un dominio Active Directory)Attention: these are account RIDs user. samrdump.py It does not enumerate groups, so don't expect to see group RIDs (512 = Domain Admins, 519 = Enterprise Admins, etc.) in its output.
A RID 501 (Guest) present and not disabled does not mean anonymous access is possible. Check your SMB configuration separately before assuming anonymous access is working.
# Per ottenere il SID del dominio, serve un altro tool
impacket-lookupsid corp.local/user:pass@10.10.10.5 | head -5With the domain's RID and SID you can then construct forged Kerberos tickets (see Golden Ticket ).
Does samrdump.py work without credentials? #
Le null session They were the classic way to perform SAMR enumeration without credentials. On modern systems, they depend on several independently configurable factors: RestrictAnonymous, anonymous access to share/named pipes, and most importantly the policy RestrictRemoteSAM.
impacket-samrdump ''@10.10.10.5
impacket-samrdump 10.10.10.5From Windows 10 1607 / Server 2016 onwards, the default security descriptor for RestrictRemoteSAM Restricts remote SAM access to local administrators only on systems non-DC; on Domain Controllers however the default remains more permissive (historically Everyone), although it can be restricted by policy. A good practical reference is This article on SAM Remote access enumeration, In addition to Microsoft documentation on RestrictRemoteSAM.
Difference between workstations, member servers and domain controllers #
| Target | Generally enumerated accounts |
|---|---|
| Standalone workstation | Local accounts |
| Member workstation/server | Local SAM account, if the account you use switches RestrictRemoteSAM |
| Domain Controller | AD domain accounts exposed via SAMR (historically more permissive default) |
| Samba or compatible | It depends entirely on the implementation and configuration |
Comparison with alternative tools #
| tool | Protocol | Main information |
|---|---|---|
samrdump.py | SAMR/SMB | RID, full name, comments, primary group, counters, base state |
| rpcclient | PRC/SMB | Users, groups, members — more flexible but requires interactive session |
| lookupsid.py | MS-LSAT/SMB | RID bruteforce, useful for building the complete SID |
| GetADUsers.py | LDAP | sAMAccountName, e-mail, pwdLastSet, lastLogon |
| blood hound | LDAP+SMB | Relationships, groups, sessions, attack paths |
# Alternativa con rpcclient (più flessibile per gruppi, richiede autenticazione)
rpcclient -U "corp.local/user%Password123" 10.10.10.5 -c "enumdomusers"
rpcclient -U "corp.local/user%Password123" 10.10.10.5 -c "enumdomgroups"
# Alternativa con netexec
nxc smb 10.10.10.5 -u user -p pass --usersWhen samrdump.py returns STATUS_ACCESS_DENIED on the entire enumeration, you can still try to query individual RIDs one by one — the policy RestrictRemoteSAM sometimes blocks bulk enumeration but not point queries:
# RID cycling manuale con rpcclient (funziona anche con null session su target permissivi)
for i in $(seq 500 1100); do
rpcclient -N -U "" 10.10.10.5 -c "queryuser 0x$(printf '%x\n' $i)" | grep "User Name\|user_rid\|group_rid" && echo ""
done
# Stesso concetto automatizzato con netexec
nxc smb 10.10.10.5 -u '' -p '' --rid-bruteWhen to use samrdump.py instead of the alternatives: you specifically want the attributes exposed by SamrQueryInformationUser2 (comments, counters, PrimaryGroupId) on a specific host, or you need a CSV ready to process without going through interactive rpcclient.
Typical workflow #
samrdump.py
│
├── Ottieni username e RID
│ ├── userlist per controlli autorizzati (password spraying, solo dopo aver verificato lockout policy)
│ └── correlazione con lookupsid.py per il SID completo
│
├── Account con AdminComment/UserComment sospetti
│ └── a volte contengono credenziali dimenticate in chiaro
│
├── Nomi che sembrano service account (svc_*)
│ └── verifica reale con GetUserSPNs.py — il nome da solo non dimostra nulla
│
├── Account di dominio ottenuti da un DC
│ ├── GetNPUsers.py per verificare no-preauth reale
│ └── BloodHound/LDAP per gruppi e privilegi (samrdump non li mostra)
│
└── Account locali ottenuti da un member server
└── verifica separata di gruppi locali e diritti (rpcclient, nxc)Detection #
There are no “dedicated” Event IDs for a specific samrdump — what you see is generic SAMR traffic, indistinguishable from other tools that use the same interface:
- SMB authentication and network logon to the target
- Connection to
IPC$and access to the named pipe\pipe\samr - DCE/RPC traffic on MS-SAMR interface — many calls
SamrOpenUser/SamrQueryInformationUserin sequence they are an enumerative pattern - Non-administrative sources querying a large number of accounts
- Event ID
5145if Detailed File Share Auditing is enabled - EDR/NDR telemetry over SMB and RPC remains the most reliable signal, more so than a single log entry
There is no general rule that one enumeration tool is always “quieter” than another.
Common mistakes #
| Error | Probable cause | Verifica |
|---|---|---|
STATUS_LOGON_FAILURE | Incorrect credentials or domain | Check format and authentication material |
STATUS_ACCESS_DENIED | Account excluded from SAMR ACLs or policy RestrictRemoteSAM on target | Don't assume you always need an admin |
STATUS_PIPE_NOT_AVAILABLE | Named pipe SAMR not available | Check SMB, IPC$ and firewalls |
| timeout | Port 139/445 filtered or incorrect routing | Check connectivity, test -target-ip |
| Hostname/KDC error with Kerberos | Target indicated only by IP | Use FQDN as target and -target-ip for the actual connection |
| No entries received | SAM domain opened but no users recovered | Attiva -debug and check the target type |
Cheat sheet #
# Base con credenziali
impacket-samrdump corp.local/user:pass@TARGET
# Workstation — account locali
impacket-samrdump ./administrator:pass@WORKSTATION
# Pass-the-Hash
impacket-samrdump -hashes :NThash corp.local/user@TARGET
# Output CSV per analisi
impacket-samrdump -csv corp.local/user:pass@TARGET > output.csv
# Kerberos con hostname/IP separati
export KRB5CCNAME=ticket.ccache
impacket-samrdump -k -no-pass -dc-ip DC_IP -target-ip TARGET_IP corp.local/user@WS01.corp.local
# Via porta 139 (fallback)
impacket-samrdump -port 139 corp.local/user:pass@TARGET
# Null session (riesce solo se la policy lo permette)
impacket-samrdump ''@TARGET
# Cerca account con password che non scade
impacket-samrdump -csv corp.local/user:pass@TARGET | awk -F, '$8=="True"'Related Articles #
For use in authorized environments only.








