Checking Credentials Against Okta

passwords Jan 19, 2020

During a penetration test or red team exercise you may have a list of usernames and passwords that you want to confirm as active. Your target also might happen to be using Okta as a single sign-on solution. By sending a simple POST request to Okta authentication endpoint, you can verify if these credentials are valid.

Okta Authentication Flow

Here's a quick rundown of what happens when you click 'Sign In' on an Okta login page.

If the organization is using MFA, Okta will generate a header (x-device-fingerprint) that ID's the device being used to login to the account. First, a GET request is made to https://<subdomain>.okta.com/auth/services/devicefingerprint, which fires another request to https://<subdomain>.okta.com/api/v1/internal/device/nonce.

Depending on the security policy set, the X-Device-Fingerprint header can be used when identifying a new/previously unseen device being used to login to an account.

Next, a POST request is sent to https://<subdomain>.okta.com/api/v1/authn, and must at least contain the following header: x-okta-user-agent-extended: okta-signin-widget-#.#.#, where the '#' symbols are replaced with the Okta sign-in widget version (at the time I started writing this post, the latest was 3.1.6). Lastly, the POST body will contain the credentials in JSON format: {"password":"<password>", "username":"<username>"}.

Using cURL

Using cURL to check if credentials are valid is fairly simple. The following command will return an HTTP status of 200 if the credentials are valid, and 401 if not:

curl -XPOST https://<subdomain>.okta.com/api/v1/authn -d '{"password":"<password>", "username":"<username>"}' \
-H "x-okta-user-agent-extended: okta-signin-widget-3.1.6" \
-H "content-type: application/json"

Just replace the subdomain, password, and username fields above to match your target. Don't forget to also ensure you have the right version number for the x-okta-user-agent-extended header; if you're not sure what it is, just send a junk request and view the response headers.

Scripted Checking

I've created a simple python script that will programmatically check a list of usernames and passwords against an Okta endpoint. The script can be found on my GitHub account here: https://github.com/h0ffayyy/okbrute

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.