当社のAIエンジンNeutronが、UCバークレーのCyberGymベンチマークで97.1%のスコアを記録しました。 詳細を見る

ディープダイブ

ディープダイブ

fairplay-decrypt:FairPlay IPAのオフライン復号

公開ツールがジェイルブレイクしたiPhoneから16バイトのFairPlayアカウント認証情報を取得し、対応するIPAをオフラインで復号します。

要点

  • fairplay-decryptは、アプリを起動せずにApp StoreのFairPlay暗号化IPAを復号するGPLv3ツールです。IPAを所有するApple Accountの16バイト認証情報を使用します。
  • 取得ツールには、iOS 10以降のジェイルブレイク済みiPhone、root SSH、そのアカウントでインストールしたアプリが必要です。復号はmacOSまたはLinux上のPython 3.9以降でオフライン実行します。
  • 弱点は、各アプリの鍵を展開する再利用可能なアカウント認証情報です。1回の取得で、そのアカウントが所有する対応IPAを復号できます。CVEは割り当てられておらず、CISA KEVカタログ2026.11.10にFairPlayの項目はありません。
  • アカウント認証情報を取得できる状況では、IPAを公開情報として扱ってください。秘密はサーバー側に置き、再パッケージされたビルドを検出し、App Store以外からアプリをインストールしないでください。「修正方法」を参照してください。

影響を受けますか?

アプリがFairPlayで暗号化されたarm64 IPAとして配布され、攻撃者がそれを所有するApple Accountの認証情報を取得できる場合に影響を受けます。次のすべてを満たす必要があります。

  • App StoreビルドがFairPlayで暗号化されている。ツールはLC_ENCRYPTION_INFO_64を持ち、cryptidが0ではないarm64 Mach-Oスライスだけを処理します。
  • 攻撃者が、アプリを所有するApple Accountの対応する種類の16バイト認証情報、またはそのアカウントに紐づくMac登録から復元した再利用可能なモデルを保持している。
  • 攻撃者がIPAを入手している。そのアカウントで購入する、パートナーから受け取る、または盗むことができます。
  • macOSまたはLinuxでツールを実行できる。復号にAppleや貴社サーバーへのネットワークアクセスは不要です。

これはアプリのリモート脆弱性ではありません。IPAを囲むFairPlayの性質であり、取得手順には侵害されたデバイスまたは登録済みMacが必要です。あるアカウントの認証情報は、別のアカウントが所有するアプリを復号しません。ツールはFairPlay Streamingの動画、32ビットバイナリ、暗号化されていないIPAを処理しません。

通常の認証情報は通常のApp Storeアプリを対象とします。取得ツールのREADMEには、Apple Arcadeアプリには別のArcade認証情報が必要とあり、1回の取得では両方の種類をカバーできません。

取得経路 攻撃者に必要なもの 得られるもの
ジェイルブレイク済みiPhone (fairplay-decrypt) iOS 10以降、root SSH、対象アカウントでインストールしたアプリ、取得ツールをビルドするXcodeとldidを備えたMac 16バイトのアカウント認証情報。そのアカウントが所有する対応IPAのオフライン復号
登録済みMac (UnfairPlay) Mac App StoreにサインインしたMac、インストールして一度起動したiPhoneアプリ、対応するIPA 再利用可能な登録モデル。同じ登録の他のIPAの復号
漏えいした認証情報 どちらかの経路で得た16バイト認証情報と、そのアカウントが所有するIPA デバイスなしのオフライン復号

IPAが暗号化されているか確認します。macOSではメインバイナリを抽出し、暗号化のロードコマンドを読みます。

unzip -p App.ipa Payload/App.app/App > /tmp/App
otool -l /tmp/App | grep -A4 LC_ENCRYPTION_INFO_64
codesign -dv --verbose=4 /tmp/App

cryptidが1ならページは暗号化されています。0ならバイナリはすでに平文です。Payload/App.app/AppはIPA内の実行ファイルパスに置き換えてください。codesignコマンドは署名のTeamIdentifierを表示するので、自社の値と比較します。

修正方法

