Firebase timeout 問題

0x00 背景

firebase/firestoreの診断を行う時に、burpを使うと、下記のようなtimeoutエラーが出る。これの解決法をここにまとめる。

[2021-11-04T09:18:26.044Z]  @firebase/firestore: Firestore (7.6.2): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.

0x01 解決方法

breakpointをしかけて、forceLongPolling を trueにする。

具体的に、chromeのdevtoolでxxx.chunk.jsを開いて、 this.forceLongPolling を見つけ、この行(36472)にbreakpointを仕掛ける。この行の実行が終わったら、forceLongPollingの値をtrueにして実行を続ける。

Local Overrides を使う

上の図と同じく、xxx.chunk.jsで右クリックして、Save for overridesを選んで、Enable Local Overridesにチェックを入れる。

そしたらローカルにxxx.chunk.jsが保存され、このxxx.chunk.jsを編集して保存すればなんでもできる。ここでは36472行目を this.forceLongPolling = true に編集して保存し、ページをリロードすると、timeout エラーが出なくなる。

0x02 consoleでjsを使う場合

var fire_scripts = ["/7.9.1/firebase.js","/9.1.2/firebase-app.js","/9.1.2/firebase-firestore.js","/9.1.2/firebase-auth.js"]; // 最新版を指定する
for(var i=0; i<fire_scripts.length; ++i){
    var s = document.createElement("script");
    s.type = "module";
    s.src = "https://www.gstatic.com/firebasejs"+fire_scripts[i];
    document.getElementsByTagName("head")[0].appendChild(s);
}

var config = {
  apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "xxxxxx.firebaseapp.com",
  databaseURL: "https://xxxxxxxx.firebaseio.com",
  projectId: "xxxxxxxxxxxx",
  storageBucket: "xxxxxxxx.appspot.com",
  messagingSenderId: "111111111111"
};

var firestore;
setTimeout(function(){
  firebase.initializeApp(window.config);
  firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION).then(function() {
           firebase.auth().tenantId="xxxxxxxxxxxx";
           firebase.auth().signInWithEmailAndPassword("nevermoe@example.com", "yourpassword").catch(function(error) { //emailとpwログインの場合これ使う
      alert("login failed");
    });
  });
  firestore = firebase.firestore();
  const settings = {timestampsInSnapshots: true, experimentalForceLongPolling: true};
  firestore.settings(settings);
},5000);

上のコードをconsoleで実行できたら、下記のコードでログイン成功してるかを検証できる。

firebase.auth().currentUser.uid
docRef=firestore.doc("/collectionxxx/docxxx/subcollectionyyy/docyyy")
docRef.get().then((doc) => {
    if (doc.exists) {
        console.log("Document data:", doc.data());
    } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
    }
}).catch((error) => {
    console.log("Error getting document:", error);
});

OIDCのnonceの役目は何?

0x00 背景

略。

0x01 nonceとstateの違いは?

結論で言うと違いはとても簡単明瞭だ。stateパラメータで防ぎたいのはCSRF攻撃だ。OAuthの文脈でのCSRFは攻撃者のcode/tokenを被害者に強制使わせ、被害者を攻撃者の身分でログインさせる攻撃である。一方、nonceで防ぎたいのはtoken/code横取り攻撃。CSRFと逆で、token/code横取り攻撃は攻撃者が被害者のtoken/codeを取得し、被害者の身分になりすます攻撃である。

0x02 なぜnonceでtoken横取り攻撃を防げるのか

nonceはSPが発行して、idPがこのnonceを発行したtokenに入れる。SPがtokenをもらった時に、まずtokenに含まれたnonceをユーザーのsessionに記録したnonceと比較する。一致しない場合このtokenを破棄する。要するにtokenはユーザーのsessionと紐づいている。ここで気づいたかもしれないが、stateパラメータはユーザーのログイン状態としか紐づいてないので、nonceがわりにならない。

0x03 疑問

sessionを持っているSPだとnonceの検証はできるが、APIサーバーだと通常session持っておらず、来たtokenはそのまま信用するしかないがnonceの意味なくない?

0x03 参考

OpenID Connectのstateとnonceの違いがわからなかった

如何将AVD Android Emulator的通信转发到burp上

0x00 背景

好久没水文章了,水一篇。最近有工作需要使用Android Studio的Emulator来测试App,所以要将Emualtor的通信转发到PC上并由burp捕获。

