※ 本記事は Unity と開示タイミングを調整し公開された英語版の第一報記事の翻訳版です。
はじめに
こんにちは、GMO Flatt Security株式会社でセキュリティエンジニアをしている RyotaK(@ryotkak)です。
本記事では、2025年5月に開催された Meta Bug Bounty Researcher Conference 2025 に参加した際に発見した、 Unity 2017.1 以降でビルドされたゲームやアプリに存在する脆弱性(CVE-2025-59489)の技術的な内容と影響について説明します。
本脆弱性は責任ある開示の方針に従って Unity に報告を実施しました。Unity はバージョン 2019.1 以降向けの修正をリリースし、問題対応のための Unity Binary Patch ツールも提供しています。該当するゲームやアプリについて、問題が修正されたUnityバージョンで再コンパイルしたバイナリを配信することを強く推奨いたします。
公式のセキュリティアドバイザリについては Unity のサイトをご参照ください:
また、この場を借りて、報告から修正まで一貫して行われた Unity の迅速な対応に感謝申し上げます。
セキュリティ上の脆弱性はソフトウェア開発において常についてまわる課題ですが、コミュニティとして一丸となって協力することで、世の中のソフトウェアをより安全に、堅牢なものにすることができます。
また、GMO Flatt Securityはゲームのチート対策を含む脆弱性診断・ペネトレーションテストを幅広く提供しています。ご興味のある方はお気軽にお問い合わせください。
要約
Unity ランタイムのインテント処理に脆弱性があり、プラットフォームによっては任意の共有ライブラリ(.so
など)を読み込ませて悪意あるコードを実行することが可能となっていました。
Androidにおいては、同一端末にインストールされた悪意あるアプリが攻撃対象の Unity アプリに付与された権限を乗っ取ることがデフォルトの設定で可能でした。
さらに特定の条件下ではリモートから任意コード実行に至る可能性もありますが、そのための条件を満たす Unity 製アプリを探すための網羅的な調査は実施していません。
Unity は、2019.1 以降の影響を受けるバージョンについて修正バージョンをリリースしました。Unity を利用されている開発者の方は Unity のリリースページから最新版をダウンロードし、プロジェクトを再ビルドして配布中のバイナリを差し替えてください。
Unity について
Unity はモバイルを含む複数プラットフォーム向けの人気のゲームエンジンです。
Unity の発表によれば、Among Us や Pokémon GO といった有名タイトルを含む、上位のモバイルゲームの約70%が Unity で開発されています。
技術的詳細
注: 本セクションで実施した分析は Android Studio の Android Emulator 上の Android 16.0 を使用して行いました。古い Android バージョンや他のプラットフォームにおいては挙動や影響が異なる可能性があります。
Unity のインテントハンドラ
Android デバイス上での Unity アプリに対するデバッグを容易にするため、Unity は unity
という Extra を含む Intent に対するハンドラを UnityPlayerActivity
に自動で追加します。UnityPlayerActivity
はアプリのデフォルトエントリポイントとしてエクスポートされ、他のアプリから呼び出すことができます。
adb shell am start -n "com.Company.MyGame/com.unity3d.player.UnityPlayerActivity" -e unity "-systemallocator"
上記のとおり、unity
Extra は Unity のコマンドライン引数としてパースされます。
Android の権限モデルは個別のアプリに対する機能アクセスを許可制で管理していますが、デフォルトではインテントの送信をする際に明示的な許可は必要ありません。
つまり、任意のアプリが Unity アプリに対して unity
Extraを送信でき、攻撃者がそのアプリに渡されるコマンドライン引数を制御できてしまいます。
xrsdk-pre-init-library
コマンドライン引数
Unity ランタイムのバイナリを Ghidra で解析したところ、以下のようなコマンドライン引数の処理が見つかりました:
initLibPath = FUN_00272540(uVar5, "xrsdk-pre-init-library");
この値は後で dlopen
に渡されるため、xrsdk-pre-init-library
というコマンドライン引数で指定されたパスがネイティブライブラリとしてロードされます。
lVar2 = dlopen(initLibPath, 2);
この挙動により、攻撃者は -xrsdk-pre-init-library
引数に任意のライブラリを指定して Unity アプリのコンテキスト内で任意のコードを実行し、そのアプリに付与された権限を悪用できます。
攻撃シナリオ
ローカル攻撃
同一デバイスにインストールされた任意の悪意あるアプリは、以下の手順で本脆弱性を悪用できます:
AndroidManifest.xml
のandroid:extractNativeLibs
属性がtrue
に設定されたネイティブライブラリを展開する。- Unity アプリを
-xrsdk-pre-init-library
引数を指定して起動し、その値を悪意あるライブラリのパスに向ける。 - Unity アプリ側でそのライブラリがロードされ、アプリの権限で悪意あるコードが実行される。
ブラウザ経由でのRCE
理論上、特定の条件下ではリモートからの悪用も可能です。
たとえば、アプリが UnityPlayerActivity
または UnityPlayerGameActivity
を android.intent.category.BROWSABLE
カテゴリ付きでエクスポートしている(ブラウザから起動可能にしている)場合、Webサイトは intent:
URL を使って Activity に渡す Extra を指定できます:
intent:#Intent;package=com.example.unitygame;scheme=custom-scheme;S.unity=-xrsdk-pre-init-library%20/data/local/tmp/malicious.so;end;
一見すると悪意あるサイトがブラウザ経由で .so
をダウンロードさせ、それを xrsdk-pre-init-library
引数で読み込ませることで攻撃が成立しそうに見えます。
SELinux による制限
しかしながら、 Android の厳格な SELinux ポリシーにより、ダウンロードディレクトリ内のファイルを dlopen
で読み込むことが禁止されているため、ブラウザを経由したリモートから攻撃するシナリオの影響は軽減されます。
library "/sdcard/Download/libtest.so" ("/storage/emulated/0/Download/libtest.so") needed or dlopened by "/data/app/~~24UwD8jnw7asNjRwx1MOBg==/com.DefaultCompany.com.unity.template. mobile2D-E043IptGJDwcTqq56BocIA==/lib/arm64/libunity.so" is not accessible for the namespace: [name="clns-9", ld_library_paths="",default_library_paths="/data/app/~~24UwD8jnw7asNjRwx1MOBg==/com.DefaultCompany.com.unity.template. mobile2D-E043IptGJDwcTqq56BocIA==/lib/arm64:/data/app/~~24UwD8jnw7asNjRwx1MOBg==/com.DefaultCompany.com.unity.template.mobile2D-E043IptGJDwcTqq56BocIA==/base.apk!/lib/arm64-v8a", permitted_paths="/data:/mnt/expand:/data/data/com.DefaultCompany.com.unity.template.mobile2D"]
ただし、 /data/
ディレクトリが permitted_paths
に含まれているため、攻撃対象のアプリが自身のプライベートストレージ(/data/data/
など)にファイルを書き込める場合はこの制限を回避できます。
さらに dlopen
は必ずしも .so
拡張子を要求しないため、攻撃者がアプリのプライベートストレージ内のファイル内容を制御できれば、悪意あるネイティブライブラリを含むファイルを作成して本脆弱性を突くことが可能です。
これはアプリがキャッシュ等で外部からのデータを保存するパターンでよく見られます。
例として、Messenger ではアプリのキャッシュを利用した攻撃が実際に行われた事例があります。詳しくは以下を参照してください:
リモートからの攻撃が成立する条件
リモートから本脆弱性を悪用するためには、以下のような条件を満たしている必要があります:
- アプリが
UnityPlayerActivity
またはUnityPlayerGameActivity
をandroid.intent.category.BROWSABLE
カテゴリ付きでエクスポートしていること(ブラウザからの起動を許可していること) - アプリが、プライベートストレージに対して攻撃者が制御する内容を書き込むこと(キャッシュ等)
なお、これらの条件を満たさなくても、ローカルからの攻撃はどの Unity アプリでも可能となる点にご注意ください。
デモ
まとめ
本記事では、数多くの Unity アプリに影響する可能性がある Unity ランタイムの任意コード実行の脆弱性について解説しました。
フレームワークやライブラリにも脆弱性は存在し得ること、そして利用する機能のセキュリティ面に常に配慮する必要があることを理解する一助になれば幸いです。
お知らせ
GMO Flatt Securityは脆弱性診断・ペネトレーションテストに特化したサイバーセキュリティ企業です。
アプリケーションのロジックにも着目し高度な検査を提供することができ、特にゲームのチート対策に関する高度な対策も可能です。ご興味のある方は、ぜひお問い合わせください。
また、AIエージェント「Takumi」であれば開発に伴走する形で脆弱性を自動で検知し、DevSecOpsを実現することが可能です。
最新情報は公式Xでご確認ください。
それでは、ここまでお読みいただきありがとうございました。