2023年時点で世界中で1億8500万本を売り上げる人気ゲームソフト「グランド・セフト・オートV」では、オンラインマルチプレイヤーモードの「GTAオンライン」をプレイすることが可能です。そんなGTAオンラインには、ユーザー間で専用サーバーの構築や接続が可能になるオープンソースのコミュニティサーバープラットフォーム「FiveM」が存在します。エンジニアのベリタス氏が、FiveMの脆弱(ぜいじゃく)性によって、別のユーザーのマイクへのアクセスが可能になるなどの危険性を報告しています。

Hacking GTA V RP Servers Using Web Exploitation Techniques

https://www.nullpt.rs/hacking-gta-servers-using-web-exploitation



グランド・セフト・オートVなどのゲームで非公式MODの開発などを行う「Cfx.re」が提供するプラットフォームのFiveMを利用すると、通常のゲームプレイでは不可能なゲームモードやマップ、ロールプレイを可能にするサーバーを独自に立てることができます。ゲーム内データの変更には「リソース」と呼ばれるLuaやC#、JavaScriptといったプログラミング言語を用いてセットアップが作成されます。

FiveMを開くと、名前は地域、プレイヤー数などのさまざまな基準でサーバーのフィルタリングが行えるほか、サーバーに適用中のリソースのリストなどを表示することも可能です。



ベリタス氏は「rcore_radiocar」というリソースを適用したサーバーに着目。「rcore_radiocar」は、各プレイヤーがYouTubeやSoundCloudのリンクを指定することで、近くのプレイヤーに音楽をブロードキャストできるようになるというリソースです。

「rcore_radiocar」内には、「SoundPlayer.js」というファイルが存在することが確認されました。

rcore_radiocar
└── html
├── css
│ ├── reset.css
│ └── style.css
├── index.html
└── scripts
├── SoundPlayer.js
├── class.js
├── functions.js
├── listener.js
└── vue.min.js

ベリタス氏によると、SoundPlayer.jsの詳細を確認するとクライアント側で音楽がどのように再生されるかの機能が明らかになるとのこと。実際にSoundPlayer.jsは「create()」関数で処理されていることが判明しました。

SoundPlayer.jsでは、ユーザーが指定したURLからYouTube動画のIDを抽出します。IDが抽出できない場合は、不明なソースとして扱われ、オーディオライブラリ「Howler.js」を用いてオーディオの解析や再生が行われます。

create()
{
// ...
var link = getYoutubeUrlId(this.getUrlSound());
if(link === "")
{
this.isYoutube = false;

this.audioPlayer = new Howl({
src: [this.getUrlSound()],
loop: false,
html5: true,
autoplay: false,
volume: 0.0,
format: ['mp3'],
onend: function(event){
ended(null);
},
onplay: function(){
isReady("nothing", true);
},
});
$("#" + this.div_id).remove();
$("body").append("<div id = '"+ this.div_id +"' style='display:none'>"+this.getUrlSound() +"</div>")
}
else
{
// ...
}
}

しかし、この方法はクロスサイトスクリプティング(XSS)に対して脆弱とのこと。ベリタス氏は「この方法では、ユーザーが任意のURLを指定できるため、悪意を持った攻撃者がXSSのURLを作成、指定するとサーバー内の別のプレイヤーのマシンで任意のJavaScriptを実行することができます」と指摘しています。

ベリタス氏が行ったデモ映像が以下。ベリタス氏がYouTube上の動画のリンクを指定すると、別のプレイヤーにも音楽が聞こえる通常の動作と同時に、音楽が聞こえたユーザーのIPアドレスが盗み出されています。

また、FiveMの脆弱性を用いることで、ユーザーのクリップボードを読み取り、別のデータを書き込むことなども可能です。なお、ベリタス氏によると、2023年5月27日時点でクリップボード機能へのアクセスが禁止されたとのこと。

さらに、ゲームサーバー上の「chat/html/App.js」には、ゲーム内メッセージがどのように処理されるかが分かる以下のようなリソースが含まれています。

// window.post defined in chat/html/index.html
window.post = (url, data) => {
var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
request.send(data);
}

send(e) {
if(this.message !== '') {
post('http://chat/chatResult', JSON.stringify({
message: this.message,
}));
} else {
this.hideInput(true);
}
}

このリソースを悪用すると、別のユーザーに対して特定のメッセージを送信させることが可能になります。以下の画像ではベリタス氏のコードによって、複数のユーザーが「test」というメッセージを送信しています。



また、「gksphone」というリソースを悪用すると、ゲーム内の携帯電話機能を用いて別のユーザーが許可しているマイクへのアクセスが可能になります。

window.gksPhone = top.citFrames['gksphone'];

window.reqMicrophoneScript = top.document.createElement('script');
window.reqMicrophoneScript.innerHTML = `
function requestMicrophone() {
return navigator.mediaDevices.getUserMedia({ audio: true })
.then((stream) => {
// ...
})
}
requestMicrophone();
`

// inject the function into the gksphone resource
// which already has microphone access :)
window.gksPhone.contentWindow.document.body.appendChild(window.reqMicrophoneScript);

さらに、リソースの悪用によって、別のプレイヤーからゲーム内通貨を盗んだり、アバターの姿を強制的に変更したりすることが可能とのことです。

ベリタス氏は「FiveMには簡単なスクリプトを悪用することで、数百のサーバーに存在する数千人ものプレイヤーに被害を与える可能性のある脆弱なリソースが含まれています」と警告。また「悪用を防ぐために不適切な文字入力を禁止する仕組みや、システムの構築が必要です。また、サーバーのオーナーは定期的にインストールされているリソースを最新版にアップデートすることが重要です」と述べています。