0x01 问题

问题是AVD的Emulator使用了它自己的虚拟路由,无法在PC上找到VM的interface,所以无法在PC上捕获Emulator的通信。

0x02 解决

通过查阅资料 https://developer.android.com/studio/run/emulator-networking?authuser=1 发现AVD的Emulator会将发到10.0.2.2的通信转发到PC的loop back上,所以我们可以先将Emulator的所有通信转发到10.0.2.2,然后进一步在PC上将loop back的通信转发到burp上,操作如下:

  1. 在Emulator上将所有https的通信转发到10.0.2.2:8080上:
generic_x86_64:/ # iptables -t nat -A OUTPUT -p tcp --dport 443 -j DNAT --to 10.0.2.2:8080
  1. 使用如下的pf将PC的loop back上的通信转发到自己上,注意此时burp监听了loop back的8080端口:
# /etc/pf-share.conf
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
rdr-anchor "forwarding"

rdr pass on lo0 inet proto tcp from any to any port {8080} -> 127.0.0.1 port 8080

dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

启用:

sudo pfctl -evf /etc/pf-share.conf

这一步看似多余但是如果不在PC上再做一次NAT,则PC上返回的通信无法回到手机上。

AWS勉強メモ

0x00 背景

0x01 サービス毎のメモ

  1. STS
    https://aws.amazon.com/premiumsupport/knowledge-center/iam-restrict-calls-ip-addresses/
    APIコールをIPで制限したい場合、公式にはこのようなやり方が推奨されている。自分は疑問に思うのは、ここの Sample IAM User Policy の所に aws:SourceIp の制限をつけるのと Sample IAM Role Trust Policy に aws:SourceIp の制限をつけるのは違うのか?

    実際に試してみよう。
    例えば test-user-nevermoe という user にこのようなポリシーをアタッチする:
    {
    "Version": "2012-10-17",
    "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::123456789012:role/test-role-nevermoe",
    "Condition": {
    "IpAddress": {
    "aws:SourceIp": "1.2.3.4/32"
    }
    }
    }
    }

    この場合は test-user-nevermoe という user は 1.2.3.4 からログインする時に限って、test-role-nevermoe に aAssumeRole できることが確認した。

    次に、このような Trust Policy を test-role-nevermoe にアタッチしてみよう:
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": "arn:aws:iam::0123456789012:user/test-user-wan"
    },
    "Action": "sts:AssumeRole",
    "Condition": {
    "IpAddress": {
    "aws:SourceIp": "1.2.3.4/32"
    }
    }
    }]
    }

    この場合も同じく、test-user-wan のログイン IP が 1.2.3.4 の時にのみ、test-role-nevermoe に AssumeRole できる。

    この二つのやり方は違いがないが、role のほうに Policy で制限した方が管理しやすいかもしれない。ただし、個人的には、user を棚卸しするときの利便性を考えると、やはり user 側で IP 制限を書いた方が楽では?

  2. KMS
    KMS には Master Key が保存されており、Master Key は AWS から離れることはない。要するにユーザーである我々でも自分自身の Master Key を見ることはできない。データを暗号化する時に Data Key が発行され、データを Data Key で暗号化し (AWSがやってくれるか(Server-Side-Encryption)、ユーザー自身がやる(Client-Side-Encryption) )、平文の Data Key が破棄される (ユーザー自身で暗号化する時にユーザー自身で破棄する)。ただし Master Key で暗号化された Data Key は暗号化されたデータと一緒に保存される。復号したい時に暗号化された Data Key を KMS に復号を依頼して、平文の Data Key を手に入れる。平文の Data Key を使ってさらにデータを復号する。
    Symmetric keyは最大4096 byteの平文しか暗号化できない。Asymmetric keyはアルゴリズムによって数百byteの平文しか暗号化できない。
    CMK自動ローテーションでも、手動ローテーションでも、古いkeyで暗号化されたデータは自動的にre-encryptされない。自動ローテーションの場合はAWSが古いCMKと新しいCMKを両方内部で持ち、古いkeyで暗号化されたデータを復号する時に自動的に古いCMKを使う。手動ローテーションする場合はアプリケーション自身で古いkeyを保持して、あるいはre-encryptをしないといけない。

  3. S3
    S3は三つの権限制御方法がある。

    1. Resource-based Policy
    2. Bucket ACL
      Bucket ACLはほとんど使わない。server access loggingをEnableした時に、TargetバケットのBucket ACLのS3 Log Delivery Groupの項目にObject:Write, Bucket ACL:Read の権限をつけないといけない。
    3. Object ACL
      これもあんまり使わないが、他のアカウントからObjectにアクセス可能かを制御している。ちなみに、Object owner (your AWS account)の権限を全部奪うと、自分のアカウントのroot userからObjectにアクセスできなくなる。

    S3のバケット、オブジェクトにリクエストする時に通常AWS CLI / SDKはリクエストを署名してくれている。この署名付きのリクエストは五分間有効だそうだ。この性質を使えば、Appを作る時にS3を活用できる:認証を通ったユーザーに署名付きのリクエストをフロントエンドに渡し、そのリクエストでS3のObjectをアクセスさせる。
    S3のServer Side Encryption方法比較:

    注意:SSE-KMSはCustomer managed keyとAWS managed key両方使える。SSE-KMSはSymmetric keyしか使えない。Server Side Encryption以外に、Client Side Encryptionも使える、これはClient Sideでdata keyを使ってオブジェクトを暗号化しておいて、S3にアップロードする方法だ。Client Side EncryptionでKMSを使う時に、data keyの生成、使用はsdkがやってくれる。ここにサンプルコードがあるけど、s3ObjectKey はObjectファイルの名前で、暗号化キーなどと一切関係ないので勘違いしないで:https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingClientSideEncryption.html

    S3のPublic Accessをブロックしても、Signed URLを使えばインタネットからアクセス可能になる。

  4. Cognito
    Cognitoには二つのPoolがある。

    1. User Pool
      User PoolはFacebook、Google、Appleみたいにユーザーを作れる。作られたUser Poolの中のUserでSign-inできる。要するにUser PoolはOAuthのIDPのような存在。
    2. Identity Pool
      Identity Poolはfederation loginする時に権限をawsにmappingする時に使う。例えばfacebookでawsにログインしたユーザーにこのaws accountのs3へのアクセス権限を付与するようなシナリオで使える。さらに、Identity Pool の Authentication providers -> Choose role with rules で facebook account 別に違うroleを付与するruleが作れる。
  5. CloudWatch
    CloudWatchには二つの機能がある。

    1. Metrics
      マシンのCPU Usage などの情報を監視。
    2. Log
      各種Logを収集し、可視化するもの。

    metricsに注目してもらいたいのは二つ:

    1. system status:
      Loss of network connectivity
      Loss of system power
      Software issues on the physical host
      Hardware issues on the physical host that impact network reachability
      system status checkが失敗した時にrecoverができる。
    2. instance status:
      Failed system status checks
      Incorrect networking or startup configuration
      Exhausted memory
      Corrupted file system
      Incompatible kernel
      instance status checkが失敗した時にrecoverできない。rebootならできる。
  6. VPC
    Internet GWがアタッチされたsubnetはpublic subnetといい、逆にprivate subnetという。Internet GWがアタッチされても、InstanceにPublic IPがついてなければInternetからInstanceにInbound通信できない。Private subnetにあるマシンはInternetとのInbound通信も、Outbound通信もできない。Private subnetにあるマシンをOutbound通信できるようにするには、NAT GWをアタッチする必要がある。
    VPC Endpointを使えば、Internet越しじゃ無くても、VPCから他のAWSサービスにアクセスできる。

