Flatt Security Blog

株式会社Flatt Securityの公式ブログです。プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

株式会社Flatt Securityの公式ブログです。
プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

決済代行サービスの実装における検証不備を悪用/Pwning Old WebKit for Fun and Profit【Security․Tokyo #1】

株式会社Flatt SecurityとTokyo HackerOne Clubが共催した脆弱性勉強会「Security․Tokyo #1」より、今回は、LT3「決済代行サービスの実装における検証不備を悪用」とLT4「Pwning Old WebKit for Fun and Profit」の発表内容をお届けします。

<注意事項> 本記事は技術的知見の共有を目的としています。掲載された発表内容の悪用や曲解、その他社会通念に反する行為を固く禁じます。

▼LT 1,2はこちら▼

blog.flatt.tech

決済代行サービスの実装における検証不備を悪用

スライド

speakerdeck.com

プロフィール

Andrew Croft(bubby963)(@bubby963)

Andrewは攻撃系セキュリティ検査の専門家として5年間以上の実務経験を持ち、現在はデロイトトーマツサイバー合同会社のRed Team Operations部門にてシニアスペシャリストとして活躍しております。業務外でも積極的にBug Bounty活動を行っており、高・緊急レベル脆弱性50件近くを含む計80件の脆弱性を国内外の大手企業への報告実績を持っております。

ネットオークションでの不正落札を可能にする脆弱性

先日バグバウンティで発見した、Stripe APIの実装不備による脆弱性について発表させていただきます。この脆弱性は「オークションの終了予定時刻より前に、最初に入札した額でオークションに出品されている商品を落札・購入できる」というものです。

対象アプリでのオークション商品の購入の流れ

今回対象となったアプリは、信頼されたユーザーが他のユーザーに対して、商品を様々な方法で販売できるアプリです。販売方法の1つにオークションがあります。

当該アプリに置ける、オークションでの商品購入の流れは以下の通りです。

  1. 決済手段を登録済みのユーザーがオークションに参加
  2. オークションの実施期間中、最高入札額より高い額であれば、任意の金額で入札が可能
  3. オークション終了時に、落札者が登録した決済手段を用いて、Stripe API経由で決済を実行

Stripe APIの呼び出しをはじめとする、決済関連処理のほとんどはバックエンドで実行されているので、攻撃者から触れるところはあまりありません。

マーケットプレース商品の購入の流れ



アプリには、オークションとは別に、一定価格で商品を販売できるマーケットプレース機能もあります。マーケットプレースから商品を購入する流れは、オークションでの商品購入時と若干異なります。

  1. ユーザーは、買いたい商品の購入手続きを開始するリクエストを送信
  2. StripeによりPaymentIntentというオブジェクトが生成され、それを一意に識別するPaymentIntent Client Secretがユーザー側に返される
  3. ユーザーのブラウザから、登録済みの決済手段の識別子とPaymentIntent Client Secretを渡して、Stripe APIを直接呼び出すことにより決済を実行

マーケットプレースでは、Stripe APIを呼び出して決済を実行する処理がクライアント側で行われます。ここが、オークション商品購入時と最も大きく異なる点です。

StripeのPaymentIntentとは

そもそも、StripeのPaymentIntentとはどのようなものなのでしょうか?

Stripeの公式仕様書では以下のように定義されています。

PaymentIntent (支払いインテント) API を使用して、複雑な決済フローを処理できる組み込みを構築します。この API は、支払いの作成から決済までを追跡し、必要に応じて追加の認証ステップをトリガーします。

簡潔に説明すると、これは支払い開始から完了までの決済フローをユーザー及び支払いセッションごとに管理するための仕組みです。基本的には、決済手段を登録できるPayment Method APIと組み合わせて使う形になっています。各PaymentIntentオブジェクトに、PaymentIntent Client Secretと購入価格や通貨などの支払内容に関する詳細情報が格納されます。

オークション商品のPaymentIntentの取得

実は、今回対象となったアプリには、マーケットプレースと同様にオークション商品に対するPaymentIntent Client Secretが発行できるGraphQLのエンドポイントが存在しました。発行されるインテントでは、購入価格が「発行時点の最高入札額」となっていました。そのため、最初に入札した額でオークション商品を落札・購入できるという攻撃が成立してしまいます。攻撃の仕組みについては、この後もう少し詳しく説明します。

この攻撃の特徴は以下の通りです。

  • PaymentIntent Client Secret発行時点の最高入札額で商品を落札・購入可能
  • 自分以外のユーザーが最高入札者だった場合でも、PaymentIntent Client Secretを発行可能
  • PaymentIntent Client Secret発行後に最高入札額が上がった場合でも、発行時点の最高入札額で落札・購入可能
  • オークションの終了予定時刻より前に商品を落札・購入可能

攻撃の流れ

では、具体的な攻撃手順の解説に移ります。



まず、オークションに出品されている商品に対して、1ドルなどの低額を入札額に設定し、入札します。



