OAuth to Account takeover
Reading time: 29 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
Basic Information
OAuthはさまざまなバージョンを提供しており、基本的な洞察はOAuth 2.0 documentationでアクセス可能です。この議論は主に広く使用されているOAuth 2.0 authorization code grant typeに焦点を当てており、アプリケーションが他のアプリケーション内のユーザーのアカウントにアクセスまたはアクションを実行できるようにする認可フレームワークを提供します(認可サーバー)。
仮想のウェブサイト_https://example.com_を考えてみてください。これはすべてのソーシャルメディア投稿を表示するために設計されています。プライベートな投稿も含まれます。これを実現するために、OAuth 2.0が使用されます。_https://example.com_はあなたのソーシャルメディア投稿にアクセスするための許可を求めます。その結果、_https://socialmedia.com_に同意画面が表示され、要求されている権限とリクエストを行っている開発者が示されます。あなたが承認すると、_https://example.com_はあなたの代わりに投稿にアクセスする能力を得ます。
OAuth 2.0フレームワーク内の以下のコンポーネントを理解することが重要です:
- resource owner: あなた、つまりユーザー/エンティティが、ソーシャルメディアアカウントの投稿など、自分のリソースへのアクセスを許可します。
- resource server: リソースオーナーの代わりに
access token
を取得した後に認証されたリクエストを管理するサーバー、例:https://socialmedia.com。 - client application: リソースオーナーからの認可を求めるアプリケーション、例:https://example.com。
- authorization server: リソースオーナーの認証が成功し、認可が得られた後に
client application
にaccess tokens
を発行するサーバー、例:https://socialmedia.com。 - client_id: アプリケーションのための公開の一意の識別子。
- client_secret: アプリケーションと認可サーバーのみに知られる機密鍵で、
access_tokens
を生成するために使用されます。 - response_type: 要求されるトークンのタイプを指定する値、例:
code
。 - scope:
client application
がresource owner
から要求しているアクセスレベル。 - redirect_uri: ユーザーが認可後にリダイレクトされるURL。これは通常、事前に登録されたリダイレクトURLと一致する必要があります。
- state: ユーザーが認可サーバーにリダイレクトされる際にデータを保持するためのパラメータ。そのユニーク性は、CSRF保護メカニズムとして機能するために重要です。
- grant_type: グラントタイプと返されるトークンのタイプを示すパラメータ。
- code:
authorization server
からの認可コードで、client application
がaccess_token
を取得するためにclient_id
とclient_secret
と共に使用します。 - access_token: クライアントアプリケーションが
resource owner
の代わりにAPIリクエストに使用するトークン。 - refresh_token: アプリケーションがユーザーに再度プロンプトを表示することなく新しい
access_token
を取得することを可能にします。
Flow
実際のOAuthフローは次のように進行します:
- あなたはhttps://example.comに移動し、「ソーシャルメディアと統合」ボタンを選択します。
- サイトは次に、あなたの投稿にアクセスするための許可を求めるリクエストをhttps://socialmedia.comに送信します。リクエストは次のように構成されます:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
- 次に、同意ページが表示されます。
- あなたの承認に続いて、ソーシャルメディアは
redirect_uri
にcode
とstate
パラメータを含むレスポンスを送信します:
https://example.com?code=uniqueCode123&state=randomString123
- 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"}
- 最後に、プロセスは https://example.com があなたの
access_token
を使用してソーシャルメディアにAPIコールを行い、アクセスすることで終了します。
脆弱性
オープンリダイレクトURI
redirect_uri
はOAuthおよびOpenIDの実装においてセキュリティにとって重要であり、認可後に認可コードなどの機密データが送信される場所を指示します。誤って設定されると、攻撃者がこれらのリクエストを悪意のあるサーバーにリダイレクトさせ、アカウントの乗っ取りを可能にすることがあります。
悪用技術は、認可サーバーの検証ロジックに基づいて異なります。厳密なパス一致から、指定されたドメインまたはサブディレクトリ内の任意のURLを受け入れることまで様々です。一般的な悪用方法には、オープンリダイレクト、パストラバーサル、弱い正規表現の悪用、トークン窃盗のためのHTMLインジェクションが含まれます。
redirect_uri
の他にも、client_uri
、policy_uri
、tos_uri
、initiate_login_uri
などのOAuthおよびOpenIDパラメータもリダイレクト攻撃に対して脆弱です。これらのパラメータはオプションであり、サーバーによってサポートが異なります。
OpenIDサーバーをターゲットにする場合、ディスカバリーエンドポイント(**.well-known/openid-configuration**
)は、registration_endpoint
、request_uri_parameter_supported
、および "require_request_uri_registration
" などの貴重な構成詳細をリストすることがよくあります。これらの詳細は、登録エンドポイントやサーバーの他の構成の特定に役立ちます。
リダイレクト実装におけるXSS
このバグバウンティレポート https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html で述べられているように、リダイレクト URLがサーバーの応答に反映される可能性があり、XSSに対して脆弱であるかもしれません。テストするための可能なペイロード:
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
CSRF - 不適切な状態パラメータの取り扱い
OAuthの実装において、state
パラメータの誤用または省略は、クロスサイトリクエストフォージェリ(CSRF)攻撃のリスクを大幅に増加させる可能性があります。この脆弱性は、state
パラメータが使用されていない、静的な値として使用されている、またはユーザーのセッションと適切に検証または関連付けられていない場合に発生し、攻撃者がCSRF保護を回避できるようになります。
攻撃者は、認証プロセスを傍受して自分のアカウントを被害者のアカウントにリンクさせることでこれを悪用し、攻撃者のほぼ完了したoauthフローを使用してユーザーにログインさせることによって、潜在的なアカウント乗っ取りを引き起こす可能性があります。これは、OAuthが認証目的で使用されるアプリケーションでは特に重要です。
この脆弱性の実例は、さまざまなCTFチャレンジやハッキングプラットフォームで文書化されており、その実際の影響を強調しています。この問題は、Slack、Stripe、PayPalなどのサードパーティサービスとの統合にも及び、攻撃者が通知や支払いを自分のアカウントにリダイレクトできる可能性があります。
state
パラメータの適切な取り扱いと検証は、CSRFから保護し、OAuthフローを安全に保つために重要です。
アカウント乗っ取り前
- アカウント作成時のメール確認なし: 攻撃者は被害者のメールを使用して事前にアカウントを作成できます。被害者が後にサードパーティサービスを使用してログインすると、アプリケーションが誤ってこのサードパーティアカウントを攻撃者の事前作成アカウントにリンクさせ、無許可のアクセスを引き起こす可能性があります。
- 緩いOAuthメール確認の悪用: 攻撃者は、メールを確認しないOAuthサービスを悪用し、自分のサービスに登録した後、アカウントのメールを被害者のものに変更することができます。この方法も、最初のシナリオと同様に無許可のアカウントアクセスのリスクを伴いますが、異なる攻撃ベクターを通じて行われます。
秘密の開示
秘密のOAuthパラメータを特定し保護することは重要です。client_id
は安全に開示できますが、client_secret
を開示することは重大なリスクを伴います。client_secret
が漏洩すると、攻撃者はアプリケーションのアイデンティティと信頼を悪用してユーザーのaccess_tokens
やプライベート情報を盗むことができます。
一般的な脆弱性は、アプリケーションが認証code
をaccess_token
に交換する際に、クライアント側ではなくサーバー側で誤って処理する場合に発生します。この誤りはclient_secret
の露出を引き起こし、攻撃者がアプリケーションの名義でaccess_tokens
を生成できるようにします。さらに、ソーシャルエンジニアリングを通じて、攻撃者はOAuth認証に追加のスコープを追加することで権限をエスカレートし、アプリケーションの信頼された地位をさらに悪用することができます。
クライアントシークレットブルートフォース
サービスプロバイダーのアイデンティティプロバイダーに対してクライアントシークレットをブルートフォースし、アカウントを盗む試みを行うことができます。
ブルートフォースのリクエストは次のようになる可能性があります:
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 leaking Code + State
クライアントがコードとステートを持っている場合、異なるページに移動するときにそれがRefererヘッダー内に反映されると、脆弱です。
Access Token Stored in Browser History
ブラウザの履歴にアクセス トークンが保存されているか確認します。
Everlasting Authorization Code
認可コードは、攻撃者がそれを盗んで使用できる時間ウィンドウを制限するために、しばらくの間だけ存在する必要があります。
Authorization/Refresh Token not bound to client
認可コードを取得し、異なるクライアントで使用できる場合、他のアカウントを乗っ取ることができます。
Happy Paths, XSS, Iframes & Post Messages to leak code & state values
AWS Cognito
このバグバウンティレポートでは、https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ AWS Cognitoがユーザーに返すトークンがユーザーデータを上書きするのに十分な権限を持っている可能性があることがわかります。したがって、異なるユーザーのメールアドレスにユーザーのメールアドレスを変更できる場合、他のアカウントを乗っ取ることができるかもしれません。
# 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"
}
]
}
For more detailed info about how to abuse AWS cognito check:
AWS - Cognito Unauthenticated Enum - HackTricks Cloud
Abusing other Apps tokens
この書き込みで述べられているように、トークン(コードではなく)を受け取ることを期待するOAuthフローは、トークンがアプリに属しているかどうかを確認しない場合、脆弱である可能性があります。
これは、攻撃者が自分のアプリケーションでOAuthをサポートするアプリケーションを作成し、Facebookでログイン(例えば)できるためです。そして、被害者が攻撃者のアプリケーションでFacebookにログインすると、攻撃者は自分のアプリケーションに与えられたユーザーのOAuthトークンを取得し、それを使用して被害者のOAuthアプリケーションにログインすることができます。
caution
したがって、攻撃者がユーザーに自分のOAuthアプリケーションへのアクセスを取得することに成功すれば、トークンを期待しているアプリケーションで被害者のアカウントを乗っ取ることができるでしょう。
Two links & cookie
この書き込みによると、被害者が攻撃者のホストを指すreturnUrlを持つページを開くことが可能でした。この情報はクッキー(RU)に保存され、後のステップでプロンプトがユーザーにその攻撃者のホストへのアクセスを許可するかどうかを尋ねます。
このプロンプトを回避するために、Oauthフローを開始するためのタブを開き、このRUクッキーをreturnUrlを使用して設定し、プロンプトが表示される前にタブを閉じ、新しいタブをその値なしで開くことが可能でした。これにより、**プロンプトは攻撃者のホストについて通知しませんが、クッキーはそれに設定されるため、トークンはリダイレクトで攻撃者のホストに送信されます。
Prompt Interaction Bypass
このビデオで説明されているように、一部のOAuth実装では、prompt
GETパラメータをNone(&prompt=none
)として指定することで、ユーザーがプラットフォームに既にログインしている場合に、ウェブ上で与えられたアクセスを確認するように求められないようにすることができます。
response_mode
このビデオで説明されているように、**response_mode
**パラメータを指定して、最終URLでコードをどこに提供するかを示すことが可能です:
response_mode=query
-> コードはGETパラメータ内に提供されます:?code=2397rf3gu93f
response_mode=fragment
-> コードはURLフラグメントパラメータ内に提供されます#code=2397rf3gu93f
response_mode=form_post
-> コードはcode
という入力を持つPOSTフォーム内に提供され、その値が含まれますresponse_mode=web_message
-> コードはポストメッセージで送信されます:window.opener.postMessage({"code": "asdasdasd...
OAuth ROPC flow - 2 FA bypass
このブログ投稿によると、これはユーザー名とパスワードを介してOAuthにログインすることを可能にするOAuthフローです。この単純なフロー中に、ユーザーが実行できるすべてのアクションへのアクセスを持つトークンが返される場合、そのトークンを使用して2FAを回避することが可能です。
ATO on web page redirecting based on open redirect to referrer
このブログ投稿は、リファラーからの値へのオープンリダイレクトを悪用してOAuthをATOに悪用する方法についてコメントしています。攻撃は次の通りです:
- 被害者が攻撃者のウェブページにアクセスします
- 被害者が悪意のあるリンクを開き、オープナーが
response_type=id_token,code&prompt=none
を追加パラメータとして使用してGoogle OAuthフローを開始します。リファラーは攻撃者のウェブサイトです。 - オープナーで、プロバイダーが被害者を認可すると、
redirect_uri
パラメータの値(被害者のウェブ)に30Xコードで戻します。これにより、攻撃者のウェブサイトがリファラーに残ります。 - 被害者のウェブサイトはリファラーに基づいてオープンリダイレクトをトリガーし、被害者のユーザーを攻撃者のウェブサイトにリダイレクトします。
respose_type
がid_token,code
であったため、コードはURLのフラグメントで攻撃者に返され、被害者のサイトを介してGoogleのアカウントを乗っ取ることが可能になります。
SSRFs parameters
この研究を確認してください この技術の詳細について。
OAuthにおける動的クライアント登録は、特に**サーバーサイドリクエストフォージェリ(SSRF)**攻撃に対するセキュリティ脆弱性の重要なベクトルとして機能します。このエンドポイントは、OAuthサーバーがクライアントアプリケーションに関する詳細を受け取ることを可能にし、悪用される可能性のある機密URLを含みます。
重要なポイント:
- 動的クライアント登録は通常
/register
にマッピングされ、client_name
、client_secret
、redirect_uris
、ロゴやJSON Web Key Sets(JWKs)のURLなどの詳細をPOSTリクエストで受け入れます。 - この機能は、RFC7591およびOpenID Connect Registration 1.0に記載された仕様に従い、SSRFに対して脆弱なパラメータを含む可能性があります。
- 登録プロセスは、いくつかの方法でサーバーをSSRFにさらす可能性があります:
logo_uri
:サーバーによって取得される可能性のあるクライアントアプリケーションのロゴのURLで、SSRFを引き起こすか、URLが不適切に処理された場合にXSSを引き起こす可能性があります。jwks_uri
:クライアントのJWKドキュメントへのURLで、悪意を持って作成された場合、サーバーが攻撃者が制御するサーバーへの外部リクエストを行う原因となる可能性があります。sector_identifier_uri
:サーバーが取得する可能性のあるredirect_uris
のJSON配列を参照し、SSRFの機会を生み出します。request_uris
:クライアントのために許可されたリクエストURIをリストし、サーバーが認可プロセスの開始時にこれらのURIを取得する場合に悪用される可能性があります。
悪用戦略:
- SSRFは、
logo_uri
、jwks_uri
、またはsector_identifier_uri
のパラメータに悪意のあるURLを持つ新しいクライアントを登録することでトリガーされる可能性があります。 request_uris
を介した直接的な悪用はホワイトリスト制御によって軽減される可能性がありますが、事前に登録された攻撃者が制御するrequest_uri
を提供することで、認可フェーズ中にSSRFを促進することができます。
OAuth providers Race Conditions
テストしているプラットフォームがOAuthプロバイダーである場合、レース条件の可能性をテストするためにこれを読んでください。
Mutable Claims Attack
OAuthでは、subフィールドがユーザーを一意に識別しますが、その形式は認可サーバーによって異なります。ユーザー識別を標準化するために、一部のクライアントはメールアドレスやユーザーハンドルを使用します。しかし、これはリスクがあります:
- 一部の認可サーバーは、これらのプロパティ(メールアドレスなど)が不変であることを保証しません。
- "Microsoftでログイン"のような特定の実装では、クライアントはメールフィールドに依存しており、これはEntra IDでユーザーによって制御され、検証されていません。
- 攻撃者は、自分のAzure AD組織(例:doyensectestorg)を作成し、それを使用してMicrosoftログインを実行することでこれを悪用できます。
- Object ID(subに保存されている)は不変で安全ですが、可変のメールフィールドに依存することでアカウントの乗っ取りが可能になります(例えば、victim@gmail.comのようなアカウントをハイジャックすること)。
Client Confusion Attack
クライアント混乱攻撃では、OAuthインプリシットフローを使用するアプリケーションが、最終的なアクセストークンが特定のクライアントIDのために生成されたものであることを確認しません。攻撃者は、GoogleのOAuthインプリシットフローを使用する公開ウェブサイトを設定し、何千人ものユーザーを騙してログインさせ、その結果、攻撃者のサイト向けに意図されたアクセストークンを収集します。これらのユーザーが、トークンのクライアントIDを検証しない別の脆弱なウェブサイトにアカウントを持っている場合、攻撃者は収集したトークンを再利用して被害者を偽装し、アカウントを乗っ取ることができます。
Scope Upgrade Attack
Authorization Code Grantタイプは、ユーザーデータを送信するための安全なサーバー間通信を含みます。しかし、Authorization Serverがアクセストークンリクエストのスコープパラメータを暗黙的に信頼する場合(RFCで定義されていないパラメータ)、悪意のあるアプリケーションがより高いスコープを要求することで認可コードの権限をアップグレードする可能性があります。アクセストークンが生成された後、リソースサーバーはそれを検証する必要があります:JWTトークンの場合、これはJWT署名を確認し、client_idやscopeなどのデータを抽出することを含みます。一方、ランダム文字列トークンの場合、サーバーは認可サーバーにクエリを行い、トークンの詳細を取得する必要があります。
Redirect Scheme Hijacking
モバイルOAuth実装では、アプリがカスタムURIスキームを使用して認可コードを受け取るリダイレクトを受け取ります。しかし、複数のアプリがデバイス上で同じスキームを登録できるため、正当なクライアントのみがリダイレクトURIを制御しているという仮定が破られます。例えば、Androidでは、com.example.app://
のようなIntent URIが、アプリのintent-filterで定義されたスキームとオプションのフィルターに基づいてキャッチされます。Androidのインテント解決は広範囲にわたる可能性があるため(特にスキームのみが指定されている場合)、攻撃者は巧妙に作成されたインテントフィルターを持つ悪意のあるアプリを登録して認可コードをハイジャックすることができます。これにより、ユーザーの相互作用(複数のアプリがインテントを処理する資格がある場合)または過度に特定的なフィルターを悪用するバイパステクニックを通じてアカウントの乗っ取りが可能になります。
References
- https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1
- https://portswigger.net/research/hidden-oauth-attack-vectors
- https://blog.doyensec.com/2025/01/30/oauth-common-vulnerabilities.html
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。