リポジトリは修正版を公開していません。これは復号ツールであり、パッチ版を持つ製品ではないためです。次の手順で露出を減らし、復号されたコピーが明かす情報を限定できます。

  1. 復号されたIPAを公開情報として扱います。APIキー、署名秘密、機密にすべき独自アルゴリズムを削除します。クライアント側の秘密は、ページが平文になれば読めます。
  2. 機密の判断をサーバーに移します。短命のトークンでサーバー側の認可を行い、バイナリに同梱された値を信用しないでください。
  3. 再パッケージ検出とサーバー側アテステーションを追加します。AppleのApp AttestとDeviceCheckは改変されたクライアントを検出できますが、復号は防げません。
  4. ユーザーには、App StoreまたはTestFlightからのみアプリをインストールさせます。管理対象の端末では、管理カタログ外からのインストールをブロックします。
  5. アカウント認証情報が取得された可能性がある場合は、そのアカウントでの配布を停止し、そのアカウントのすべてのIPAを露出済みとして扱います。購入履歴を確認してください。

これらの手順は、そのアカウントが所有するIPAの復号を防ぎません。復号されたコピーが明かす情報と、悪用の仕方を限定します。

根本原因は何ですか?

FairPlayはSC_Info内の2つのファイルから導出した鍵で各4 KBページを暗号化し、その連鎖は16バイトのアカウント認証情報から始まります。暗号はAES-128です。弱点は暗号の破綻ではなく、ルート秘密の保管場所にあります。

重要な3つのファイル

  • <Name>.sinfは、アカウントのname、16バイトのiviv、440または448バイトのprivレコードを持つアトムツリーです。
  • <Name>.supfまたは<Name>.v5.supfは、暗号化されたページごとに32バイトのレコードを持ちます。16バイトのラップされた鍵と16バイトのAES-CBC IVです。
  • arm64 Mach-OヘッダーのLC_ENCRYPTION_INFO_64は、cryptoff、cryptsize、cryptidで暗号化ページを示します。

derive_work16()は、アカウント認証情報とprivレコードから、アプリごとの16バイトのワーク鍵を作ります。抜粋のname、iviv、credential、raw_privは、パーサーが読むSINFフィールドと16バイト認証情報です。鍵は認証情報をバイト0x30とXORしたもので、認証情報そのものではありません。IVはアカウント名とivivのMD5です。

iv = hashlib.md5(name + iviv).digest()
op = Cipher(algorithms.AES(_xor(credential, b"0" * 16)), modes.CBC(iv)).decryptor()
clear = op.update(raw_priv) + op.finalize()
if clear[:4] != b"itun" or clear[20:24] != b"key " or clear[44:48] != b"iviv":
    raise ValueError("credential does not decode this SINF priv record")
return clear[24:40]

derive_page_key()は、16バイトのラップされたレコード、ページ番号、ワーク鍵を受け取ります。ワーク鍵で3つの16バイト元ブロックをAES-128-ECBで暗号化し、finish()という独自変換で混ぜます。

a, b, c = (
    struct.unpack(">8H", block_transform(s, work))
    for s in source_blocks(wrapped, absolute_index)
)
return struct.pack(">8H", *finish(_xor_int(finish(_xor_int(finish(a), b)), c)))

finish()は、16ビットの4ラウンドと32ビットの4ラウンドの加算、二乗、XORを実行します。コードのコメントでは、一方の桁上げを保持し、他方を破棄しています。この変換はAES上の難読化であり、2つ目の秘密ではありません。16バイトの結果がページのAES-CBC鍵で、SUPFレコードの次の16バイトがそのIVです。

アプリごとの鍵はアカウント秘密で暗号化されているため、1つの認証情報が、そのアカウントが所有する対応アプリのprivレコードを復号します。取得ツールはデバイス上でその認証情報を復元します。fairplaydのセレクター関数にハードウェアブレークポイントを設定し、インストール済みアプリ経由でライセンス操作を発生させます。

取得ツールはセレクター出力とkeybag状態を取得します。その後、その状態をデバイスのUDIDとツールのテーブルと組み合わせ、16バイトファイルを作ります。設計は、デバイスのOSがfairplaydの状態を秘密に保つと想定しています。ジェイルブレイク済みでrootアクセスを持つデバイスは、その信頼境界を提供しません。これが設計上の弱点です。認証情報はアカウント全体にわたり、再利用可能で、侵害されたデバイスのユーザー空間から復元できます。

どのように悪用されますか?

