How to Customize Scan Profiles in user-scanner: A Complete Pattern Syntax Guide
To customize scan profiles in user-scanner, construct a pattern string using square brackets for character sets, curly braces for length repetition, and backslashes for literal escaping, then supply it via the -p CLI flag or the expand_patterns() API.
The kaifcodec/user-scanner repository implements a domain-specific pattern language that defines which usernames or handles to probe during reconnaissance. By mastering this syntax, you can customize scan profiles to target specific naming conventions, ranges, or character subsets without modifying the core engine code.
Understanding the Pattern Engine Architecture
user-scanner processes every scan profile through a four-stage pipeline implemented in user_scanner/core/patterns.py. When you supply a pattern, the tool executes these steps:
- Lexical analysis – The
Lexerclass tokenizes the raw pattern string (user_scanner/core/patterns.py:L16-L29). - Parsing – The
_parse_patternsfunction converts tokens into a list of blocks, representing either plain strings orPatternBlockobjects that contain character sets and length sets (L23-L52). - Expansion – The
expand_patternsfunction iterates through blocks to yield every possible username combination (L78-L93). This generator feeds directly into the HTTP request scheduler. - Counting – The
count_patternsfunction calculates total permutations beforehand (L25-L38), enabling the CLI to display progress indicators like "Scanning X of Y permutations."
The engine consumes these expanded strings via user_scanner/core/engine.py, which creates a Job for each handle and respects global flags such as concurrency (-C), timeout (-t), and --allow-loud as documented in docs/FLAGS.md.
Core Pattern Syntax for Custom Profiles
A scan profile is simply a pattern string that supports three primary customization mechanisms:
Character Sets (Square Brackets)
Define allowed characters at specific positions using square brackets. Ranges like a-z or 0-9 are expanded internally by the _char_range helper.
[a-c]expands toa,b,cjohn[a-c]generatesjohna,johnb,johnc
Length Control (Curly Braces)
Attach a length set to a character set to control repetition. The parser builds a lenset (e.g., {0-2} translates to lengths 0, 1, and 2).
[0-9]{2}requires exactly two digitsjohn[0-9]{0-2}producesjohn,john0throughjohn9, andjohn00throughjohn99
Escaping Special Characters
Prepend a backslash to treat [, ], or \ literally in your pattern.
\\[produces the literal character["hello\\[world\\]"generates exactlyhello[world]
Implementing Custom Scan Profiles
You can deploy custom profiles through either the command-line interface or the Python library.
CLI Method
Pass your pattern directly using the -p or --pattern flag defined in user_scanner/__main__.py:
user-scanner -p "admin[0-9]{0-2}" -t 5 -C 10
This command scans admin, admin0 through admin99, using a 5-second timeout and 10 concurrent workers.
Python API Method
For programmatic control, import the expansion utilities and engine directly:
from user_scanner.core.engine import Engine
from user_scanner.core.patterns import expand_patterns
# Define a profile checking john0-john9 and jane[a-c]
profile = "john[0-9]{1} jane[a-c]"
# Generate handles manually (or let Engine handle expansion internally)
handles = list(expand_patterns(profile))
engine = Engine()
results = engine.scan(handles) # Returns iterator of Result objects
for r in results:
print(r.handle, r.status, r.extra)
Counting Permutations Before Scanning
Use count_patterns to preview scan scope:
python -c "import user_scanner.core.patterns as p; print(p.count_patterns('user[0-9]{3}'))"
Output: 1000
This confirms the scan will generate exactly 1,000 usernames before consuming bandwidth.
How the Engine Processes Your Profile
Once expanded, the list of handles flows into user_scanner/core/engine.py, where each string becomes a Job instance. The engine respects your CLI flags for rate limiting and timeout configurations, then outputs structured Result objects defined in user_scanner/core/result.py. The entire pipeline—from pattern parsing in user_scanner/core/patterns.py to final status reporting—operates as a lazy iterator, ensuring memory efficiency even when your custom profile generates millions of permutations.
Summary
- Pattern strings are the core mechanism to customize scan profiles in
user-scanner, parsed by theLexerand_parse_patternsfunctions inuser_scanner/core/patterns.py. - Square brackets define character sets, curly braces control repetition length, and backslashes escape special characters.
- Use
expand_patterns()to generate handles programmatically or the-pCLI flag for direct execution. - Call
count_patterns()before scanning to predict total permutation counts and resource requirements. - The engine processes expanded handles via
user_scanner/core/engine.py, creating Job instances that respect global concurrency and timeout flags.
Frequently Asked Questions
What is the pattern syntax for user-scanner scan profiles?
Scan profiles use a custom DSL where square brackets define character sets (e.g., [a-z]), curly braces specify repetition counts (e.g., {2}), and backslashes escape literal characters. This syntax is parsed by classes in user_scanner/core/patterns.py and fully documented in the repository's docs/PATTERNS.md.
How do I count how many usernames a pattern will generate?
Import count_patterns from user_scanner.core.patterns and pass your pattern string. This function, implemented between lines 25-38 of user_scanner/core/patterns.py, calculates the Cartesian product of all character and length sets without expanding them into memory.
Can I use multiple character sets in a single pattern?
Yes. The _parse_patterns function (lines 23-52) tokenizes complex patterns containing multiple blocks. For example, "admin[0-9][a-c]{2}" combines numeric and alphabetic sets with length control, generating combinations like admin0aa, admin0ab, through admin9cc.
Where does user-scanner process the pattern string internally?
The pattern string enters the pipeline in user_scanner/core/patterns.py, where the Lexer class performs tokenization (lines 16-29) and _parse_patterns builds block representations. The expanded results then flow to user_scanner/core/engine.py, which orchestrates the actual HTTP scanning via the Engine class.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →