ゲーム、特にソシャゲ、ネトゲにおいて様々なハッキング(チート)が実際に行われます。
大きく分類すると、アプリケーションハッキング(クライアントサイドでのハッキング)とネットーワークハッキング(サーバーへのハッキング)とその他のハッキングがあります。
多くはエンジニアがよくやらかすバグであったり、知識(経験)不足を狙ってくるものです。
今回は内容のボリュームの関係上、アプリケーションハッキングについてのみ、実際によく行われるチート行為やその方法、対策などについて中心に挙げていきたいと思います。
ボタン連打
何が起こる?
コスト(課金石など)を払うことなく無限にアイテムが増殖する。
やり方
対策
- データベースの排他制御(トランザクション + ロック)を行う。
- 連打ができないように一度ボタンを押したら処理が完了するまで押せないようにする。
具体例・解説
1.について、具体的な対策例として、以下にMySQLで実行可能なSQLを記述します。
トランザクション
/* トランザクション */
BEGIN
/* INSERT文 または UPDATE文 または DELETE文 などの更新系SQLを記述 */
...
/* 更新したデータを反映してトランザクションを終了したい場合はCOMMIT トランザクションスタート前の状態に戻したい場合はROLLBACK*/
COMMIT
/* または */
ROLLBACK
悲観的ロック
/* トランザクション + 悲観的ロック */
BEGIN
SELECT ... FOR UPDATE
/* INSERT文 または UPDATE文 または DELETE文 などの更新系SQLを記述 */
...
COMMIT
/* または */
ROLLBACK
楽観的ロックなどそのほかのSQLについての詳細についてはこちらを参照
被害例(参考)
上記の他にも最近のゲームにおいて、多数の発生ケースが多くあります。
デコンパイル(逆コンパイル)
デコンパイルとは?
逆コンパイルとも言います。
アプリの実行ファイルからソースコードの形式に戻すことを「デコンパイル」といいます。デコンパイルすることでサーバーにアクセスしているパスワード、秘密鍵の情報や暗号化されているものを解除するためのアルゴリズムなどがわかってしまいます。
やり方
プラットフォーム | 説明 |
---|---|
ブラウザ | ブラウザのデベロッパーツールを開く。取得できたjavascriptはクライアントで実行されているソースコードになります |
Android | dex2jarやjadやというツールを用いることでデコンパイルすることが可能です。詳しくはこちら。AndroidのAPKを逆コンパイルする |
iOS | 具体的なやり方などはこちらを参照。iOS Reverse Engineeringの操作手順 |
対策
- 重要な値はサーバーにのみ保持し、ネットワークを用いてデータを取得する。その上でデータの更新はサーバー上でのみ行うようにする。
- C/C++を使ったネイティブコードで処理を書く。
具体例・解説
1.の具体例として、ガチャを行う処理を実装する場合、サーバー側で抽選を行い、抽選の結果のみをクライアント(端末)に送るようにする。ガチャ抽選の実装内容をシーケンス図に表すと以下のようになる。
2.の具体例としてAndroid NDK, iOS(Objective-C++), UnityIL2CPP などそれぞれ対応したプラットフォームでビルドするようにする。
2.の詳しい解説として、C/C++で記述されたコードをコンパイルすると機械語に変換されます。これを逆コンパイルしても、逆アセンブラまでにしかなりません。そのため、この状態ではソースコードの中身を解析するのは(人間では)非常に困難なため、ネイティブコードで書いた処理というのはデコンパイルへの対策となります。
参考
- Web開発でよく使う、特に使えるChromeデベロッパー・ツールの機能
- Objective-C++ 取扱説明書 〜始め方から使い方、注意点まで〜【完全保存版】
- Cの逆コンパイラはどこまで実現可能か,Javaはなぜ逆コンパイルされやすいのか?
メモリ改ざん
何ができる?
アプリ実行時にメモリ値を可視化し、そのメモリ値を変更することができます。これにより、明らかにおかしい値にしてゲームバランスを崩壊させてしまったり、そのデータをそのまま端末内に保存させたりすることでゲームを破壊したり、メモリ値からサーバーとの認証鍵を解析、取得することでサーバーへのハッキングが可能となる、といったことができるようになります。
やり方
Android、iOSでメモリを改ざんできるツール(ソフト)はいくつかあります。「iOS memory hack」や「Android memory hack」で検索すると紹介動画やツール紹介サイトがいくつか出てきます。以下、サイトの一例を紹介します。
- Top 8 Game Hacker Apps for Android with/without Root
- Top 14 Best Game Hack Apps / Tools for Android With and Without Root
- Jailbreak
など
対策
具体例や解説
1.の例として、サーバー側でガチャの抽選を行い、抽選結果のみをサーバーから受け取るように実装する。
2.の解説として、チェックサムやMD5 ハッシュ値というものは値がわずかに変更されれば値が変更されてしまうものです。変数の参照先が変わった場合も値が変化するため、チェックサムやMD5 ハッシュ値を監視することでメモリ値が変更されれば検知することができます。
しかし、厳しく対応しようとすれば、対応箇所が膨大となり、対応コストが高くなります。また、対応することでパフォーマンスが犠牲になる可能性もあります。メモリ改ざんを行ったからといって、サーバー上のデータが書き換わるわけではないので、ケースバイケースで対応することをおすすめします。
Log検知
アプリを起動した時に出力されるアプリ専用のLogを検出することがLog検出です。
何ができる?
処理の中身を解析するヒントを与えてしまいます。これ自体で何かをハッキングするということはないのですが、ハッキングするための方針、ヒントを与えることになります。
やり方
ケース | ツール | 参考 |
---|---|---|
ブラウザ | デベロッパーツール | Web開発でよく使う、特に使えるChromeデベロッパー・ツールの機能 |
Android | Android Studio->Logcat | Android Studio の logcat を快適にする |
iOS | Xcode他 | iPhoneの実機ログを確認する方法 |
対策
- Logを全て消す
- Buildする時に環境を切り分けるようにし、それぞれの環境において出力するLogレベルを切り替えるようにする
- エラーなど、ログとして検知したいものは直接出力はせず、違う表現にして出力したり、一部だけ出力する。
具体例や解説
2.の具体例としてDebugビルドやReleaseビルドといったビルドの環境を分け、logレベルがDebugのものはReleaaseビルドでは出力されない、といった設定、ルールを儲ける。(各プラットフォームの開発環境の中にはそのような、制御ができるような仕組みがあるはずです)
3.の解説として、検知したエラーや文言はサーバーに送ったり、サーバーでログとして記録するが、ユーザーが検知できる形としては表示せず、以下のような共通の文言として出力(表示)する。これにより詳しいことは開発側は検知し対応でき、またユーザーには何か問題が起きたことがそれとなく伝えることができるので、お互いの住み分けができる。
参考
脱獄(root化)
脱獄とは?
root権限を取得することを脱獄といいます。
root権限を取得することですべての操作が可能になります。
端末の中のデータを全て消すといった、本来なら操作ができないように制限されているようなこともできるようになります。
また、脱獄することでアプリ内に用意された、アクセスが制限されているような領域にもアクセスすることができてしまうため、この領域に保存されている秘密鍵やアカウント情報といった特有の情報も見ることができるようになります。
全ての情報を見ることができるので、情報次第ではハッキングできなかったものが可能になったり、といったハッキングへの足がかりとすることが可能になります。
また、Android(Linux)ではroot化、iOSでは脱獄と呼ぶのが一般的です。
やり方
プラットフォーム | ツール例 | 参考 |
---|---|---|
Android | Androidをroot化/脱獄するアプリの紹介 他 | ツール例と同じく Androidをroot化/脱獄するアプリの紹介 他 |
iOS | PP Jailbreak 他 | 【完全版】iOS 11脱獄可能なのか?iOS 11 Jailbreak攻略~iOS 11脱獄方法とツールを一挙ご紹介 |
なお、脱獄すると端末の保証対象外となったり、端末の挙動が不安定になったり、端末が起動しなくなるなど、大きなリスクがあります。脱獄する場合はこれらのリスクを十分理解し、端末を一台、破壊するつもりで行ってください。
対策
- アプリ内で脱獄したかどうかを検知可能なため、脱獄していたら処理を変えるように実装する。
- データを暗号化して保存する。
具体例や解説
1.の実装方法を以下にあげます。
- Androidの場合、SafetyNet APIやrootbeerライブラリを用いることで脱獄しているかどうか確認することができる。
- iOSの場合、iOS脱獄チェックメモやSwiftでiOS脱獄チェックを参考にチェック処理を作成して確認することができます。
2.の解説としてAES暗号などの共通鍵暗号の処理を施して、データを人間が見てもわからないように加工する。(データの暗号化に関しては改めて別の機会にまとめます)
参考
- Root化とは
- SafetyNet Attestation API
- SafetyNet attestation: 不正利用対策の構成要素
- アプリのroot化端末チェック(SafetyNet)を回避する方法まとめ
乱数調整
乱数調整とは?
乱数の特性を掴み、狙ったものを出せるようにすることです。
本来「乱数」とは、「全く規則性が無く予測がつかない数字の並び」と言う意味ですが、必ず書いた通りに動くというプログラムの宿命上そのようなものをプログラムだけで仮想することは出来ません。
そのため、不規則な数が出現するような数式であったり、何らかの方法で作成した乱数の羅列の一部を移植する事で「擬似乱数」を生成して用います。この乱数を生成する特性をつかみ、操作することで調整する(狙ったものを出す)ことが可能になります。
乱数の生成方法
乱数生成によく使われるアルゴリズムとしては線形合同法やメルセンヌツイスタがあります。乱数生成時、どのアルゴリズムが標準で使われるかどうかは開発言語ごとに異なります。
なお、乱数を生成する際、現在時刻を基にして、擬似乱数を生成することが多いので、特定のタイミング(時刻)を狙うとうまくいく、といった都市伝説みたいな論調はあながち間違っているわけではありません。
対策
乱数を生成するとき、「真の乱数」を用いる。
具体例や解説
「真の乱数」とは自然界の中で生じてしまう(物理的な)誤差やノイズのことをいいます。具体的には通信時間やセンサーの検出した生のデータ(誤り検出訂正していない値)などを乱数生成時に用いることです。
最も簡単な実装方法としては抽選処理は全てサーバーで行い、抽選結果のみ取得することで乱数を調整することが困難にすることができます。
被害例
この他、クライアントで乱数を用いた抽選処理を行っているゲームでは乱数調整を行ったというケースに度々存在します。
参考
- 乱数調整とは (ランスウチョウセイとは) [単語記事] - ニコニコ大百科
- 乱数調整とは - はてなキーワード
- サイコロを振るのは簡単である、しかし、ゲームでサイコロを実装するにはサイコロを知らなければならない
- 乱数調整 入門
次回予告
以上がよく行われる有名なアプリケーションハッキングになります。(まだ他にもあるかもしれませんが)
次回はネットワークハッキングについてご紹介します。