ジェイルブレイク済みiPhoneと、対象アプリを所有するApple Accountを持つ攻撃者は、認証情報を1つ取得し、対応するIPAをオフラインで復号します。公開ツールは次の経路をたどります。

  1. iOS 10以降のジェイルブレイク済みiPhoneをroot SSHアクセス付きで用意し、対象アカウントのApp Storeアプリを少なくとも1つインストールします。
  2. Xcode、ldid、idevice_id、iproxyを備えたMacで取得ツールをビルドし、credential-retrieval/retrieve.pyをデバイスに対して実行します。
  3. 取得ツールはfairplaydにブレークポイントを設定し、インストール済みアプリを起動してライセンス操作を発生させ、セレクター出力とkeybag状態を取得し、credential.binを書き込みます。
  4. 同じApple Accountから対象IPAを入手します。
  5. decrypt.pyをIPAと認証情報で実行します。Mach-Oの暗号化コマンド、SINFレコード、SUPFテーブルを解析し、ワーク鍵と各ページ鍵を導出し、ページを復号し、cryptidを消去して新しいIPAを書き込みます。
  6. インストールする必要がある場合は出力に再署名します。復号は暗号化マーカーを消しますが、有効なコード署名は作りません。

復号経路のどこもAppleに接続しません。デバイスとのやり取りは取得手順だけです。復号器は純粋なPythonで、macOSまたはLinuxで動作します。

攻撃の流れは?

ジェイルブレイク済みデバイスがfairplaydを観察してアカウント認証情報を復元し、その認証情報が各アプリの鍵を展開するため、ページをオフラインで復号できます。