PrivateLinkというサービスは VPC の Endpoint Serviceである。VPCにあるカスタムサービスを他のVPCに共有するためのサービス。

  1. Storage Gateway
    Storage Gatewayを使うにはオンプレマシンにAWSのVMイメージをインストールする必要がある。

  2. Config

  3. Trusted Advisor
    Trusted AdvisorはSecurityだけでなく、Performance、CostなどのAWSのベストプラクティスにフィットしてないかをチェックしてくれる。Trusted AdvisorのSecurityはConfigと重複する部分もあるが、Configと違って、Trusted Advisorはルールのカスタマイズできない。

  4. その他
    kmsのkey policyは必須で、明示的に書かれたprincipalしかアクセス権限がない。一方でs3のbucket policyは必須ではないし、principalを明示的に書かなくても、role/userにs3へのアクセス権限があればアクセスできる。そしてkey policyでprincipalを"arn:aws:iam::012345678901:root" に指定すると、AdministratorAccess/KAWSKeyManagementServicePowerUserを所有しているuser/roleが自然にアクセスできるという隠れ仕様がある。推測ですが、S3にデフォルトの隠れPolicyがあって、"arn:aws:iam::012345678901:root" が必ず最初からついている状態になっている。

OAuth2.0を復習してLINEとヤフーの脆弱性見つけたら両社が経営統合された

