Skip to content

Enumeration

Flangvik edited this page Mar 8, 2026 · 2 revisions

TeamFiltration's enumeration module validates whether O365 / Entra ID accounts exist in a target tenant, without triggering authentication events or account lockouts. Four distinct validation methods are available, each with different speed, noise, and accuracy trade-offs.

   --enum        Load the enumeration module

         --domain              Domain to perform enumeration against, names pulled from statistically-likely-usernames if not provided with --usernames
         --usernames           Path to a list of usernames to enumerate (full email addresses, one per line)
         --tenant-info         Enumerate tenant and domain information (based on Invoke-AADIntReconAsOutsider from AADInternal)
         --dehashed            Use the Dehashed submodule to enumerate emails from a base domain (requires Dehashed credentials in config)
         --validate-msol       Validate accounts using the public GetCredentialType method (Rate-limited — ~20 accounts/sec)
         --validate-teams      Validate accounts using the Teams API method (Recommended — ~300 accounts/sec)
         --validate-login      Validate accounts by attempting to log in (Noisy — triggers authentication events — ~100 accounts/sec)
         --validate-onedrive   Validate accounts using the OneDrive method by @nyxgeek (Recommended — ~300 accounts/sec)

Validation Methods

--validate-teams (Recommended)

Uses a sacrificial Office 365 account to query the Microsoft Teams external search API. This method is passive — it does not trigger any login events on the target accounts. It is the fastest and least noisy method available.

Requirements: A sacrificial O365 account must be provided in the config (sacrificialO365Username + sacrificialO365Passwords). The account must not have MFA enforced and must have a valid Microsoft 365 Business Basic (or equivalent) license.

TeamFiltration.exe --outpath C:\Clients\Example\TFOutput --config myConfig.json --enum --validate-teams --domain legitcorp.net

When no --usernames list is provided with --domain, TeamFiltration pulls from the statistically-likely-usernames repository and prompts you to choose an email format:

[♥] TeamFiltration VX.X.X, created by @Flangvik
[+] Args parsed --outpath C:\Clients\Example\TFOutput --config myConfig.json --enum --validate-teams --domain legitcorp.net
[+] No usernames list provided, pulling statistically-likely-usernames
[?] Provide a target domain/tenant (e.g legitcorp.net) #> legitcorp.net
    |=> [1] john.smith@legitcorp.net
    |=> [2] john@legitcorp.net
    |=> [3] johnjs@legitcorp.net
    |=> [4] johns@legitcorp.net
    |=> [5] johnsmith@legitcorp.net
    |=> [6] jsmith@legitcorp.net
    |=> [7] smith@legitcorp.net
    |=> [8] smithj@legitcorp.net
    |=> [9] john_smith@legitcorp.net

[?] Select an email format #> 1

[ENUM] 24.05.2021 12:31:05 EST Filtering out previously attempted accounts
[ENUM] 24.05.2021 12:31:06 EST Enumerating 248231 possible accounts, this will take ~14 minutes
[ENUM] 24.05.2021 12:31:07 EST Successfully got Teams token for sacrificial account
[ENUM] 24.05.2021 12:31:07 EST Loaded 248231 usernames
[ENUM] 24.05.2021 12:31:08 EST enita.lintz@legitcorp.net valid!
[ENUM] 24.05.2021 12:31:09 EST bruce.wayne@legitcorp.net valid!
[ENUM] 24.05.2021 12:31:13 EST herminia.oliva@legitcorp.net valid!
[ENUM] 24.05.2021 12:31:13 EST thomas.anderson@legitcorp.net valid!
[ENUM] 24.05.2021 12:31:17 EST sharilyn.penning@legitcorp.net valid!

--validate-onedrive (Recommended)

Uses the OneDrive URL inference technique originally by @nyxgeek. Checks whether a user's OneDrive URL resolves, which indirectly confirms the account exists. Passive — no login events triggered.

TeamFiltration.exe --outpath C:\Clients\Example\TFOutput --config myConfig.json --enum --validate-onedrive --domain legitcorp.net

--validate-msol

Uses the public GetCredentialType Microsoft Online endpoint to check if an account exists. This method is rate-limited (approximately 20 accounts/sec) and may be subject to throttling by Microsoft.

TeamFiltration.exe --outpath C:\Clients\Example\TFOutput --config myConfig.json --enum --validate-msol --usernames C:\Clients\Example\usernames.txt

--validate-login

Attempts to authenticate each account in order to confirm existence. This method is noisy — it creates real authentication events in the tenant's sign-in logs and can trigger account lockouts if not used carefully. Use with appropriate sleep/jitter settings.

TeamFiltration.exe --outpath C:\Clients\Example\TFOutput --config myConfig.json --enum --validate-login --usernames C:\Clients\Example\usernames.txt

Supplying Your Own Username List

Use --usernames to provide a file of full email addresses (one per line) instead of generating them from a domain:

TeamFiltration.exe --outpath C:\Clients\Example\TFOutput --config myConfig.json --enum --validate-teams --usernames C:\Clients\Example\OSINT\emails.txt

Tenant Recon

Use --tenant-info to enumerate publicly available information about a tenant (domains, federation status, etc.) without validating individual accounts. Based on the Invoke-AADIntReconAsOutsider technique from AADInternals:

TeamFiltration.exe --outpath C:\Clients\Example\TFOutput --config myConfig.json --enum --tenant-info --domain legitcorp.net

Dehashed Integration

Use --dehashed to pull email addresses from the Dehashed breach database for a given base domain. Requires dehashedEmail and dehashedApiKey in the config file:

TeamFiltration.exe --outpath C:\Clients\Example\TFOutput --config myConfig.json --enum --dehashed --validate-teams --domain legitcorp.net

Notes

  • All validated emails are automatically stored in the TeamFiltration database and will be picked up by the spray module without any additional flags.
  • Previously validated accounts are filtered out automatically on subsequent runs to avoid redundant checks.
  • You can combine --dehashed with any validation method in a single command.

Clone this wiki locally