flowchart TD A["root SSHを持つジェイルブレイク済みiPhone"] --> B["fairplaydへのハードウェアブレークポイント"] B --> C["セレクター出力とkeybag状態の取得"] C --> D["アカウント認証情報を1つ導出
所有する各アプリに再利用"] D --> E["SINF privをアプリのワーク鍵へ展開"] E --> F["SUPFレコードからページ鍵を導出"] F --> G["arm64ページを復号しcryptidを消去"]

攻撃者に何ができますか?

認証情報を持つ攻撃者は、Apple Accountが所有する対応IPAをオフラインで繰り返し復号し、そのコードとリソースを読んだり再パッケージしたりできます。影響は機密性と再パッケージであり、リモートコード実行ではありません。

条件は影響の一部です。

  • アプリが認証情報のアカウントに所有され、その種類と一致している必要があります。READMEには、各認証情報は取得元のApple Accountのアプリで機能し、Arcadeアプリには別のArcade認証情報が必要とあります。
  • IPAに、対応するSINFとSUPFの組を持つ暗号化arm64スライスが含まれている必要があります。
  • 攻撃者にはIPAのコピーが必要です。
  • インストール用の再パッケージには署名IDが必要です。ツールは署名しません。
  • 復号はサーバー側の認証、ビジネスロジック、App Attestを回避しません。再パッケージされたアプリが貴社サーバーを呼ぶときも、これらの制御は実行されます。

復号されたIPAは、SwiftとObjective-Cのコード、文字列、組み込み設定、APIエンドポイント、バイナリに同梱された鍵やトークンを露出します。脆弱性調査を短縮し、再パッケージを容易にします。攻撃者はフレームワークを注入したりリソースを変更したりして、バンドルに再署名し、App Store外で配布できます。

2つ目の公開プロジェクトUnfairPlayは、ジェイルブレイク済みiPhoneではなく登録済みMacから再利用可能なモデルを復元します。READMEには、1つのモデルが同じ登録の他の個人化IPAを復号し、iOS IPAをmacOSレイアウトに変換できるとあります。これにより、ジェイルブレイク済み端末からMac App Storeアカウントへと障壁が下がります。プロジェクトは2026年10月25日に登場し、fairplay-decryptの最初のコミットから6日後でした。

fairplay-decryptの最初のコミットからUnfairPlayのmacOS経路まで6日
図1: iPhone向け復号ツールは2026年10月19日に公開され、macOS経路は2026年10月25日に登場しました。出典: fairplay-decryptのコミット履歴とUnfairPlayリポジトリ、2026年11月12日確認

UnfairPlayは、出力が入力のSC_InfoライセンスとiTunesMetadata.plistを保持し、これらがStoreアカウントを識別すると警告しています。これらは、運用者が明示的に削除しない限り残ります。不用意に共有された復号IPAは、コードだけでなくアカウントの身元も露出する可能性があります。

2026年11月12日、fairplay-decryptリポジトリは2,400以上のスターと375のフォークを持っていました。関心は悪用ではありません。プロジェクトにも確認した情報源にも、ツールを使った攻撃の報告はありません。

ツールは、分析を許可されたアプリにのみ使用してください。復号コマンドは入力を許可済みIPAと説明しています。

修正が機能する理由

引用できる修正版はないため、プロジェクト内で設計上の弱点を閉じるものはありません。修正には、解析関数1つではなく鍵階層の変更が必要です。次の3つの変更がコストを上げます。

  • アプリごとの鍵を、OSが読めないハードウェア秘密(Secure Enclaveなど)に結び付け、鍵を解放する前にOSをアテステーションする。
  • アカウント認証情報から導出するのではなく、デバイスとアカウントを確認するサーバーから、アプリとセッションごとの鍵を配信する。
  • 認証情報スキームをローテーションし、悪用を検出したときに取得済み認証情報を無効化する。

どれも1行のパッチではなく、どれもデバイスをある程度信頼します。ジェイルブレイク済みOSは、鍵がラップされていてもユーザー空間のデーモンを観察できます。今回、クライアント側DRMは、カーネルアクセスを持つデバイス所有者に対してコードを機密に保てませんでした。

プロジェクトはAppleの変更に追従しています。iOS 10から12の取得、16 KBページ対応、SUPFバージョン5、複数のarm64スライス、Apple Arcade認証情報を追加しました。fairplay-decryptにCVEは割り当てられておらず、アカウント認証情報への依存をなくすリリースもありません。

侵害されたかどうかを確認するには?

復号されたコピーは貴社サーバーに痕跡を残さないため、再パッケージされたビルドとアカウント認証情報の露出を確認します。配布ビルドごとに、次の手がかりを探します。

  • 暗号化されているはずのビルドでcryptidが0。
  • TeamIdentifierが自社と異なるコード署名。
  • 自社のリリースと異なるバンドルID、Info.plist、embedded.mobileprovision。
  • 注入されたフレームワークや追加のSC_Infoファイル。
  • App StoreまたはTestFlight外での配布。

メインバイナリを抽出して調べます。

unzip -p Suspicious.ipa Payload/App.app/App > /tmp/App
otool -l /tmp/App | grep -A4 LC_ENCRYPTION_INFO_64
codesign -dv --verbose=4 /tmp/App

平文バイナリと別チームの署名の組み合わせは有力な手がかりですが、復号の証拠ではありません。暗号化されていないバイナリは、コピーが復号された証拠になりません。

サーバー側では、App AttestとDeviceCheckの失敗、ジェイルブレイク端末のシグナル、予期しないバージョンや整合性ヘッダーを欠くAPIクライアントを確認します。これらも手がかりであり、証拠ではありません。プロジェクトは侵害の指標を公開していません。復号は外部に通信しないオフラインのファイル操作なので、失敗した試行は痕跡を残さないことがあります。

年表

  • 2026-10-19: EthanArbuckle/fairplay-decryptリポジトリが最初の公開コミットを受け取ります。
  • 2026-10-22: READMEがiOS 15対応を確認します。
  • 2026-10-23: iOS 10から12の認証情報取得を追加するコミットがあります。
  • 2026-10-25: macOSプロジェクトUnfairPlayが作成されます。
  • 2026-10-30: プロジェクトがGPLv3ライセンスとApple Arcade認証情報の取得を追加します。
  • 2026-11-08: 最新コミットがArcade取得をFairPlayのIOKit観察に置き換えます。

よくある質問

fairplay-decryptにCVEはありますか?

いいえ。プロジェクトは研究ツールであり、修正版を持つ製品の脆弱性ではありません。2026年11月12日時点でNVDにこのプロジェクトのFairPlayレコードはなく、CISA KEVカタログ2026.11.10にもFairPlayの項目はありません。

ジェイルブレイクは必要ですか?

fairplay-decryptでは、取得時に必要です。取得ツールはroot SSHを持つジェイルブレイク済みiPhoneを必要とします。復号自体は電話なしでmacOSまたはLinux上で動作します。別プロジェクトのUnfairPlayは、ジェイルブレイク済みiPhoneではなく登録済みMacを使います。

1つの認証情報ですべてのアプリを復号できますか?

認証情報のApple Accountが所有する対応IPAを復号します。通常の認証情報は通常のアプリを対象とし、READMEではArcadeアプリに別のArcade認証情報が必要とされています。他のアカウントのアプリやFairPlay Streamingの動画は復号しません。

出力はインストールできますか?

そのままではできません。ツールはcryptidを消去しますが、バイナリに再署名しません。iOSは有効な署名を要求するため、インストール前にプロビジョニングプロファイルで再署名する必要があります。

どのアプリとiOSバージョンが対象ですか?

取得ツールはiOS 10以降としています。復号器はarm64 Mach-Oスライス、SUPFバージョン3と5、440または448バイトのSINF privレコードをサポートします。32ビットのみのアプリや暗号化されていないバイナリは処理しません。

実際に悪用されていますか?

いいえ。2026年11月12日時点で、プロジェクトにも確認した情報源にも、ツールを使った攻撃の報告はありません。CISA KEVにもありません。スターとフォークの数は関心を示すもので、悪用ではありません。

参考資料

  • EthanArbuckle/fairplay-decryptリポジトリ、README、16バイト認証情報、対応形式、オフライン復号: https://github.com/EthanArbuckle/fairplay-decrypt/blob/main/README.md (2026年11月12日確認)
  • core.py、コミットd81d98b13656c9dbb340f04dd0838137278f44a5、SINF、SUPF、ページ鍵の導出: https://github.com/EthanArbuckle/fairplay-decrypt/blob/d81d98b13656c9dbb340f04dd0838137278f44a5/core.py (2026年11月12日確認)
  • decrypt.py、同じコミット、IPA入力と出力パス: https://github.com/EthanArbuckle/fairplay-decrypt/blob/d81d98b13656c9dbb340f04dd0838137278f44a5/decrypt.py (2026年11月12日確認)
  • credential-retrieval/README.md、ジェイルブレイク端末の要件、iOS 10以降、再利用可能なアカウント認証情報: https://github.com/EthanArbuckle/fairplay-decrypt/blob/main/credential-retrieval/README.md (2026年11月12日確認)
  • credential-retrieval/credential/observer.c、ハードウェアブレークポイントとFairPlayオブザーバー: https://github.com/EthanArbuckle/fairplay-decrypt/blob/main/credential-retrieval/credential/observer.c (2026年11月12日確認)
  • credential-retrieval/credential/credential.c、セレクター、keybag、認証情報の導出: https://github.com/EthanArbuckle/fairplay-decrypt/blob/main/credential-retrieval/credential/credential.c (2026年11月12日確認)
  • コミット5fdf16b48ea4a2a32950641aba23dd3063c34856、2026年10月19日の最初の公開コミット: https://github.com/EthanArbuckle/fairplay-decrypt/commit/5fdf16b48ea4a2a32950641aba23dd3063c34856 (2026年11月12日確認)
  • コミット9e5aa3ea290d79c3320190004dc512e034d99484、2026年10月30日のGPLv3ライセンス: https://github.com/EthanArbuckle/fairplay-decrypt/commit/9e5aa3ea290d79c3320190004dc512e034d99484 (2026年11月12日確認)
  • コミット8350383e2e9050f7a77197bf32545ddbef90b57c、2026年10月30日のApple Arcade認証情報取得: https://github.com/EthanArbuckle/fairplay-decrypt/commit/8350383e2e9050f7a77197bf32545ddbef90b57c (2026年11月12日確認)
  • コミット5e35c7a、2026年10月23日のiOS 10から12対応: https://github.com/EthanArbuckle/fairplay-decrypt/commit/5e35c7a (2026年11月12日確認)
  • EthanArbuckle/fairplay-decryptのコミット履歴、iOS 10から12、16 KBページ、SUPF v5、複数スライス、Arcadeの変更: https://github.com/EthanArbuckle/fairplay-decrypt/commits/main (2026年11月12日確認)
  • DrWhax/unfairplayリポジトリ、README、登録済みMac経路と再利用可能なモデル: https://github.com/DrWhax/unfairplay/blob/main/README.md (2026年11月12日確認)
  • DrWhax/unfairplayリポジトリページ、2026年10月25日作成: https://github.com/DrWhax/unfairplay (2026年11月12日確認)
  • vnc0/fairplay-scinfo、SINFとSUPFの形式、ラップされたページ鍵の文書: https://github.com/vnc0/fairplay-scinfo (2026年11月12日確認)
  • Apple、loader.h、LC_ENCRYPTION_INFO_64構造とcryptidフィールド: https://github.com/apple-oss-distributions/xnu/blob/main/EXTERNAL_HEADERS/mach-o/loader.h (2026年11月12日確認)
  • CISA、Known Exploited VulnerabilitiesカタログJSON、バージョン2026.11.10、FairPlayの項目なし: https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (2026年11月12日確認)
  • NVDのFairPlay検索、2026年11月12日時点でプロジェクトのレコードなし: https://nvd.nist.gov/vuln/search/results?query=fairplay&search_type=all (2026年11月12日確認)
  • EthanArbuckle/fairplay-decryptリポジトリページ、2026年11月12日時点で2,400以上のスターと375のフォーク: https://github.com/EthanArbuckle/fairplay-decrypt (2026年11月12日確認)