0x00 背景

一 Web Pentester の立場から、毎回 OAuth 連携の案件が来る時に、どこが診断する必要なのか、どこが idP の SDK 使っているから診断不要なのかを見極める必要があり、このような背景において、OAuth2.0 をもう一回復習して、心得を共有したいと思い始めました。(0x01~0x08)。復習しているうちに、OAuth の idP 両社の脆弱性を見つけ、50万円賞金もらって終わりと思ったらいつの間に両社経営統合されました。この話を読みたい方は 0x09 から読んでください。

この文章を読む前提は二つあります:

  1. OAuth2.0 の各種認証 Flow (すくなくとも Implicit Grant, Code Grant, Code Grant with PKCE) を大まかに理解していること。
  2. この文章図解:OAuth 2.0に潜む「5つの脆弱性」と解決法に書いてある攻撃手法1~4を大まかに理解していること(攻撃手法5は今回の範囲外)。

これを前提に、以下の六つの質問に対して議論してみます。この六つの質問の答えが全部わかる人は 0x09 に進めてください。

  1. Code Grant では code が漏洩した場合に悪用できるか
  2. Web Message Response Mode では Covert Redirect 脆弱性は発生しうるか
  3. Web Message Response Mode では state パラメータは必須なのか
  4. Code Grant with PKCE では state パラメータが必須なのか
  5. WebView を利用する Implicit Grant は Token Interception される恐れはあるのか
  6. WebView を利用する Implicit Grant は何が良くないのか

0x01 Code Grant では code が漏洩した場合に悪用できるか

まず一番簡単だが、一番誤解が多い質問から説明します。

Code Grant では、code が何かしらの理由で攻撃者にもれた場合に (Auth Server が redirect 先を制限してない、Referer/URL で漏洩、Appの場合悪意 App Schema による漏洩等)、攻撃者がこの code を使って token と交換できるでしょうか。多くの方が「state パラメータがついていれば交換できない」という誤解を持っています。

しかし、state パラメータは code と紐づいてなく、攻撃者は code を入手したら、被害者の state を使わずに、自分が事前に用意した state と被害者の code で正規な URL を組み立てることができます。この URL を使えば被害者のアイデンティティーで認証を完結することができます。

0x02 Web Message Response Mode では Covert Redirect 脆弱性は発生しうるか

まず Web Message Response Mode とは何がを説明します。これは普段 OAuth ではあんまり聞きなれない単語かもしれませんが、2015年に HTML5 が普及してから導入された Mode です。これはあくまで実装の話で、OAuth の 新しい Flow ではありません。Web Message Response Mode は Implicit Grant とも、Code Grant とも組み合わせて使えます。簡単にイメージを説明すると、今まで各 Flow を紹介する際に、idP が token また code を Client に返す時に、redirect を使って Client に token また code を URL 経由で渡していると説明したが、これは実は Redirect Response Mode と言います。この Mode に対して、Web Message Response Mode という Mode があります。 Web Message Response Mode では、redirect を使わずに、HTML5 の postMessage を利用しています。Client のサイトから OAuth 認証を実行する時に、idP サイトに遷移せずに、Pop-up Window が開かれ、その新しい Window で OAuth の認証をします。認証が完了したら、postMessage API を使って、親 Window (Client のサイト) に token または code を渡します。もっと詳しい説明はこちらの IETF に記述されています:https://tools.ietf.org/html/draft-sakimura-oauth-wmrm-00

インタネット上では Redirect Response Mode の紹介が多いが、正直 Implicit Grant で Redirect Response Mode を使う idP は最近あんまり見かけず、例えば LINE はそもそも response_type=token をサポートしないし、Facebook と Google が提供している Login Widget (Javascript の SDK) は Web Message Response Mode を使ってます。

