daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

commit ff5fb8249205c8b4b97f8fc18a2dac6c6530d34f
parent 17d3afee9d348b61305ec9a78169866657454dd9
Author: $: DAΞMON <zer0sec.xp@icloud.com>
Date:   Thu, 17 Sep 2026 05:42:16 +0100

Add SMTP user enumeration and Amass cheat sheets

New enumeration/ pages: smtp-user-enum.pl + swaks + nmap smtp-enum-users
(grouped, all three answer "does this mailbox exist"), and Amass v5 (its
CLI changed significantly from v3/v4 - intel folded into enum, results
live in a graph DB read back via `subs`). Written and version-checked
against the tools as actually installed/run on this machine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Diffstat:
Mcontent-manifest.json | 44+++++++++++++++++++++++++++++++++++++++++++-
Asrc/content/sheets/enumeration/amass.md | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/content/sheets/enumeration/smtp-user-enum.md | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 291 insertions(+), 1 deletion(-)

diff --git a/content-manifest.json b/content-manifest.json @@ -1217,6 +1217,47 @@ "difficulty": "intermediate", "action": "port", "note": "Distinct undo/recovery focus not covered by the main Git sheet." + }, + { + "source": "local", + "rel": "smtp-user-enum + swaks + nmap smtp-enum-users", + "category": "enumeration", + "slug": "smtp-user-enum", + "title": "SMTP User Enumeration", + "description": "smtp-user-enum, swaks and nmap smtp-enum-users \u2014 VRFY/EXPN/RCPT enumeration, open-relay checks, manual SMTP probing.", + "tools": [ + "smtp-user-enum", + "swaks", + "Nmap" + ], + "tags": [ + "enumeration", + "smtp", + "email" + ], + "difficulty": "beginner", + "action": "add", + "note": "New sheet: written after installing smtp-user-enum/swaks on the attacker Mac; nmap smtp-enum-users already bundled." + }, + { + "source": "local", + "rel": "amass v5.1.1", + "category": "enumeration", + "slug": "amass", + "title": "Amass", + "description": "OWASP Amass v5 subdomain enumeration and attack-surface mapping \u2014 enum, ASN/CIDR discovery, reading results out of its graph database.", + "tools": [ + "Amass" + ], + "tags": [ + "enumeration", + "osint", + "recon", + "dns" + ], + "difficulty": "intermediate", + "action": "add", + "note": "New sheet: v5 rewrote the CLI (OAM graph DB, engine subcommand, intel folded into enum) vs the v3/v4-era commands still shown in passive-external-recon.md." } ] -} +} +\ No newline at end of file diff --git a/src/content/sheets/enumeration/amass.md b/src/content/sheets/enumeration/amass.md @@ -0,0 +1,114 @@ +--- +title: "Amass" +description: "OWASP Amass v5 subdomain enumeration and attack-surface mapping — enum, ASN/CIDR discovery, and reading results back out of its graph database." +category: enumeration +tags: [enumeration, osint, recon, dns] +tools: [Amass] +difficulty: intermediate +updated: "2026-09-17" +--- + +# Amass + +OWASP Amass performs passive-by-default subdomain enumeration and attack-surface mapping, combining certificate transparency logs, passive DNS sources, search engines, and (optionally) active techniques like zone-transfer attempts and DNS brute-forcing. It's typically the first name-gathering pass alongside subfinder/assetfinder in [Stage 00 — Passive External Recon](/sheets/pentest-workflow/passive-external-recon). + +> [!warning] Version note — v5 changed the CLI shape +> Amass v5 rewrote storage around a local graph database (the "OAM" — Open Asset Model) served by a background **engine** process. Older tutorials referencing `amass intel -asn`, `amass intel -whois`, or `amass enum -o results.txt` are describing v3/v4 and **do not apply to v5** — there is no `intel` subcommand anymore; ASN/CIDR discovery moved directly into `enum`, and results live in the graph DB, read back out with `amass subs` rather than a plain output file. Confirmed against v5.1.1 (`amass -version`). + +## Subcommands (v5) + +```text +amass enum interface with the engine that performs enumerations +amass subs analyze and present discovered subdomains and associated data +amass track diff OAM data to identify newly discovered assets since a timestamp +amass viz generate graph visualizations (DOT / GEXF) from OAM data +amass assoc query the OAM along an association "triple" walk +amass engine run/manage the collection engine that backs the OAM database +``` + +`amass enum` auto-starts the background engine the first time it's needed (`ps aux | grep amass` will show `amass engine` running afterward); it stays up across invocations so repeated `enum`/`subs` calls against the same domain reuse the same graph DB. Stop it with `pkill -f "amass engine"` if you want a clean slate. + +## `amass enum` — the main pass + +```bash +# passive is the DEFAULT in v5 — this alone is the safe, non-contact baseline +amass enum -d $DOMAIN + +# multiple domains in one run +amass enum -d $DOMAIN,$DOMAIN2 + +# active mode: adds zone-transfer attempts + cert-name grabs against the target's own infra +amass enum -d $DOMAIN -active + +# brute force on top of the passive/active sources, with a custom wordlist +amass enum -d $DOMAIN -brute -w /path/to/subdomains.txt + +# ASN/CIDR-driven discovery — folded directly into `enum` in v5 (no more `intel` subcommand) +amass enum -asn 12345 +amass enum -cidr 203.0.113.0/24 -d $DOMAIN + +# seed from names you already have (other tools' output), skip re-discovering them +amass enum -d $DOMAIN -nf known_subs.txt + +# write files out under a directory instead of just the graph DB +amass enum -d $DOMAIN -oA ./recon/amass_$DOMAIN +``` + +| Flag | Description | Default | +|---|---|---| +| `-d value` | Domain(s), comma-separated | — | +| `-df file` | File of domains | — | +| `-active` | Attempt zone transfers + cert-name grabs (this is what makes a run "active", not a `-passive` flag — that flag still exists but is a no-op since passive is now default) | off | +| `-brute` | Run DNS brute forcing after the search/API sources | off | +| `-w file` / `-aw file` | Wordlist for brute forcing / name alterations | — | +| `-alts` | Generate altered/permuted names from what's found | off | +| `-asn value` | ASN(s), comma-separated — org-wide discovery | — | +| `-cidr value` | CIDR(s), comma-separated | — | +| `-addr value` | IPs/ranges (`192.168.1.1-254`) | — | +| `-p value` | Ports to check when resolving | 80, 443 | +| `-r` / `-tr value` | Untrusted / trusted DNS resolver IPs | system default | +| `-nf file` | Seed with already-known names (skips re-discovery) | — | +| `-bl value` / `-blf file` | Blacklist subdomains (inline / from file) | — | +| `-timeout N` | Minutes with no progress before terminating | 30 | +| `-oA prefix` | Path prefix for all output files | — | +| `-dir path` | Directory holding the graph database | default state dir | +| `-list` | Print all available data source names | — | +| `-include` / `-exclude value` | Restrict to / drop specific data sources | all | +| `-v` | Verbose/debug output | off | +| `-silent` | No output during the run | off | + +> [!tools] Related in the same recon stage +> [subfinder](https://github.com/projectdiscovery/subfinder), [assetfinder](https://github.com/tomnomnom/assetfinder), and [puredns](https://github.com/d3mondev/puredns) (wildcard-aware resolving) — see [Stage 00](/sheets/pentest-workflow/passive-external-recon) for unioning all of them together. No single passive source is complete; run at least two and merge. + +## Reading results back out + +Amass v5 doesn't dump to stdout the way older versions did — query the graph DB with `subs` after `enum` finishes: + +```bash +amass subs -d $DOMAIN -names # just the discovered names, one per line +amass subs -d $DOMAIN -ip # names + IPs +amass subs -d $DOMAIN -ipv4 # IPv4 only +amass subs -d $DOMAIN -summary # ASN table summary instead of names +amass subs -d $DOMAIN -names > subs_amass.txt # pipe into the union step alongside subfinder/assetfinder +``` + +## Diffing over time & visualizing + +```bash +# only assets discovered since a given time — good for re-scanning a target periodically +amass track -d $DOMAIN -since '09/01 00:00:00 2026 UTC' + +# export the asset graph +amass viz -dir <graph-db-dir> -dot -oA ./recon/amass_graph +amass viz -dir <graph-db-dir> -gexf -oA ./recon/amass_graph # open the .gexf in Gephi +``` + +> [!warning] Watch out +> - `-active` sends zone-transfer attempts and TLS connections straight at the target's own nameservers/hosts — that's active recon, not passive; keep engagements scoped accordingly (same rule as [Stage 00's `amass enum -passive` note](/sheets/pentest-workflow/passive-external-recon), now spelled `-active`'s absence rather than a `-passive` flag's presence). +> - API keys for VirusTotal/SecurityTrails/Shodan/Censys etc. (`amass enum -list` shows all sources) meaningfully increase yield — configure them in the YAML config (`-config`) rather than relying on the free/keyless sources alone. +> - The background engine persists between runs; if a `subs`/`track` query looks stale, confirm you're pointed at the same `-dir` the `enum` run used, or that the engine process is even still the one you expect (`ps aux | grep amass`). + +## Sources + +- https://github.com/owasp-amass/amass +- `amass -h`, `amass enum -h`, `amass subs -h`, `amass track -h`, `amass viz -h` (v5.1.1, confirmed locally) diff --git a/src/content/sheets/enumeration/smtp-user-enum.md b/src/content/sheets/enumeration/smtp-user-enum.md @@ -0,0 +1,134 @@ +--- +title: "SMTP User Enumeration" +description: "smtp-user-enum, swaks and nmap's smtp-enum-users — VRFY/EXPN/RCPT username enumeration, open-relay checks and manual SMTP probing." +category: enumeration +tags: [enumeration, smtp, email] +tools: [smtp-user-enum, swaks, Nmap] +difficulty: beginner +updated: "2026-09-17" +--- + +# SMTP User Enumeration + +Three ways to answer "does this mailbox exist?" against an SMTP server (25/465/587): the purpose-built **smtp-user-enum.pl** (bulk VRFY/EXPN/RCPT), **nmap**'s bundled `smtp-enum-users` script (same three methods, one-shot with the rest of a scan), and **swaks** for hand-crafted probes — relay testing, `RCPT TO` acceptance checks, and STARTTLS/auth testing that the dedicated enumerators don't do. Start with `nmap -sC -p25 $IP` (the `smtp-commands` script) to see which of VRFY/EXPN/AUTH/STARTTLS the server even advertises before picking a method. For the full protocol-level workflow (open relay, spray, CVE-2020-7247) see [Service Enumeration → SMTP](/sheets/pentest-workflow/service-enumeration) and [Attacking Common Services → Email](/sheets/pentest-workflow/attacking-common-services). + +## smtp-user-enum.pl + +Perl script (pentestmonkey), preinstalled on Kali; on macOS clone it — `git clone https://github.com/pentestmonkey/smtp-user-enum`, no dependencies beyond core Perl (`Net::SMTP`, `Getopt::Std`). Runs one method against a wordlist with configurable concurrency. + +```bash +# VRFY (default method) — most reliable when not disabled +perl smtp-user-enum.pl -M VRFY -U users.txt -t $IP + +# EXPN — expands a mailing list/alias to member addresses +perl smtp-user-enum.pl -M EXPN -U users.txt -t $IP + +# RCPT — works even when VRFY/EXPN are disabled; needs a MAIL FROM domain +perl smtp-user-enum.pl -M RCPT -U users.txt -D $DOMAIN -t $IP + +# single username check, custom port, more workers +perl smtp-user-enum.pl -M VRFY -u root -t $IP -p 25 -m 10 +``` + +| Flag | Description | Default | +|---|---|---| +| `-M mode` | Method: `VRFY`, `EXPN`, or `RCPT` | `VRFY` | +| `-u user` | Single username to check | — | +| `-U file` | File of usernames | — | +| `-t host` | Single target host | — | +| `-T file` | File of target hosts | — | +| `-D dom` | Domain appended to usernames for `RCPT` mode (guess full addresses) | none | +| `-f addr` | `MAIL FROM` address, `RCPT` mode only | `user@example.com` | +| `-p port` | TCP port | 25 | +| `-m n` | Max concurrent processes | 5 | +| `-d` | Debug output | off | +| `-v` | Verbose | off | + +> [!warning] Watch out +> - Many hardened MTAs (Postfix in particular) leave VRFY enabled but always return `252 Cannot VRFY user` regardless of validity — calibrate first by testing one known-bad and one known-good username; if both give identical responses, VRFY is neutered and you need `RCPT` instead. +> - `RCPT` mode is slow (~5–7 requests/sec) and the noisiest of the three since it opens a full `MAIL FROM`/`RCPT TO` sequence per guess (no `DATA` sent, so no mail is actually delivered) — scope the wordlist, don't point it at rockyou. +> - `-m` concurrency above ~10–15 gets rate-limited or blacklisted by most modern MTAs. + +## nmap `smtp-enum-users` + +Same three methods, run as part of an nmap scan — convenient when you're already scanning the port and want a same-command result, or need nmap's `userdb`/`passdb`-style scripted output. + +```bash +# default: tries RCPT, then VRFY, then EXPN, against nmap's built-in username list +nmap -p25 --script smtp-enum-users $IP + +# pick methods and order explicitly +nmap -p25 --script smtp-enum-users --script-args smtp-enum-users.methods={EXPN,RCPT,VRFY} $IP + +# custom username list (standard nmap unpwdb 'userdb' argument) +nmap -p25 --script smtp-enum-users --script-args userdb=/opt/users.txt $IP + +# banner/capability check first — shows if VRFY/EXPN/STARTTLS/AUTH are even offered +nmap -p25 -sC -sV $IP +``` + +Stops early if the server enforces authentication, and prints whatever usernames it found before any error. Related scripts on the same target: `smtp-commands` (EHLO/HELP capability banner), `smtp-open-relay` (tries hardcoded `MAIL FROM`/`RCPT TO` combinations to detect relaying — flags authenticated servers as not-vulnerable rather than erroring), `smtp-vuln-cve2010-4344` / `smtp-vuln-cve2011-1720` (Exim/Postfix heap overflows). + +```bash +nmap -p25 --script smtp-commands,smtp-open-relay,smtp-vuln* $IP +``` + +## swaks — manual probing, relay & auth testing + +swaks doesn't bulk-enumerate on its own, but it's the right tool for anything smtp-user-enum/nmap don't cover: single-shot `RCPT TO` acceptance checks (useful when VRFY/EXPN are both off), open-relay testing, and exercising STARTTLS/AUTH. + +```bash +# basic connectivity / banner + EHLO capabilities +swaks --to test@$DOMAIN --server $IP + +# RCPT-based user check — stop right after RCPT TO, read the response code +# (accepted, 250/251 = valid mailbox; 550/551/553 = no such user) +swaks --to victim@$DOMAIN --from test@evil.com --server $IP --quit-after RCPT --hide-all; echo "exit: $?" + +# same idea, scripted over a userlist (swaks exits non-zero on rejection) +for u in $(cat users.txt); do + swaks --to "$u@$DOMAIN" --server $IP --quit-after RCPT --hide-all \ + && echo "VALID: $u" +done + +# open relay test — external sender AND external recipient, neither in the local domain +swaks --to outsider@external-test.com --from spoofed@some-other-domain.com --server $IP +# accepted (250) with no auth from an address outside $DOMAIN, to an address outside $DOMAIN = open relay + +# force/require STARTTLS, dump the peer cert +swaks --to test@$DOMAIN --server $IP --tls --tls-get-peer-cert + +# authenticated send (validate creds found via spraying/loot) +swaks --to test@$DOMAIN --from user@$DOMAIN --server $IP \ + --auth LOGIN --auth-user 'user@$DOMAIN' --auth-password 'Password1!' +``` + +| Flag | Description | Default | +|---|---|---| +| `-t, --to ADDR` | Envelope recipient (only truly required option) | — | +| `-f, --from ADDR` | Envelope sender; `<>` for null sender | best-guess local user@host | +| `-s, --server HOST[:PORT]` | Target server | localhost | +| `--port PORT` | Override port | protocol default (25) | +| `--protocol PROTO` | `SMTP`, `ESMTP`, `SSMTP`, `SMTPS`, `LMTP`, … — sets port/TLS/HELO type as a side effect | `ESMTP` | +| `--quit-after STOP` | End the transaction cleanly right after a stage: `CONNECT`, `HELO`/`EHLO`, `STARTTLS`, `AUTH`, `MAIL`, `RCPT` | full transaction | +| `-tls` | Require STARTTLS, abort if unavailable | off | +| `-tlsc, --tls-on-connect` | Implicit TLS on connect (port 465 style) | off | +| `-a, --auth [TYPE]` | Require auth: `LOGIN`, `PLAIN`, `CRAM-MD5`, `DIGEST-MD5`, `NTLM` | off | +| `-au, --auth-user` / `-ap, --auth-password` | Credentials for `--auth` | prompt | +| `-n, --suppress-data` | Don't print the DATA section (keep output readable) | off | +| `-ha, --hide-all` | Suppress all output — check `$?` instead | off | +| `--timeout TIME` | Transaction timeout (`5s`/`3m`/`1h`, `0` = none) | 30s | + +> [!tip] `--quit-after RCPT` is the whole trick +> This is straight from swaks' own quick-start docs: stopping right after `RCPT TO:` gets you the server's accept/reject verdict without ever sending a message body, so it reads almost identically to what `smtp-user-enum -M RCPT` does internally — useful when you want to hand-verify a couple of hits, or when you need swaks' TLS/auth handling that smtp-user-enum doesn't have. + +> [!warning] Watch out +> - Open-relay and unauthenticated `RCPT` probing generate real SMTP session log entries (and, on a relay hit, an actual outbound message) — scope carefully on live/production mail infrastructure, this isn't a passive check. +> - `--protocol SMTP` forces `HELO` instead of `EHLO`, which some scanners use specifically to dodge servers that only rate-limit/log on ESMTP extensions. + +## Sources + +- https://github.com/pentestmonkey/smtp-user-enum +- https://github.com/jetmore/swaks +- https://nmap.org/nsedoc/scripts/smtp-enum-users.html +- https://nmap.org/nsedoc/scripts/smtp-open-relay.html