enum4linux-ng
SMB and RPC enumeration tool that pulls users, shares, groups, password policy, and OS info from Windows/Samba hosts. The rewrite of the classic enum4linux in Python with structured output and better reliability.
What is it?
enum4linux-ng is a Python rewrite of the classic Perl-based enum4linux. It uses SMB (port 445) and RPC (port 135/139) to enumerate information from Windows and Samba hosts. It asks the target questions and reports what the target is willing to answer; it exploits nothing.
The key concept is null sessions. Many Windows machines (especially older ones or misconfigured Domain Controllers) allow unauthenticated connections over SMB. When a null session works, you can pull:
- Domain users: full list of usernames via RID cycling or SAM enumeration
- Shares: which SMB shares exist and sometimes their permissions
- Groups and memberships: who belongs to Domain Admins, etc.
- Password policy: lockout threshold, minimum length, complexity requirements
- OS information: Windows version, domain name, NetBIOS name
The original enum4linux was Perl and relied on parsing output from smbclient and rpcclient, fragile and often broke with newer Samba versions. enum4linux-ng is written in Python, uses impacket under the hood, produces JSON/YAML output, and is significantly more reliable. Always use the -ng version.
Run this first
This asks the target everything it will answer without credentials. Replace the address with a host that has port 445 open.
$ enum4linux-ng -A 10.10.10.10
-Aruns the standard set of checks: users, groups, shares, password policy, OS information, NetBIOS names and printers.
Read the password policy first. Its lockout threshold decides how many password guesses you can make before accounts lock. Then note the users and shares, and take the shares to smbmap. Most modern domain controllers block null sessions, so an empty result means "try again with credentials", not "nothing here".
When do you use it?
Run enum4linux-ng whenever Nmap shows port 445 open on a target. This is your first SMB enumeration step before diving deeper with smbmap or BloodHound. The typical scenarios:
- Port 445 open, no creds yet → try null session enumeration. If it works you get users and policy for free
- You have a domain username → authenticated enumeration pulls far more detail
- Need the password policy before spraying → the lockout threshold determines how aggressive you can be with kerbrute
- Need a user list for attacks → RID cycling pulls valid usernames even when SAM enumeration is blocked
- Characterizing a new Windows host → OS version, domain membership, shares, all in one command
Don't bother with enum4linux-ng against Linux hosts unless they're running Samba. It's Windows/AD-focused. For Linux enumeration use Nmap scripts or manual service probing.
How to run it
Null session (no credentials)
# Run all enumeration modules with null session $ enum4linux-ng -A 10.10.10.10 # -A = all simple enumeration (users, shares, groups, policy, OS info) # This is the "throw everything at it" flag
Authenticated enumeration
# Authenticated: gets far more data than null session $ enum4linux-ng -A -u 'jsmith' -p 'Password123!' 10.10.10.10 # With a domain specified (sometimes required) $ enum4linux-ng -A -u 'jsmith' -p 'Password123!' -d 'corp.local' 10.10.10.10
Save output for later
# Save as JSON (machine-parsable) and YAML $ enum4linux-ng -A -oJ enum_output 10.10.10.10 $ enum4linux-ng -A -oY enum_output 10.10.10.10 # -oJ = JSON output to file # -oY = YAML output to file
Reading the output
enum4linux-ng produces a lot of output. Here's what matters and what to do with each piece:
========================================== | OS Information via RPC for 10.10.10.10 | ========================================== [*] OS info for 10.10.10.10: [+] os info: OS: Windows Server 2019 Standard 17763 <-- exact version OS version: 10.0 OS release: '' OS build: '17763' Native OS: Windows Server 2016 Standard 6.3 Native LAN mgr: Windows Server 2016 Standard 6.3 Platform id: '500' Server type: '0x80102b' Server type str: Wk Sv PDC Tim NT Domain <-- PDC = Primary Domain Controller
======================================= | Users via RID cycling for 10.10.10.10 | ======================================= [*] Trying to enumerate users via RID cycling [+] Found 8 user(s): 500: CORP\Administrator (Local/Domain User) 501: CORP\Guest (Local/Domain User) 502: CORP\krbtgt (Local/Domain User) 1103: CORP\jsmith (Local/Domain User) <-- valid user 1104: CORP\svc_backup (Local/Domain User) <-- service account! 1105: CORP\adunn (Local/Domain User) 1106: CORP\mmorgan (Local/Domain User) 1107: CORP\svc_sql (Local/Domain User) <-- service account!
Any username starting with svc_ is almost certainly a service account. These often have weak passwords, SPNs set (Kerberoastable), and elevated privileges. Feed them to Rubeus for Kerberoasting or try password spraying with kerbrute.
========================================= | Password Policy for 10.10.10.10 | ========================================= [+] Password policy: Password history length: 24 Minimum password length: 7 <-- weak minimum Maximum password age: 41 days 23:53:20 Password properties: DOMAIN_PASSWORD_COMPLEX Account lockout threshold: 5 <-- lock after 5 fails Account lockout duration: 30 minutes Reset account lockout after: 30 minutes
A lockout threshold of 5 means you can safely try 3 passwords per user with wait periods between rounds. If the threshold is 0 (no lockout) you can spray freely. If it's 3 or lower, be extremely careful. Always check the policy before spraying with Kerbrute.
========================================== | Shares via RPC for 10.10.10.10 | ========================================== [*] Trying to list shares via RPC [+] Found 5 share(s): ADMIN$: comment: Remote Admin type: Disk C$: comment: Default share type: Disk Department: <-- custom share, check it! comment: type: Disk IPC$: comment: Remote IPC type: IPC NETLOGON: comment: Logon server share type: Disk
The Department share is a non-default share, investigate it immediately with smbmap to check if you can read/write to it.
Common flags
| Flag | What it does | When to use |
|---|---|---|
-A | All simple enumeration | First run, always start here |
-u / -p | Username and password | When you have credentials |
-d | Domain name | When auth fails without it |
-oJ | JSON output | When you want to parse results programmatically |
-oY | YAML output | Human-readable structured output |
-R | RID cycling (turns it on) | When SAM enumeration is blocked or returns too few users |
-r | RID ranges to cycle (default 500-550,1000-1050) | When the default misses users, for example -R -r 500-20000 |
-U | User enumeration only | When you only need usernames |
-S | Share enumeration only | Quick share check |
-P | Password policy only | Before password spraying |
-G | Group enumeration only | Check group memberships |
enum4linux-ng vs smbmap vs CrackMapExec
These tools overlap but serve different primary purposes:
| Tool | Best for | Weakness |
|---|---|---|
| enum4linux-ng | Broad recon: users, groups, policy, OS, shares in one pass | Doesn't show per-share file permissions well |
| smbmap | Share permissions and file operations (read/write/list/download) | Doesn't enumerate users or password policy |
| CrackMapExec | Credential spraying across many hosts, checking admin access | Less detailed per-host enumeration |
Typical workflow: enum4linux-ng -A first to get users + policy → spray with kerbrute → authenticated smbmap to check share contents → BloodHound for attack path mapping.
Common mistakes
- Using old enum4linux (Perl): The original version breaks frequently with modern SMB implementations. Always use
enum4linux-ng - Giving up when null session fails: Null sessions are increasingly blocked. That doesn't mean SMB enumeration is dead, try again once you have valid creds
- Ignoring RID cycling: Sometimes SAM enumeration is blocked but RID cycling still works (and vice versa).
-Aruns the normal enumeration (users, groups, shares, policy, OS) but not RID cycling, so add-Rto try it - Not saving output: Always use
-oJor-oY. You'll want to reference the user list, password policy, and shares later - Forgetting the password policy: The most critical piece of output. If you skip this and spray aggressively, you'll lock accounts and alert the SOC
- Not expanding the RID range: RID cycling only tries RIDs 500-550 and 1000-1050 by default, so it misses any user created later. Set a wider range with
-r, for example-R -r 500-20000
Check yourself
Answer each question out loud or on paper first, then open it. Retrieving the answer teaches you more than rereading the page.
What does -A run, and what does it leave out that you may need?
-R when normal user enumeration is blocked or returns too few users.Which part of the output do you read before any password guessing, and why?
RID cycling returns only a few users on a large domain. What is the likely cause and the fix?
-r, for example -R -r 500-20000.A null session is refused. Is SMB enumeration over?
-u and -p and run it again.Why use enum4linux-ng and not the original enum4linux?
-oJ and -oY save the results as JSON or YAML.