リクエストが正常に受け付けられたことが確認できたら、オークションを識別するためのauctionidを渡し、ターゲットのオークション商品に対して、その時点の最高入札額に紐づいたPaymentIntent Client Secretの発行リクエストを送信します。これに対する応答内容から、PaymentIntent Client Secretの値を取得できます。



そして、入手したPaymentIntent Client Secretに加え、ユーザーの登録済決済方法を識別するPayment Method ID、当該アプリのStripe Public Keyを渡すことで、Stripe APIを直接呼び出して決済を実行することができます。

PaymentIntent Client Secret発行時の最高入札額で決済ができてしまうことが、ログの画像からもお分かりいただけると思います。

その他応用できる場面の考察

PaymentIntent Client SecretがStripeからユーザーに渡される仕様のWebサイトであれば、こういった脆弱性が潜在している可能性があります。Stripeの公式手順書通りに実装した場合はこの仕様になるので、標的になり得るサイトが多いのではないかと推測しています。

今回紹介したオークションの仕組みを悪用する攻撃は特殊かと思いますので、もう少し一般的にあり得そうな脆弱性の候補を考えてみました。

まず、クレジット制度やポイント制度のあるサイト上で、クレジットやポイントの残高を差し引いた額を持つPaymentIntent Client Secretを多数確保して、順番に決済を実行していくという悪用の可能性があります。クレジットの認証機能に不備がある場合は、一度しか使えないはずのクレジットを何度も使えてしまう脆弱性が成立する可能性があります。

また、今回紹介したアプリのように、ユーザーが他のユーザーに向けて商品を販売できるサイト上で、低価格で販売登録した商品に対してPaymentIntent Client Secretを発行しておいてから、当該商品の価格を大きくあげて、発行しておいたPaymentIntent Client Secretを利用して決済を実行し、販売金額を水増しするという悪用も考えられます。商品販売後に、商品を販売するユーザーのアカウントに加算される金額が、実際にStripe API経由で決済された金額ではなく、商品の販売価格を元に計算された金額に基づく場合は、このような脆弱性が考えられます。

これらはビジネスロジック系の脆弱性ということで、やはりアプリごとに発生条件が大きく異なると思います。PaymentIntent Client Secretを実装する場合は、アプリの処理の流れや機能などを踏まえ、様々な攻撃手法を想定して調査してみるのが良さそうです。

Pwning Old WebKit for Fun and Profit

スライド

speakerdeck.com

プロフィール

