OAuth-to-Kubernetes-to-Git OSINT Pivot: Authorization Flow Exploitation Across Infrastructure Services
Théorie
Why This Matters
Authentication infrastructure represents the highest-value reconnaissance target in modern cloud environments. Identifying an organization's OAuth provider, SSO endpoints, and Kubernetes orchestration platform before active testing enables red teams to construct targeted phishing campaigns against the specific login portal, identify credential stuffing targets, and locate exposed management interfaces. In documented incidents, exposed Kubernetes API endpoints have been accessed without authentication — the default Kubernetes 1.5 and earlier configuration allowed anonymous API access — leading to cryptominer deployment, data exfiltration, and in at least one case, access to a major financial institution's production cluster. Understanding the OSINT chain from OAuth endpoint discovery through Kubernetes API enumeration to git configuration file discovery is essential for both offensive assessment and defensive infrastructure hardening.
Core Concept
OAuth/SSO endpoint discovery begins with the target organization's website login flow. Modern web applications redirect authentication to a dedicated identity provider (IdP). The redirect URL in the browser's address bar when clicking "Sign In" reveals the OAuth provider: Google (accounts.google.com/o/oauth2/), Azure AD/Entra ID (login.microsoftonline.com/TENANT_ID/), Okta (company.okta.com), Auth0 (company.auth0.com), or Ping Identity (company.pingone.com). The OAuth client ID appears as a URL parameter (client_id=) in the authorization redirect — this value is not secret and reveals the registered application name or identifier, sometimes including the organization's internal application naming convention.
Azure AD tenant ID appears directly in the OAuth redirect URL as a UUID: login.microsoftonline.com/TENANT_UUID/oauth2/. This tenant ID can be resolved to domain names associated with the tenant using the Microsoft OpenID Connect discovery endpoint.
Kubernetes API exposure is discoverable through Shodan and Censys. The Kubernetes API server listens on port 6443 (HTTPS) by default and presents a TLS certificate. Shodan queries port:6443 kubernetes or http.title:"Kubernetes" and Censys queries for Kubernetes-specific response headers surface exposed API servers. The Kubernetes Dashboard (port 8001/8443 or exposed via Ingress) is indexed by http.title:"Kubernetes Dashboard" on Shodan. An exposed dashboard without authentication represents a critical finding.
Exposed kubectl configuration files (.kube/config) in public git repositories contain: the cluster API server endpoint URL (e.g., https://k8s-cluster.company.com:6443), the cluster certificate authority data (base64-encoded), and user credentials — either client certificates, bearer tokens, or OIDC configuration. When developers commit their entire home directory to git, or when CI/CD pipelines store kubeconfig in repository secrets that are accidentally logged, these files appear in git history.
Service account tokens mounted into Kubernetes pods at /var/run/secrets/kubernetes.io/serviceaccount/token are JWT tokens. If a pod with a mounted service account token is compromised (or if the token appears in git history or logs), the token can be used to authenticate to the Kubernetes API: curl -k -H "Authorization: Bearer TOKEN" https://K8S_API_ENDPOINT/api/v1/namespaces.
Technical Deep-Dive
# Step 1: OAuth provider identification from login redirect
# Use curl to follow the redirect chain from the target's login page
curl -sv "https://target.com/login" 2>&1 | grep -i "location:" | head -5
# => Location: https://login.microsoftonline.com/TENANT_UUID/oauth2/v2.0/authorize?client_id=...
# Extract tenant ID and client ID
LOGIN_URL="https://login.microsoftonline.com/a1b2c3d4-e5f6-7890-abcd-ef1234567890/oauth2/v2.0/authorize?client_id=app-client-id-here&response_type=code"
echo "$LOGIN_URL" | grep -oP 'microsoftonline.com/K[^/]+'
echo "$LOGIN_URL" | grep -oP 'client_id=K[^&]+'
# Resolve Azure AD tenant to associated domains
TENANT_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"
curl -s "https://login.microsoftonline.com/${TENANT_ID}/.well-known/openid-configuration" |
python3 -m json.tool | grep -E '"issuer"|"token_endpoint"|"userinfo_endpoint"'
# Step 2: Kubernetes API exposure via Shodan CLI
shodan search 'port:6443 kubernetes' --fields ip_str,port,hostnames,ssl.cert.subject.cn | head -20
shodan search 'http.title:"Kubernetes Dashboard"' --fields ip_str,port,hostnames | head -20
# Censys query for Kubernetes API servers (via censys CLI):
# censys search 'services.port=6443 AND services.tls.certificate.parsed.subject.common_name:kubernetes'
# Probe a discovered Kubernetes API endpoint for anonymous access
K8S_ENDPOINT="https://k8s-cluster.company.com:6443"
curl -k "${K8S_ENDPOINT}/api/v1/namespaces" 2>/dev/null | python3 -m json.tool |
grep -E '"kind"|"name"' | head -20
# 200 response with namespace list = anonymous access enabled (critical finding)
# 401 Unauthorized = authentication required (expected)
# Step 3: Search for kubeconfig files in public repositories
gh search code "clusters:" --extension=yaml --owner=target-org --limit=30
--json path,repository | python3 -m json.tool | grep -E '"path"|"nameWithOwner"'
gh search code "server: https" --owner=target-org --limit=30
--json path,repository,textMatches |
python3 -c "
import json, sys, re
results = json.load(sys.stdin)
for r in results:
for tm in r.get('textMatches', []):
frag = tm.get('fragment', '')
# Flag kubeconfig server entries
if re.search(r'server:s*https://S+:d+', frag):
print(f"KUBECONFIG CANDIDATE: {r.get('path','?')} in {r.get('repository',{}).get('nameWithOwner','?')}")
"
# Step 4: Parse a recovered kubeconfig
python3 - <<'EOF'
import yaml, base64
with open("recovered_kubeconfig.yaml") as f:
kubeconfig = yaml.safe_load(f)
for cluster in kubeconfig.get("clusters", []):
name = cluster.get("name")
server = cluster.get("cluster", {}).get("server")
print(f"Cluster: {name} => {server}")
for user in kubeconfig.get("users", []):
uname = user.get("name")
token = user.get("user", {}).get("token")
cert = user.get("user", {}).get("client-certificate-data")
print(f"User: {uname} | Token: {'present' if token else 'absent'} | Cert: {'present' if cert else 'absent'}")
EOF
Intelligence Collection Methodology
- Map the OAuth/SSO provider: Visit the target's login page and use browser developer tools or
curl -svto follow the redirect chain. Record: provider name, tenant/domain ID, OAuth client ID, and the authorization endpoint URL. - Enumerate OAuth-registered applications: For Azure AD tenants, query the Microsoft Graph API's public app endpoint:
https://graph.microsoft.com/v1.0/applications(requires tenant token, but directory search is sometimes publicly accessible). Okta's developer portal may expose application names in error messages. - Search Shodan for Kubernetes infrastructure: Query
port:6443 ssl.cert.subject.cn:*.company.comto find Kubernetes API servers with certificates matching the target domain. Queryhttp.title:"Kubernetes Dashboard"for exposed dashboards. Note all IP addresses and hostnames. - Test discovered Kubernetes endpoints for anonymous access: Run
curl -k https://K8S_IP:6443/api/v1/namespacesagainst each discovered endpoint. A successful response without credentials indicates anonymous access — a critical severity finding. A 401 response is expected and not a finding. - Search GitHub for kubeconfig files: Use
gh search codeto search the target organization's repositories for:clusters:(YAML kubeconfig structure),server: httpswith port patterns,certificate-authority-data:, andclient-certificate-data:. Each of these strings appears specifically in kubeconfig files. - Check CI/CD pipeline configurations for kubeconfig references: Search for GitHub Actions workflow files (
.github/workflows/) that referenceKUBE_CONFIG,KUBECONFIG, orkubectl. Developers sometimes base64-encode the kubeconfig and store it as a GitHub secret, then log it during debugging — check workflow run logs if accessible. - Mine git commit history for service account tokens: Run truffleHog over all discovered repositories searching for Kubernetes service account token patterns (JWT format: three base64url segments separated by dots, starting with
eyJ). Kubernetes service account tokens use theRS256algorithm and include akubernetes.ioclaim. - Map the full authentication infrastructure: Compile findings into an infrastructure map: OAuth provider → tenant ID → associated domains → Kubernetes cluster endpoints → kubeconfig credential types → git repositories containing credentials. This map defines the complete authentication attack surface.
- Verify cluster names against git commit messages: Kubernetes cluster names (from discovered kubeconfig files) often appear in commit messages (
deploy to prod-us-east-1-k8s). Search git log output and CI/CD pipeline configurations for these cluster names to corroborate discoveries and find additional credential references.
Common Intelligence Collection Errors
- Missing Okta and Auth0 subdomain patterns: Okta-hosted organizations always use
COMPANY.okta.comorCOMPANY.okta.eu; Auth0-hosted apps useCOMPANY.auth0.com. These subdomains are directly resolvable and identify the IdP without accessing the target's website. Test common organization name patterns against these domains before examining the login flow. - Treating 401 on the Kubernetes API as proof of security: A 401 response confirms authentication is required, but does not indicate what authentication mechanisms are accepted or whether those mechanisms are configured securely. RBAC misconfigurations, permissive service account bindings, and outdated authentication plugins are not detectable from unauthenticated probing alone.
- Overlooking kubeconfig in Docker images: Developers occasionally build Docker images that include their kubeconfig for CI/CD convenience. Public Docker Hub images from the target organization should be inspected with
docker pull IMAGE && docker run --rm IMAGE cat /root/.kube/config. - Ignoring the
certificate-authority-datafield as intelligence: Thecertificate-authority-datafield in kubeconfig is a base64-encoded CA certificate for the cluster. Decoding it withbase64 -d | openssl x509 -text -nooutreveals the cluster's internal CA common name, organization name, and certificate validity period — confirming cluster identity and age. - Assuming OAuth client IDs are sensitive: The OAuth
client_idparameter in authorization URLs is not a secret — it is intentionally public and must be included in browser-visible URLs. The actual secret is theclient_secret, which should never appear in frontend code or URLs. Reporting a client ID as a credential exposure is a false positive. - Not checking Kubernetes Dashboard version for known authentication bypasses: Different Kubernetes Dashboard versions have different default authentication configurations. Version 1.x allowed "skip" authentication by default. Before testing authentication controls, identify the dashboard version from the login page HTML and check for known CVEs affecting that version.
NICE Framework Alignment
| Code | Knowledge/Skill/Task Statement | How This Card Develops It |
|---|---|---|
| K0058 | Knowledge of network protocols | Understanding OAuth 2.0 authorization code flow, Kubernetes API REST protocol over HTTPS port 6443, and JWT token structure |
| K0145 | Knowledge of security assessment approaches | Executing a structured three-stage OAuth-to-Kubernetes-to-Git authentication infrastructure reconnaissance chain |
| K0272 | Knowledge of network security architecture | Mapping how OAuth providers, Kubernetes API servers, and git credential storage interact to create a connected authentication infrastructure |
| K0427 | Knowledge of encryption algorithms | Decoding base64-encoded kubeconfig certificate fields, analyzing JWT service account token structure, and interpreting TLS certificate metadata |
| S0040 | Skill in identifying and extracting data of interest from various sources | Extracting OAuth tenant IDs, Kubernetes endpoints, and kubeconfig credentials from login flows, Shodan results, and git repositories |
| T0569 | Apply and utilize authorized cyber capabilities to achieve objectives | Deploying Shodan, GitHub code search, kubectl probing, and truffleHog in authorized authentication infrastructure assessment |
Further Reading
- Kubernetes Security and Observability — Brendan Creane & Amit Gupta, Chapter 4: Securing Kubernetes API Access (O'Reilly Media)
- Hacking the Cloud — Kubernetes Enumeration — Nick Frichette (hackingthe.cloud)
- OAuth 2.0 in Action — Justin Richer & Antonio Sanso, Chapter 3: OAuth Client Registration (Manning Publications)
Challenge Lab
Renforcez votre apprentissage avec un défi généré basé sur la compétence de cette carte.