JSSEC セキュアコーディングデイ #3 |ゲームチート事例
JSSECのイベント「セキュアコーディングデイ」において「事例で学ぶセキュアコーディング」と題して講演をしました。今回はその講演内容紹介の3回目です。
事例で学ぶセキュアコーディング
3回目の今回は講演内容からゲームチートの事例を紹介します。
事例紹介
パラメータ改ざん
次はゲームチートに関連した事例です。ゲームチートにおいてパラメータ改ざんはとても一般的なチート手法です。事例で紹介するゲームはステージごとにミッションがあり、場合によっては友達と協力してクリアして進めていきます。また、課金してアイテムを取得することで更に優位にゲームを進めることができます。
このゲームでは以下の3つのチートが可能でした。
- スコアを改ざんできる
- ステージクリアを自在に操れる
- 課金せずにアイテムを使用できる
スコアを改ざんできる
例えば、ステージをクリアした場合等ゲームの状況によりスコアが変更されるイベントがあります。この時の流れを図にするとこのようになります。
ステージをクリアした時点でユーザの状態を含む情報がサーバに送信され、サーバ側では送信された情報を保存ができたかどうかをアプリに返す、このような流れになっていました。
サーバ側ではアプリから送信された情報を正規なものとしてチェックするわけでもなく信じてそのまま保存しています。よって、この送信されるリクエストを改ざんすることで、スコアを改ざんできるわけです。
ステージクリアを自在に操れる
ステージクリアを自在に操れるとはどういうことでしょうか。このゲームではステージを選択しそこのミッションを達成することで次のステップへ進むことができます。これを繰り返すことでゲームが進行していくわけですが、ステージには難易度があります。容易にクリアできるステージと困難なステージがあります。このチートでは容易にクリアできるステージを使用することで、クリアが困難なステージを容易にクリアすることができるというものです。
その仕組は次のようなものです。ゲームを開始した際に選択したステージ情報がサーバに送信されます。サーバ側ではそのステージが存在しているかどうかを確認し、存在の有無をアプリに返します。アプリでは存在していればゲームが開始されます。
そこで、容易にクリアできるステージを選択しゲームを開始しようとします。この時サーバに送信されるステージ情報を、クリアが困難なステージの情報に改ざんしてサーバに送信します。サーバ側ではそのステージの有無を確認しているだけなので、問題なくゲームが開始されます。
サーバ側ではクリアが困難なステージでゲームが開始されたと認識されています。しかし、アプリ側では容易にクリアできるステージを選択していることになっており、容易にクリアできるステージでゲームが開始されてしまいました。また、ステージ終了時にはステージ情報はサーバに送信されない仕様のため、アプリ側とサーバ側で異なったステージ情報のまま進行します。結果、クリアしたという情報は送信されるため、クリアが容易なステージを使用することで、クリアが困難なステージをクリアできてしまいました。
課金せずにアイテムを使用できる
このゲームにおけるアイテム使用時の処理の流れを図にしたものです。
アイテムを使用する際に、使用するアイテムの情報とその数をサーバに送信します。サーバではユーザがそのアイテムを所有しているか、数は足りているかをチェックしその結果をアプリに返します。アプリではそのサーバのチェックで問題がなければアイテムを使用するという流れになっています。
ここで問題だったのは、サーバから返される結果の部分です。サーバ側のチェックで問題がなければOKあればNGといったような結果が返されます。このレスポンスを改ざんし、もしNGでもOKとアプリに返せばアイテムを自由に使用することが可能だったわけです。
改ざんチェックのバイパス
先ほどのパラメータ改ざんの例では、改ざんチェックの機能が実装されていないということもあり改ざんが容易でした。では改ざんチェックを実装すればよいのではないかということにつながります。そこで、改ざんチェックのバイパスという事例があります。
サーバに送信されるリクエストにハッシュを追加して、それをチェックすることでパラメータ改ざんをチェックするという仕組みを実装していたゲームがありました。
しかし、このハッシュですがサーバに送信する際のpathと送信する内容とIDを連結して生成していました。アプリ内にこの生成ロジックについてのヒントがあり容易に判明してしまったわけです。
root化検知のバイパス
また、アプリによってはroot化された端末では起動しないようにするために、それを検知する仕組みを導入することがあります。しかし、CheckRootedやisRooted等わかりやすいクラス名やメソッド名で実装されているということが少なからずあります。何かしらの理由で検知する仕組みを導入したのに、これでは容易にバイパスされてしまう恐れがあります。
addJavascriptInterface
JavascriptからJavaのメソッドを呼び出すための機能がありそれを実現するために使用するのがaddJavascriptInterfaceです。これを起因とした脆弱性は数年前に話題になりました。最近のAPIでは制限が加えられきちんと実装することで問題は起きなくなりました。しかし、脆弱性診断の現場ではいまだに多くのアプリでこの脆弱性が見つかっています。
まとめ
脆弱性診断の現場からみた現状ということで以上の内容を紹介しました。現場ではSSL/TLSサーバ証明書検証不備やaddJavascriptInterfaceといった今更感のある脆弱性がいまだに多くのアプリで見つかっています。
JSSECのセキュアコーディングガイドにおいてもこれら脆弱性を作りこまないためのサンプルコードが多数掲載されています。今回紹介した事例と合わせてセキュアコーディングガイドも参考にしセキュアなアプリを作成することを心がけていただければと思います。