National Cyber Warfare Foundation (NCWF)

Inside adnullenum: one-pass null-session enumeration of Active Directory over SAMR and LSARPC


0 user ratings
2026-09-20 21:29:10
milo
Red Team (CNA)
"Inside

adnullenum consolidates anonymous SAMR and LSARPC enumeration into a single credential-free run, producing structured output for authorized assessments and labs.








Toolcrypt0p3g/adnullenum — single-pass anonymous Active Directory enumerator over \samr and \lsarpc
CategoryActive Directory / SMB enumeration (Python, impacket)
Primary UseAuthorized external/internal assessments: null-session recon of a domain controller, harvesting users, computers, groups, policy and LSA/DNS details with structured output
Safe UseOnly against systems you own or are explicitly authorized to test — penetration tests, lab domains, and hardening/defensive research; unauthorized directory enumeration may be illegal
Telemetry NoteGenerates high volumes of anonymous SMB/SAMR/LSARPC calls on port 445 — RID cycling in batches of 1000 and repeated per-user queries are visible in DC security logs and network monitoring as classic null-session enumeration patterns

adnullenum is a compact Python enumerator that performs anonymous — null-session — Active Directory reconnaissance against a domain controller using the \samr and \lsarpc named pipes, with no credentials required. The author is candid about what it is: not a new capability, but a packaging exercise that gathers in one run what operators normally stitch together from rpcclient sessions, impacket's samrdump.py and lookupsid.py, or full frameworks like NetExec. The niche it targets is the opening phase of an engagement where you have no domain account, you've found the DC through DNS, and you want the complete picture — accounts, per-user detail, groups, policy, and LSA/DNS information — without parsing stdout from four different tools by hand.


The tool exists in an impacket-based version, adnullenum.py, and requires Python 3.9+ plus that single SMB library. Installation is deliberately minimal: a virtual environment and pip install impacket covers it, after which python3 adnullenum.py --help enumerates the full option surface. There's no agent, no persistence mechanism, and no post-exploitation functionality — the README's framing is unambiguously that of an enumeration convenience wrapper for authorized work, with an explicit warning that running it against directories you don't own or aren't permitted to test may be illegal.


Operationally, everything routes through a single --mode flag. The default recon mode is deliberately the safe first look: domain info, user/group/computer counts, password and lockout policy, and the LSA/DNS details, with no brute-forcing at all. From there the modes escalate in depth — rids finds which accounts exist and sorts them into users, computers, and groups; users adds full per-user detail plus the interesting-accounts summary; groups resolves domain groups and builtin aliases to real member names; and full does everything. This staging reflects a sensible tradecraft instinct: establish that anonymous access is even open before committing to a noisy RID sweep.


The core enumeration engine is RID cycling. When the domain refuses to list users directly — which the README notes is common — the tool asks the DC to translate account IDs to names in batches of 1000, sweeping upward until the DC reports nothing more exists or until 5000 consecutive empty RIDs (configurable via --stop-after). You can pin an exact window with --range 500-50000 or widen the net on large domains with --start-rid and --max-rid. Machine accounts ending in $ are separated from real users, which matters because the two populations feed very different downstream checks.


Where the architecture gets interesting is the degradation ladder when SAMR is locked down. Some DCs return ACCESS_DENIED on anonymous enumdomains, and adnullenum handles this in layers: LSA recon always runs, and the domain name, SID, forest, GUID, and trusts frequently still come back over \lsarpc even when SAMR is sealed. RID translation can optionally fall back to LSA LsarLookupSids via the --lsa-fallback flag — off by default precisely because it's a second brute-force pass — while deep per-user detail and group membership, which genuinely require SAMR, are skipped and noted rather than silently failing. If both pipes are restricted, the run degrades to recon only, which is an honest terminal state: as the README puts it, on such a target no anonymous tool will enumerate the accounts.


The output design is where the tool distinguishes itself from rpcclient-by-hand workflows. Every run drops a timestamped folder under output/ containing txt/ and csv/ versions of everything (with optional json/ via --json), a manifest.json summarizing counts and interesting accounts, an access_denied.txt audit trail when something was restricted, and — most notably — a lists/ folder with userlist.txt and computerlist.txt purpose-built for feeding downstream tooling. In users/full mode the user list contains enabled accounts only; the computer list keeps the $ suffix on machine-account sAMAccountName values for pre-Windows 2000 compatibility checks.


The session-reuse mechanic shows the author has actually run this against large domains. RID discovery is the slow part, so the tool persists rids.txt in every run folder, and a subsequent invocation with --session (or --rid-file for a plain text file) skips the brute entirely and reuses the previously discovered inventory. There's also --lists-from, which rebuilds the feed lists from existing CSVs with zero network traffic — useful when you ran only rids initially and later decide you want the curated lists. Terminal output is capped at 100 entries per section (--limit) so a 100k-object domain doesn't flood the console; the files always contain the complete data.


The interesting-account flagging is the analytic layer that saves operators the most time. As accounts stream past, the tool annotates conditions like AS-REP-roastable, password not required, password never expires, unconstrained delegation, never logged on, and descriptions that mention a password — the last being a classic real-world hygiene failure. The README's example output shows this working against a sanitized test DC, flagging Administrator for PWD_NEVER_EXPIRES and a service account as ASREP_ROASTABLE. For defenders, this flag list doubles as a hardening checklist: every condition it flags is something a blue team should be able to answer for.


The comparison section is unusually honest for a GitHub README. It names enum4linux-ng as the closest mature equivalent (null-session SAMR + LSA, RID cycling, policy), points at NetExec's --rid-brute, --users, and --pass-pol for the same coverage inside a larger framework, and dissecting rpcclient's limitations in detail — its enumdomusers misses machine accounts, queryuser works one account at a time, and it has no built-in RID-cycling loop. The author's framing is that if you want battle-tested, use the incumbents; adnullenum's value proposition is the single-run workflow, the SAMR-to-LSA fallback, and the structured multi-format output.


From a detection standpoint, nothing here is quiet by design, though --sleep and --jitter exist to pace queries. Anonymous connections on port 445 followed by high-volume LsarLookupSids batches and sequential RID translations are among the oldest and best-signatured patterns in Windows security logging, showing up in DC event logs and any decent network detection stack. That visibility is a feature for the defensive audience: running adnullenum against your own lab or production domain (with authorization) is a direct test of whether your monitoring catches canonical null-session enumeration.


As an assessment utility, adnullenum occupies a legitimate and well-defined slot: it's a workflow consolidator for the anonymous phase of an authorized engagement, built on standard SAMR/LSARPC semantics, with disciplined fallback behavior and output engineered for the next stage rather than for its own sake. Its MIT license, Python implementation, and minimal dependency footprint make it easy to audit before use — which is exactly what you should do with any tool that talks to your directory. Paired with its own warnings about authorization and its graceful degradation when a domain is properly hardened, it reads less like a weapon and more like a well-organized checklist with a network adapter.



Official project repository for crypt0p3g/adnullenum.

Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.






Source: OffensiveSec
Source Link: https://www.offsecblog.com/2026/09/inside-adnullenum-one-pass-null-session.html


Comments
new comment
Nobody has commented yet. Will you be the first?
 
Forum
Red Team (CNA)



Copyright 2012 through 2026 - National Cyber Warfare Foundation - All rights reserved worldwide.