
Azure RedOps is a offensive security toolkit for assessing the security posture of Microsoft Entra ID
A Swiss Army tool for Azure / Entra ID red teaming.
Author: Mr.Un1k0d3r (TrueCyber Inc) Version: 0.1 Language: Python 3.12+
AzureRedOps is a offensive security toolkit for assessing the security
posture of Microsoft Entra ID and Azure tenants. It wraps the most common
red-team workflows — authentication, token management, directory enumeration,
privilege checking, password spraying, and post-exploitation actions against
Microsoft Graph — behind one consistent --activity driven CLI.
Every operation is selected with -a/--activity. Tokens obtained during
authentication can be cached locally (.azure_creds) and reused by name with
-l/--load-access-token, so you rarely have to paste raw JWTs.
Learn more about the tool on CYPFER blog
.azure_creds). Any flow can persist its tokens automatically with -s/--save + -n/--name.auth) — direct username/password authentication.phish-start / phish-capture) — abuse the OAuth device authorization grant to capture tokens issued when a target enters your user code at microsoft.com/devicelogin. Auto-captures by default.auth-app) — full Authorization Code + PKCE flow against a custom application registration, served by a built-in local HTTPS listener that receives the redirect.auth-interactive) — drive a real browser (Playwright; Firefox by default, -br to switch) (handles MFA / Conditional Access / SSO), then harvest every token from the recorded session HAR.refresh) — trade a refresh token for fresh access tokens.obo) — exchange an already-issued access token for a new token scoped to a downstream resource (OAuth 2.0 jwt-bearer / OBO).browser-sso) — open a real browser already authenticated as the user straight into the target web app (Outlook on the web, Teams, SharePoint, the Azure portal, ...). With -aprt/--auto-prt it auto-mints a Primary Refresh Token (PRT) cookie from a refresh token (device registration → PRT → x-ms-RefreshTokenCredential), so a fresh browser completes single sign-on with no manual login.gather-all collector.spray) and cross-app refresh-token spraying (spray-refresh).magic-app finds publicly-redirectable apps with AllPrincipals consent; built-in lists of known/interesting Microsoft app IDs.requirements.txt):
PyJWTrequestsplaywrightcryptography (only needed for browser-sso -aprt, the auto-PRT flow)auth-interactive, browser-sso).
Firefox is the default engine (-br/--browser); install it with
python -m playwright install firefox.includes/web/cert.pem and includes/web/key.pem
(only needed for the auth-app PKCE flow — see Notes).# Clone the repository
git clone <your-fork-url> AzureRedOps
cd AzureRedOps
# Create and activate a virtual environment
python3 -m venv AzureRedOps
source AzureRedOps/bin/activate # Linux / macOS
# .\AzureRedOps\Scripts\Activate.ps1 # Windows PowerShell
# Install dependencies
pip install -r requirements.txt
# Install the browser used by the browser flows (one-time).
# Firefox is the default engine; install the one(s) you plan to use with -br.
python -m playwright install firefox
# python -m playwright install chromium webkit # optional, for -br chromium/webkit
# python -m playwright install-deps # Linux/WSL: pull system libs
Run the tool:
python3 AzureRedOps.py -a <activity> [options]
The general invocation pattern is:
python3 AzureRedOps.py -a <activity> [authentication] [activity options] [global options]
Activities that call Microsoft Graph need an access token. You can supply it two ways:
| Method | Flag | Example |
|---|---|---|
| Pass a raw token | -ac, --access-token | -ac eyJ0eXAi... |
| Load a cached token by name | -l, --load-access-token | -l mytoken |
When -l is used, the matching access_token (and, where relevant, refresh_token
and tenant) is read from the .azure_creds store.
-s / -n)Any activity that obtains tokens (auth, auth-app, auth-interactive,
phish-start/phish-capture, refresh) can automatically persist them to the
local credential store (.azure_creds) by adding -s/--save together with
-n/--name:
# Authenticate and save the resulting tokens under the name "victim1"
python3 AzureRedOps.py -a auth -u [email protected] -p 'P@ssw0rd!' -tid <tenant-guid> -s -n victim1
-s/--save turns on auto-save; it requires -n/--name — the tool exits with an
error if -n is missing.-n/--name is the key the token is stored under. You can later reuse it with
-l victim1 instead of pasting the raw JWT, view it with -a view -n victim1, or
delete it with -a delete -n victim1.auth-interactive activity always auto-saves and will prompt you for a name
interactively if -n is not supplied.-j)Most enumeration activities (list-users, list-applications, list-principals,
gather-all, raw-url) accept -j/--json <filename> to write the raw API response
to a JSON file instead of (or in addition to) printing it:
# Dump every user to users.json
python3 AzureRedOps.py -a list-users -l victim1 -j users.json
For gather-all, the supplied filename is used as a suffix and one file is written
per Graph endpoint (e.g. users-<name>, groups-<name>, ...).
Tip:
-jcontrols structured JSON export, while-re/--redirect-to-filemirrors the formatted console output tooutput.txt. The two are independent.
-t, --tenant expects a domain name (e.g. contoso.com) and is used by the id activity.-tid, --tenant-id expects a tenant GUID or common, used by the authentication activities.