Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Arbitrary code execution in Unity Runtime

2025年10月03日に「Hacker News」が公開したITニュース「Arbitrary code execution in Unity Runtime」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

人気ゲーム開発環境Unityの実行環境で、外部から悪意のあるプログラムを勝手に動かされる可能性のある脆弱性が発見された。これにより、システムが乗っ取られる危険があるため、利用者は注意が必要だ。

ITニュース解説

システムエンジニアを目指す初心者の皆さん、ITニュースには時々、ソフトウェアの根幹を揺るがすような重要な脆弱性の情報が流れてくる。今回は、ゲーム開発で広く利用されている「Unity」というゲームエンジンで発見された、「任意コード実行」という非常に危険な脆弱性について解説する。

まず「任意コード実行」とは何かを理解しよう。これは、攻撃者が本来意図しない、悪意のあるプログラムのコードを、対象のシステム上で勝手に実行できてしまう状態を指す。もしこれが成功すれば、攻撃者はシステムを完全に制御下に置き、個人情報の窃取、ファイルの破壊、別のマルウェアのインストールなど、あらゆる悪事を働くことが可能になる。そのため、これは数ある脆弱性の中でも特に重大なものとされている。

今回の脆弱性は、Unityで開発されたゲームやアプリケーションが動作する「Unity Runtime」という実行環境に存在していた。Unityは、C#というプログラミング言語を使ってゲームのロジックを記述し、それを様々なプラットフォーム(PC、スマートフォン、ゲーム機など)で動かすことができる強力なツールだ。しかし、C#で書かれたコードが常に単独で動作しているわけではない。システムの一部の機能や、より高速な処理が必要な部分では、C++などの別の言語で書かれた「ネイティブコード」と呼ばれるプログラムと連携する必要がある。このC#とネイティブコード間の連携の仕組みに、今回の問題の根本原因があった。

C#からネイティブコードを呼び出す際には、「P/Invoke(Platform Invoke)」という仕組みが使われる。これは、C#のコードがDLLファイルや共有ライブラリといった外部のネイティブコードライブラリにある関数を呼び出すための機能だ。しかし、C#とC++ではデータの持ち方やメモリの管理方法が異なるため、このP/Invokeを使って関数を呼び出す際には、引数や戻り値のデータをそれぞれの言語の形式に合わせて変換する「マーシャリング」という処理が必要となる。

今回の脆弱性は、特にメモリ上の「ポインタ」という、データの場所を示すアドレスから文字列を読み取るためのマーシャリング関数、具体的には Marshal.PtrToStringAnsi などに起因していた。この関数は、C++側で確保されたメモリ領域にある文字列を、C#が扱える文字列形式に変換する役割を担っている。

問題は、Unityのランタイム環境におけるメモリ管理、特に「ガベージコレクション(GC)」と呼ばれる自動メモリ解放機能との組み合わせで発生した。ガベージコレクションは、プログラムが不要になったメモリ領域を自動的に検出し、解放することで、開発者がメモリ管理の手間から解放される非常に便利な機能だ。しかし、今回のケースでは、ある特定の条件下で、まだ使用中であるはずのメモリ領域がガベージコレクションによって誤って解放されてしまうという状況が生じた。これを「Use-After-Free(解放済みメモリ使用)」脆弱性と呼ぶ。

Use-After-Freeが発生すると、攻撃者は解放されたはずのメモリ領域を、自分たちが用意したデータで上書きすることが可能になる。そして、プログラムがその上書きされたメモリ領域を再び参照しようとした際に、攻撃者の意図するデータが読み込まれることになり、プログラムの予期せぬ動作やクラッシュを引き起こすことができる。

今回の攻撃では、このUse-After-Free脆弱性を利用して、メモリ上に存在する特定のオブジェクトの構造を巧妙に改変した。これにより、攻撃者は最終的に「任意のメモリを読み書きできる」という強力な能力、「R/W(Read/Write)プリミティブ」を手に入れた。R/Wプリミティブは、コンピューターのメモリ内のどんな場所でも自由にデータを読み取ったり書き込んだりできる能力を指す。これは、システムの心臓部を直接操作するようなもので、非常に危険な状態だ。

R/Wプリミティブを獲得した攻撃者は、さらに次の段階に進む。Unityランタイムでは、「JIT(Just-In-Time)コンパイラ」という技術が利用されている。これは、プログラムの実行中にリアルタイムでコードを機械語に変換し、実行を最適化する仕組みだ。攻撃者はR/Wプリミティブを使い、JITコンパイラが生成するコードの領域や、既存の重要な関数のアドレス(ポインタ)を書き換える。このようにして、本来実行されるべきプログラムの代わりに、攻撃者が用意した悪意のあるコードを強制的に実行させることが可能になるのだ。これが「任意コード実行」の最終的な達成となる。

この脆弱性の影響は非常に広範囲に及ぶ可能性がある。特に、WindowsやmacOSなどのPCプラットフォーム向けにUnityで開発されたスタンドアロンアプリケーションが主な標的となる。もし、脆弱性のあるバージョンのUnityで開発されたゲームやアプリをユーザーが実行した場合、攻撃者はそのゲームやアプリを悪用して、ユーザーのコンピュータ上で任意のコードを実行できてしまう。これにより、個人情報の窃取、システムの破壊、あるいはユーザーのコンピュータをゾンビ化させて他の攻撃に利用するといった、深刻な被害が発生する恐れがあった。

幸いなことに、Unityはこの脆弱性を認識しており、既に修正済みの新しいバージョンをリリースしている。具体的には、Unity 2022.2.0b16、2022.1.20f1、2021.3.10f1、2020.3.43f1などが修正版として公開されている。

開発者にとっては、速やかにUnityのバージョンを更新することが最も重要だ。また、セキュリティの観点から、Marshal.PtrToString系の関数を、ユーザーからの入力や信頼できないソースから得られたポインタに対して直接使用することは避けるべきである。ユーザーの皆さんにとっては、利用しているソフトウェアやゲームを常に最新の状態に保つことが、このような脆弱性から自身を守るための基本的な対策となる。

今回の事例は、プログラミング言語間の連携や、メモリ管理といったシステムの根幹に関わる部分に潜む脆弱性が、いかに重大な結果をもたらすかを改めて示している。システムエンジニアを目指す皆さんにとって、このような基礎的な部分の理解がいかに重要であるかを学ぶ良い機会となるだろう。

関連コンテンツ

関連IT用語