では、Web Message Response Mode を使っていると、かつて炎上していた Covert Redirect (この文章はわかりやすい:https://weblog.bulknews.net/covert-redirect-vulnerability-with-oauth-2-2c1f3083b1b4) という脆弱性はなくなるでしょうか?

答えは YES, Covert Redirect という脆弱性は無くなります。理由も自明ですが、Redirect という手順がなくなったからです。その代わりに postMessage が利用され、Open Redirector があっても OAuth への影響はないでしょう。

ここで少し余談ですが、なぜ LINE が Implicit Grant をサポートしないかというと、筆者の推測だと、OAuth Security Best Practice に書書かれているように、Implicit Grant に脆弱性がとても埋め込みやすい (token 漏洩しやすい、client の正規性確認できないなど) ので、おすすめしない Flow になっています。

0x03 Web Message Response Mode では state パラメータは必須なのか

0x02 で議論していた各 idP が提供している Web Message Response Mode の Javascript SDK を使う場合には、Client の実装不備による OAuth で良く発生する CSRF 脆弱性にも耐性があるでしょうか?

答えは YES, Web Message Response Mode を取り込んだ Javascript SDK を使うと、state パラメータはなくても CSRF はありえないでしょう。なぜかというと、idP が SDK をちゃんと実装していれば、message イベントが来る時に、postMessage の origin をチェックしているでしょう。この origin のチェックによって、非 idP の domain からの postMessage は一切拒絶されるので、CSRF の余地がありません。

ちなみに、Yahoo の Javascript SDK は親切に state パラメータを生成し、チェックしてくれていますが、Google と Facebook の Javascript SDK はいずれも state パラメータを使っていません。

0x04 Code Grant with PKCE では state パラメータが必須なのか

Appの場合、悪意に登録された App Schema による Code Interception攻撃を防ぐために、Code Flow with PKCE という手法が採用されます。多くの idP が提供している SDK が、PKCE を実装する時に state パラメータも必須になっているが、実際に state パラメータがなくても(Clientの実装忘れ等)、CSRF に耐性あるでしょうか?

答えは YES, state パラメータがなくても、PKCE は CSRFに耐性があります。この答えにたどり着くまで少し考えが必要ですが、PKCE を使う場合に、code_challenge と code は idP サーバで紐づいていて、攻撃者は code_verifier が知らない限り、 自分の code を他人に使用させることはできません。
PKCE

0x05 WebView を利用する Implicit Grant は Code / Token Interception される恐れはあるのか

WebView を利用して、OAuth の認証 SDK を提供している idP がすくなくありません。むしろ WebView の中で OAuth 認証をさせるのはもう各 idP のデファクトスタンダードになっていると言えます。 Code / Token Interception という問題は Native App の OAuth 認証時に、外部ブラウザを使う時に発生し得る問題ですが、WebView を使う場合にも Code / Token Interception 攻撃発生し得るかみてみます。

Code / Token Interception が発生するタイミングは、OAuth の認証が完了し、 Client App に遷移して戻る時です。この際に違うクライアントに遷移してしまったら Code / Token Interception が発生します。ただし、Native App 用の WebView を使った SDK は、殆どの idP はその WebView の shouldOverrideUrlLoading メソッドを上書きし、認証完了後の Redirect を App 内に閉じるようにしています (e.g. Facebookの場合:https://github.com/facebook/facebook-android-sdk/blob/4.x-branch/facebook-common/src/main/java/com/facebook/internal/WebDialog.java#L578)。このような実装であれば、外部 App への誤遷移によって、 code / token が外部 App に漏れることはないでしょう。

しかし、他の idP も調べたら脆弱な実装は見つかりました。例えばヤフーの YConnect を使う場合に、ヤフーのライブラリーは WebView を改造することなく、認証成功後に Redirect する時に、App 本体から Export しているカスタムスキーマを利用して、WebView から App 本体に遷移させます。この状況は何が不味いかというと、WebView からカスタムスキーマをオープンする時に、必ずしも該当 WebView を開いた App が優先的に開かれる保証はないです。要するに、他の Evil-App も同じカスタムスキーマを登録したら、正規 App の WebView から Evil-App を開く可能性があります。これは Code / Token Interception に繋がります。

0x06 WebView を利用する Implicit Grant は何が良くないのか

前述の事例から見ると、WebView を利用した Native App はどんな脆弱性も作り込めなく、最強な作り方では?と思ってしまう方も居ると思いますが、しかし、このデファクトスタンダードは本当にいいのか考えましょう。

RFC8252の8.12節で説明された通りに、WebView を使うとそもそも OAuth の意味が無くなります。OAuth は信用できない第三者に ID / PW を提供しないで身分を認証するプロトコルであり、第三者 App の中の WebView (WebView に偽装するものも含め) に直接 ID / PW を入れるのはどう考えても OAuth 本来の役目が成り立たないでしょう。

ここで LINE を褒めてあげたいんで、LINE の場合は WebView 方式の SDK を提供せずに、ちゃんと外部ブラウザ方式で認証をしています。

0x07 まとめ表

Flow 別の Client の (SDK使わず) 実装により、脆弱性を埋め込む可能性

Y -- Clientの実装により、脆弱性を埋め込む可能性がある
N -- Clientの実装と関係なく、脆弱になることはない

脆弱性 Implicit Grant Code Grant Code Grant with PKCE
Token Replace Y N N
Covert Redirect Y N N
CSRF Y Y N
Token Interception Y - -
Code Interception - Y N

この表から見ると、やはり Code Grant with PKCE は一番安全だなと感じますよね。

今回調べた四社 idP のサポートしている Flow と 提供している SDK

Identity Provider Implicit Grant Code Grant Code Grant with PKCE
LINE サポートしない Client 各自で実装 Native SDK
Yahoo! Japan Javascript SDK, Web Message Response Mode Javascript SDK, バックエンドはClient 各自で実装 サポートしない
Google Javascript SDK, Web Message Response Mode Client 各自で実装 Client 各自で実装
Facebook Javascript SDK, Web Message Response Mode Client 各自で実装 サポートしない

今回調べた四社 idP が提供している SDK を使う場合に脆弱性を埋め込む可能性

Native SDK Client の実装により脆弱を埋め込む可能性
LINE PKCE ない
Yahoo Implicit / Hybrid 外部ブラウザを使う実装は Code Interception と Token Interception に脆弱;WebView を使う実装もカスタムスキーマ Export しているので脆弱になる;Stateパラメータはデベロッパー自ら生成するので、デベロッパーによってCSRF脆弱性が生じうる
Google Implicit Grant Google Sign-in 使うと Implicit Grant になるが、WebView をカスタマイズしているので Token Interception 攻撃されない。PKCE使おうとしたら自前でクエリを組み立てる必要がある。
Facebook Implicit Grant WebView をカスタマイズしているので Token Interception 攻撃されない
Javascript SDK Client の実装により脆弱を埋め込む可能性
LINE ない Client の実装による
Yahoo Implict Grant Web Message Response Mode + state なので、Covert Redirect と CSRF 攻撃されない
Google Implicit Grant Web Message Response Mode なので、Covert Redirect と CSRF攻撃されない
Facebook Implicit Grant Web Message Response Mode なので、Covert Redirect と CSRF 攻撃されない

0x08 結論

結論は意外と簡単にまとめられます。idP が提供している SDK を利用している場合に、Client の実装に関わらず脆弱になる可能性はほとんどないと言えます。ただし、idP の提供している SDK に脆弱性があったり、一部のパラメータ生成がデベロッパーに任せたりしたら話は違いますが。。。

例として、次の二段落で idP 側の脆弱性について紹介します。

0x09 今回見つけた脆弱性(LINE社)

まず今回5000ドルの報奨金をいただいたLINEのOAuthの脆弱性に付いて紹介します。とてもシンプルな脆弱性で、一言でいうと、PKCEの実装にcode_verifierとcodeの紐づけをAuth Serverでチェックしていないというところがダメです。
なぜこんな簡単な脆弱性は今まで見つかってないのかというと、おそらくこの PKCE 機能はドキュメントされていないからではないかと推測しています。LINE の line-sdk-android を実際に動かして通信みないと、LINE の OAuth が PKCE 対応していること自体に気づけないし、さらに、パラメータの名前は標準的な code_verifier と code_challenge ではなく、otp と otpId と名付けされて、一目ですぐ PKCE だと気づきにくいでしょう。(同社の情報によると、実装当時はまだ PKCE の標準が定めていないから code_verifier などの標準単語使わなかったわけだそうです。)
実際にこの脆弱性を利用するために、被害者アプリとおなじ package name の悪意アプリをインストールする必要があることです。悪用するには少しハードルがあると言えます。さらに、PKCE が実装されている Identity Provider 自体も少なく、Facebook でもそもそも PKCE 対応していないし、PKCE 対応しようとするだけで偉いと思います。ただし、ちゃんと実装しましょうね。

0x0A 今回見つけた脆弱性(ヤフー社)

次の例は Yahoo の OAuth にあります。0x05にすでに少し触れてまして、簡単に説明すると、ヤフーの OAuth SDK は超手抜き実装で Callback 用のカスタムスキーマを Export されていて、WebView で認証しても、外部ブラウザで認証しても Code Interception, Token Intercetion ができてしまいます。外部ブラウザーを使う OAuth 認証の Code Interception と Token Interception は基本 PKCE でしか防げないので、単に PKCE 未実装だけだと脆弱性と言えるか微妙ですが、少なくとも WebView を使った認証フローは PKCE 無しでも Code Interception と Token Interception されない実装はできるはずです。Facebook も PKCE 未対応ですが、Facebook の SDK では WebView の shouldOverrideUrlLoading メソットをオーバライドすることで、Callback 時に外部アプリに遷移出来ないようにされています。一方でヤフーの手抜き実装だと WebView をカスタマイズしてなく、Callback の URL スキーマが来た時に OS の機能に頼ってどのアプリを立ち上げるのを任せている状態で脆弱です。

これの修正としてはまずカスタマイズスキーマ(Android の場合)を android-app:// スキーマに入れ替わって、その後根本的な対策 PKCE 実装を追加されたらしいです。

0x0B OIDC の Certification サービスについて

もう一つ気になることがります。OpenID Foundation は OpenID Connect Certification というプログラムがあって、この組織の特定の要件を満たすと、会社のサイトに認定されてるよ的なロゴを貼ることができます。要するにオンラインショッピングする時によく見かける SSL Site Seal Logo のようなもんです。ヤフー社のはこちらに貼られていますhttps://developer.yahoo.co.jp/yconnect/v2/。このロゴを見ると、すごい「セキュアだ!」と安心感が出るかもしれませんが、よくよくここの認定に関するドキュメントを読んだらhttps://openid.net/wordpress-content/uploads/2018/06/OpenID-Connect-Conformance-Profiles.pdf、セキュリティ上の要件は一つも書かれていません。結局 OIDC の Site Seal Logo があっても、どの程度の安全性をクリアしているのかを表明するものではありません。何を言いたいかというと、OIDC といえば認証認可という安全性は極力求められている分野のはずですが、OpenID Foundation で発行した Certification には安全性レベルの定義はないのはやや気持ち悪いです。

0x0C 余談

今回特に LINE と Yahoo で見つけた脆弱性の話しましたが、両社の対応スピード感等に大きな差が感じました。LINE には7月12日に脆弱性報告し、2週間後に修正され、一ヶ月後に賞金を講座に振り込まれました。Yahoo はバグバウンティプログラムが存在しないので、8月5日にIPA経由で報告したんですが、一通目の返信は報告してからおおよそ三週間後でした。11月12日に Android 版 SDK の work around がリリーされ、12月19日にやっと PKCE がリリースされました。ちなみに、11月18日に LINE とヤフーが経営統合され、ヤフーのセキュリティ事情も LINE と統一されたら嬉しいですよね。そして先日 YJTC でこのような発表安全・安心に向けたYahoo! ID連携の改善とネイティブアプリのID連携の実装があり、スライドを読んだら「なるほど PKCE はなかっただけでなく、PPID も対応してなかったですね」と思いました。LINE の場合は PKCE はあったし、PPID もずっと前から対応してた気がします。まあある意味では両社のセキュリティレベルも統一されつつあると言えるでしょうかね。めでたし。

(完)

0x0D その他の参考情報

NULL

forensic要素初探

0x00 背景

最近做了一些forensic的调查,随便写一下,随时补充。

0x01 Windows

持久化:

  1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\
  3. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks{xxxxxxx-xxxx-xxxx-AD98-xxxxxxxxxx}

在驱除病毒时,往往仅删除了病毒的注册表文件还不够,需要重启电脑。或者使用命令行删除计划任务或者服务:

sc delete ServiceName
schtasks /delete /tn TaskName

Continue reading