早速星野君はプロキシツールを介した状態でFlashゲームを始めてみた。
星野君 「あ……。これ、ひどい作りになってる……」
星野君が作ったFlashゲームは、実際には下図のような構成になっている。
始めにキャラクターデータをWebサーバ側から読み込む。次に、戦闘を行うときにはWebサーバから敵データを読み込み、そのデータを基にFlash側で戦闘を行う。戦闘が終わると、戦闘データをWebサーバに格納する。
このとき、データをやりとりする間に書き換えができるとしたらどうだろう。Webサーバ側からデータを読み込むときに、Webサーバからの応答を書き換え、自分のキャラクターデータを能力の高いものに変更し、逆に敵のデータを弱いものにするということが容易にできてしまう。また、Webサーバに戦闘結果を格納するときには、獲得できる経験値を自由に書き換えることができるし、さらには戦闘をまったく行わなくても、このリクエストを再送するだけで何度も戦闘をこなしたことにできてしまう。
加えて、複数のゲーム間でこのCGIを使い回せるような仕様を取っていたため、データの読み込み、書き込みの際に使用するファイルをFlashからの入力に頼る作りになっていた。このところ、Webアプリケーションの検査をいくつかこなしてきた星野君は、この作りが実はとても危険なものだということに気付いてしまった。
星野君 「(これはすぐ直さないとやばい……)」
このゲームにおいて、Flash側からは以下のようなURLにアクセスすることで、データの読み込み、書き込みを行わせていた。
http://www.example.com/cgi-bin/game.cgi?filename=game9/enemy.dat&player=har…… |
これは非常に危険な作りで、ディレクトリトラバーサルという攻撃手法に対して脆弱になってしまう。例えば、filenameの部分を以下のように書き換えることで、サーバ上の「/etc/passwd」ファイルを読み込むことができてしまうのだ。
http://www.example.com/cgi-bin/game.cgi?filename=../../../../etc/passwd |
星野君 「(ファイル名はCGIの内部で管理するように変えないとダメだな……)」
対策としては非常に簡単で、ファイル名を直接指定させないようにすればよい。まず、サーバ側Webアプリケーション内部で静的にファイル名を指定しておく。そして、ユーザーからの入力データはファイル名とは関係のないものにし、Webアプリケーション内部にて入力に応じて読み込むファイルを指定する。
しかし、これでディレクトリトラバーサルの対策はできたものの、星野君にはFlashとサーバ側Webアプリケーションとの間でゲームデータを安全に送受信する方法がまったく思い当たらなかった。つまりこれだけでは、プレーヤーの能力値を不正に操作できる状態のままになっているのだ。
星野君 「明日会社でまこと先輩に聞いてみようかな……」
致命的な部分の改修はひとまず完了したので、星野君は不正なデータの削除をした後、ひとまずクロとシロと戯れることにした。
Copyright © ITmedia, Inc. All Rights Reserved.