hhc0null(@hhc0null

ハッカーと友達になりたい

Outline

2023年の今、なぜ古いWebkitをターゲットにするのか、気になっている方もいると思いますが、これは2023年の今も、古いWebkitを元にしたブラウザが動いているからです。

また、”Stop Using QtWebKit and also Wkhtmltopdf”(QtWebkitとwkhtmltopdfの使用をやめよう)ということも訴えていきたいと思います。このような強い言葉を使う理由は、QtWebKitもwkhtmltopdfも、悪意のあるHTMLを受け取ったら、その時点でコンプロマイズされてしまう可能性があるためです。

2023年の今、なぜ古いWebKitをターゲットにするのか?

WebKitとは

WebKitとはSafariの中身、OSSのWebブラウザエンジンです。以下のコンポーネント*1から構成されています。

  • bmalloc:WebKitのmalloc実装
  • WTF(Web Template Framework):独自のテンプレートライブラリ
  • JavaScriptCore:JavaScriptエンジン
  • WebCore:Web APIやHTML、XMLとCSSパーサの実装
  • WebKitLegacy:macOSのWebViewとiOSのUIWebViewの実装
  • WebKit:macOSとiOSのWKWebViewの実装

など

今回は、JavaScriptエンジンであるJavaScriptCoreをターゲットとします。

Fun:WebKitは教材がいっぱい

Fun and ProfitのFunの部分に当たるのですが、WebKitに関する教材はたくさんあります。

なぜかというと、Pwn2Ownなどの有名なハッキングコンテストで、たくさん叩かれてきたからです。また、Zero Day InitiativeZerodiumなどが、バグバウンティの一環でWebKitに関する脆弱性を買い取っています。そして、これらで見つかった脆弱性が、PlayStationシリーズやNintendo Switchなどのゲームコンソールのハッキングに悪用されていることがあるというのも理由の1つかもしれません。

皆さん優しいので、叩き方を教えてくれます。あえて古めのものを集めてみましたが、例えば以下のような記事などがあります。

blog.xyz.is

www.phrack.org

scarybeastsecurity.blogspot.com

最後に紹介したのは、元Google Project ZeroのChris Evansさん(@scarybeasts)による記事です。今回は、こちらの記事を参考にしてexploitを書きました。実際に書いたのは4年ほど前なのですが、非常に参考になりました。この場を借りて御礼申し上げます。

このようなトピックに興味のある方は、以下のようなキーワードで検索すると、関連記事が色々出てくるかと思います。

webkit, javascriptcore(jcs), vuln, exploit, pwn

Profit:こんなところにWebKit

先ほどお話したバグバウンティも十分Profitに値するとは思うのですが、世界最高峰レベルの脆弱性を求めているので、さすがに高度すぎます。私はしがないペンテスターなので、手の届く範囲でやっていきたいです。ですので、組み込み機器で動くWebブラウザやサーバサイドで動くWebブラウザをターゲットにしていこうと考えていました。

具体的には、ヘッドレスブラウザの先駆けであるPhantomJSや、HTMLをPDFにコンバートできるPDFコンバータ・wkhtmltopdfなどの開発が終了したものです。wkhtmltopdfに関しては、SSRF*2やLFI*3が発見された事例があります。

WebKitの多様性

WebKitは色々な環境にポーティングされています。メンテナンスされている移植の例としては以下のようなものがあります。

  • Apple:Mac Port, Windows Port
  • GNOME:WebKitGTK
  • WPE WebKit Team:WPE WebKit

一方で、QtWebKitのようなメンテナンスされていない移植の例も存在します。QtWebKitは、QtへポーティングされたWebKitで、ChromiumをベースとしたQt WebEngineの誕生により開発が終了しています。開発終了後、WebKitバージョンのアップグレードを目的とした、有志によるQtWebKit復活プロジェクトが立ち上がったようなのですが、2020年頃を最後にコミットは発生していないようです。

Stop Using QtWebKit and also wkhtmltopdf

“Stop Using QtWebKit”

「QTWebKitを使うな」という強めの言葉ですが、これはGNOMEのMichael Catanzaroさんが2022年に発表した記事のタイトルです。「脆弱性があって危険なので、使わないでください」という注意喚起の内容でした。

blogs.gnome.org

Michaelさんは、実は2016年にも、ブログ記事で同様の指摘を行っていました。

blogs.gnome.org

今回は6年越しの指摘になりますが、「まだまだ脆弱性が多いので、使わないように」と再度呼びかけた形です。

…and Also wkhtmltopdf

wkhtmltopdfは、QtWebKitを利用しています。自前でホストしてはいますが、WebKitのバージョンはSafari -536.11(2012-05-11)で、10年前の脆弱なコードを使っていると言えます。

2012年前後のWebKitの脆弱性

2012年前後のWebKitの脆弱性としては、Mobile Pwn2Own 2012で実演されたCVE-2012-3748と、CVE-2013-2842があります。CVE-2012-3748は配列ソートのコールバックがステートを変えてしまって、UAF攻撃などが起きてしまうというものです。CVE-2013-2842はChromiumで見つかった脆弱性です。Chromimumは元々WebKitからフォークしたものなので、フォークした直後はWebKitとChromiumのデータベースは共通していました。そのため、WebKitのコードの中にも見つかりました。

CVE-2012-3748



この画像の💾で示した箇所が、ステートをスタック上に保存してしまっているところです。ヒープ領域のポインタをスタックに置いてしまっています。



⚠️で示した箇所は、ソート処理の比較関数がコールバックとして呼ばれるところです。これはAVL木を使っていて、insertのところで比較が走ります。

🔥で示した箇所は、ステートが変わることによってバッファオーバーフローやUAF、Double Freeなどが起きる箇所です。このように、色々な箇所で発火するというのがこの脆弱性の特徴です。

まとめ

CVE-2012-3748は、wkhtmltopdfで実際に今でも動く脆弱性です。wkhtmltopdfは既に開発を終了してしまい、脆弱性が修正されることはないので、開発者の皆さんは使わないようにしてください。ペンテスターの方は、脆弱性を見つけたらExploitを書いてみて、報告書の厚みを増しましょう(笑)。Happy Hacking!

References

  • WebKit/Introduction.md at dacbd7c36056647c1867f34236ade6815002e1f1 · WebKit/WebKit

github.com

  • "NVD - CVE-2020-21365"

nvd.nist.gov

  • "NVD - CVE-2022-35583"

nvd.nist.gov

  • "Introducing the Qt WebEngine"

www.qt.io

  • "Updated WebKit to 2dea2a19feedc165596b933fe9509ddd0caf4d15 · wkhtmltopdf/qt@929b444"

github.com

  • "Search · Fix build with GLib 2.31"

github.com

  • "Fix build with GLib 2.31 · WebKit/WebKit@ca8ddd2"

github.com

  • "97603 – (CVE-2012-3748) (Mobile Pwn2Own) ZDI-CAN-1657: : WebKit Shiftcount Vulnerability"

bugs.webkit.org

  • "226696 - Security: use-after-free removing a frame from its parent in a beforeload event of an OBJECT element - chromium"

bugs.chromium.org

▼LT 1,2はこちら▼

blog.flatt.tech

Security․Tokyoでは運営メンバーを募集しています!(応募〆切:3/17(金)18:00)

オフライン開催の脆弱性勉強会「Security․Tokyo」では、セキュリティに関心のある/熱量のある運営メンバーを募集しています! 興味を持ってくださった方はぜひ下のリンクから応募をお願いします。 (当日、会場で応募いただいた方は、今回の追加募集が終わり次第ご連絡しますので、少々お待ちください)

docs.google.com

Security․Tokyoを企画したFlatt Security代表取締役CEOの井手が、今回の勉強会企画開催に込めた思いについて書きました。こちらもぜひ併せて ご覧ください!

flatt.tech