ZennへUnityのモバイルゲーム向けクラッキングが行われるポイントを整理してみたを移管しました。
今後このページは更新されません。
免責事項
この記事に記載されている内容を、実際に試して発生した損害に対していかなる責任も負いません。(補償しません)
すべて自己責任のもとで行ってください。
リリースされているアプリやゲーム、ソフトウェア利用許諾契約(EULA)やアプリケーション利用規約などでリバースエンジニアリングは禁止されています。
実際に試す場合は、自分で開発しているアプリやゲームや脆弱性確認用でリリースされているアプリやゲームを使いましょう。
勘違いして理解しており、誤ったことを記載しているところもあるかもしれません。
実際に対策を行うときは、専門家に相談してください。
はじめに
目的
「Unityのモバイルゲーム向けセキュリティ関連覚書 - Qiita」の資料を全部読むのは大変です。 1
理解が進みやすいように、クラッキングが行われる目的、ポイント、対策を整理してみました。
なるべく一般的な名称を使っているつもりです。長くなるため細かく解説をつけていません。
必要に応じて、覚書で調べるか、ググっていただけると助かります。(各種対応方法の詳細も覚書を確認してください)
ここ間違っている、ここもう少し詳しくなどコメントもらえると助かります。
対応方法
この後に出てくる対応方法は、書かれている対応を行えば絶対に安全というものではありません。
基本、無限のコスト(人と時間)をかけられる攻撃者の方が有利です。
どこまで対応する必要があるかは、守りたい情報やアセットの重要度と、実装(対応)コストを、勘案する必要があります。
暗号化
エンコーディング(base64など)は、暗号化ではありません。
暗号化は、System.Security.CryptographyなどでAESやRAS使用したもののことを指しています。
暗号化にも強度があります。現在のPCでは暗号強度が弱いものだと解析されてしまいます。
適切な暗号強度のアルゴリズムと暗号化キーをを設定する必要があります。
(ハッシュアルゴリズムにも強度があります。適切なアルゴリズムを選択する必要があります。)
その他
Unityのモバイルゲームと銘打っていますが。
「WindowsやmacOSのPC環境」、「AndroidやiOS環境ネイティブアプリやゲーム」、「PlayStation 4、Xbox One、Switchなどコンソール機」、「Webサービスやゲーム」でもクラッキングのターゲットになり対策が必要です。
クラッキングの目的
私見になりますが。 2
ゲームをクラッキングする目的としては、「人より有利に進めたい」、「技術的興味」、「営利目的」などが考えられます。
- 人より有利に進めたいは、「他の人に(お金を使わないで)簡単勝ちたい」、「時間短縮」、「欲しいユニットやアイテムを簡単に手に入れたい」などが考えられます。有利とは別に、元画像、3Dモデル、音楽データが欲しいなども考えられます。
- 技術的興味は、対処のゲームがどのような構造で作られているか、セキュリティーを破りたいなど自分の欲求を満たすため。また、技術力を見せるためにクラッキングの方法やツールを公開することもあります。3
- 営利目的は、「人より有利に進めたい」人でクラッキング能力がない人向けに、簡単に使えるクラッキングツール、改造済みのゲームアプリ、アカウントを提供して利益をえる。また、サービスを攻撃して停止に追い込み要求をだしたり。ユーザーデータなど価値あるものを手に入れて販売したりすることが考えられます。
対策が必要な条件は、上記の目的を持つ人が現れる場合に行う必要があります。
対策は守りたいポイントを明確にして、必要処置を行いましょう。
セキュリティ対策を後から入れる場合は、最初から対策よりもコストが高くなります。4
全体像
大きく分けて、クライアント、ネットワーク、サーバに対するクラッキングのポイントを記載していきます。
- クライアントは、クライアント内にある情報に対する攻撃
- ネットワークは、クライアントとサーバ間で行う通信に対する攻撃
- サーバは、サーバ内にある情報に対する攻撃
クライアント
スマートフォン(Android、iOS)端末内で行われる、クラッキングの内容と対策になります。
静的解析
プログラムが実行されていない状態で解析を行うことです。
パッケージ
Androidはapkファイル。iOSはipaファイル。
root(Android)、jailbreak(iOS)状態の端末から環境で取得したり、専用サイトを使用してダウンロードできる。(Androidはroot化してなくても端末から取り出せるかも)
apk、ipa共にzipファイルのため解凍するだけで中身をみることができます。
パッケージ情報の一部ファイルはプレーンテキストではなく、バイナリファイルに変換されています。
変換ツールを使ってプレーンテキストに戻すことができます。(apktoolツールなど)
改変したものをインストールするためには、apk、ipa共にパッケケージを再署名する必要があります。
実行ファイル
Windowsでいうと.exe。macだと.app(正確には実行許可ビットが立っているファイル)。
逆コンンパイル(逆アセンブル)を行われた場合に、可読性の高い状態でコードが復元されてしまいます。
- ソースコードに実際使われないなコードやメソッドを挿入する
- ソースコードを難読化(関数名や変数名を推測しにく名前に変えるなど)し、逆コンンパイルをされても解析しにくいようにする
セーブデータや通信時の暗号化キー、開発用サーバのエントリーポイントなどをconst、static
readonlyなどで文字列定義すると。
実行ファイル内にそのまま文字列として含まれる。逆コンパイルや「strings」コマンドなどで文字列を発見されてしまいます。
- 不要な情報は含めないようにする
- 暗号化や難読化する
- 常にサーバから取得する(ローカルには保存しないようにする)
アセット
Unityだと、シーンファイル、シーンから参照しているリソースファイル、Resourcesフォルダ内のファイル、StreamingAssetsフォルダ内のファイルなどが対象になります。
シーンファイル、Prefab、画像、3Dモデル、音声データ、フォントなどが同梱されます。対処方法は「静的解析→ストレージ→アセット」の項目を参照してください。
マスターデータが含まれる場合もあります。対処方法は「静的解析→ストレージ→マスターデータ」の項目を参照してください。
ストレージ
ストレージは、ROMと表現される内蔵ストレージ。AndroidはSDカードで拡張した領域も含みます。
root(Android)、jailbreak(iOS)端末や、デバッグが許可されているアプリケーションの場合ストレージのデータにアクセスして取得できます。
AndroidのSDカードに書き込んだデータは、PCに接続してマウントしたり、SDカードリーダで簡単に読み出すことができます。
アカウント
ユーザーを識別する必要がある場合には、どのユーザーか認識するためにUUIDや専用アカウントを準備すると思います。
独自で実装する場合して、PlayerPrefs、テキストファイル、バイナリファイルに保存する場合は注意する必要があります。
プレーンテキスト、PlayerPrefs、バイナリファイルに保存すると内容がテキストエディターやバイナリエディターで読むことができます。
- 暗号化や難読化する
- OSのセキュアに保存する機能で保護して保存する(AndroidはAccountManager、iOSはKeychainなど)
- idとパスワードではなく、セッショントークンを保存しておく。一定時間でセッショントークンは更新されるようにしておきクラッカーに渡っても永続的に使用できないようにする
マスターデータ
マスターデータはキャラクターデータ(HPやSTRなど)、敵キャラクターデータ、ステージ情報など、ゲーム初期や動作を設定するための情報をさしています。
敵キャラクターのHPをすべて1に変更して、バトルを有利に進めるられると困ります。
Sqliteや専用のバイナリフォーマットなどを、ストレージに保存している場合は解析が可能です。
マスターデータを取り出し。解析をしてパラメータ変更が行えます。
- 改変されても問題のないデータのみ格納する
- 暗号化や難読化する
- 常にサーバから取得する(ローカルには保存しないようにする)
- 重要な情報は、複数の場所にデータを保存しておき、比較して改変チェックを行う
- ハッシュ値も合わせて保存しておき改変チェックを行う
開発用のデータなど、リリース版のアプリに不要な情報は含めないようにしましょう。
ユーザーデータ
ユーザーデータは、ゲームの設定(ユーザー名、BGMのボリュームなど)、フレンド情報、ゲームの中断データなどがあります。
BGMのボリュームは書き換えられても問題ありません。ですが、ゲームの中断データを改変されクリアしたことになる、勝利したことになると問題になります。
PlayerPrefs、テキストファイル、バイナリファイルでストレージに保存した場合はファイルを取り出し。
ファイルを解析をしてパラメータ変更が行えます。
- 改変されても問題のないデータのみ格納する
- 暗号化や難読化する
- 常にサーバから取得する(ローカルには保存しないようにする)
- 重要な情報は、複数の場所にデータを保存しておき、比較して改変チェックを行う
- ハッシュ値も合わせて保存しておき改変チェックを行う
アセット
パッケージに含まれているものや、クラウドストレージ(AmazonのS3など)からダウンロードしてくるデータをさします。
UnityだとAssetbundleファイルのこと。
Assetbundleではなく、専用のフォーマットで保持する場合もあるかもしれません。
シーンファイル、Prefabなどにテキストで入力してあるセーブデータ、通信時の暗号化キー、開発用サーバのエントリーポイントなどは文字列として保存されてしまいます
- 不要な情報は含めないようにする
- 暗号化や難読化する
- 常にサーバから取得する(ローカルには保存しないようにする)
画像、3Dモデルな、音声データ、フォントなどを変換してPCで閲覧できます。
- 暗号化や難読化する
- 専用フォーマットにして、解析しにくようにする
- 常にサーバから取得する(ローカルには保存しないようにする)
動的解析
プログラムが実行いる状態で解析を行うことです。
攻撃方法
デバッガー
実行中のプログラムを動作を確認するための方法。
通常は開発中のアプリケーションの動作を見るために使用します。
- 実行中のプログラムにアタッチして、実行中のプログラム動作を確認する
- プログラムの動作からチェックロジックなどを探し出す
- 回避ロジックを、実行ファイルにパッチを当て改造アプリを作成する
- アプリケーションを再署名する
メモリ改変
プログラムはメモリ内にロードされて実行されます。
プログラムがロードされたメモリを書き換えて目的の状態に変更する方法です。
- メモリ調査用のアプリを動作させて、アプリケーションを動作させる
- HPなど変化を確認したい箇所をプレイする
- メモリ内の変化を確認して、変更すべき場所を探す
- メモリを書き換えるアプリケーションを使用して、HPなど減らないようにパッチを当てる
常にサーバから取得する(ローカルには保存しないようにする)
サーバーからダウンロード行い、メモリにアセットが常駐している場合はメモリをダンプしてファイルに保存する。
一般的なファイルフォーマットの場合は保存したファイルから、データを一般的なツールを使い表示できます。
暗号化して常駐しさせていれば保存しただけでは表示できません。
ですが、複合ロジックが解析された場合には、アセットのデータと合わせて元のデータを復元される可能性があります。
インジェクション 5
対象のアプリケーションに、ハッキング用のアプリケーションを同梱して実行・攻撃する方法です。
- アプリケーションのハックするためのバイナリを付与する
- アプリケーションを再署名する
- 実機でアプリケーションを動かして動作や変更したいポイントを調査する
- パッチを作り必要に応じてアプリケーションの動作を変更する
対応方法
解析をするようなアクションが行われたことを検知してアプリケーションをクラッシュさせる。
注意点としては、検出ロジックで端末やOSのバージョンによって想定した挙動と異なる場合。
普通にプレイしている場合でもクラッシュさせてしまう可能性があります。
メーカー、OS、バージョン、端末の設定、常駐するアプリをイロイロなパターン組み合わせてチェックする必要があります。
- 端末がroot(Android)、jailbreak(iOS)されていないかチックする
- 特徴的なファイルを検知してアプリケーションを終了させる
- エミュレータチェック
- 特徴的なファイルを検知してアプリケーションを終了させる
- アプリケーションが改変されていないか
- 署名のチェックを行う
- ファイルのハッシュチェックを行い、ファイルが置き換えられていないか確認する
- チェックに引っかかった場合はアプリケーションを終了する
- デバッグモードの設定がオン(許可)になっていないかをチェックする
- デバッグモードがオン(許可)にはアプリケーションを終了する
- デバッガーがアタッチされていないかチックする
- アタッチされている場合はアプリケーションを終了する
- シンボル情報を残さないようにする
- メモリ書き換え
- 複数箇所に書き込みを行い定期的に比較する
- 書き換えられて胃が場合にはアプリケーションを終了する
すべてのチェックを同じタイミングで行うと、まとめて対策コードが潰される可能性があります。
コードを分散する、チェックタイミングを分散する、複数準備して別々にチェックするなど対応を行う必要があります。
ネットワーク
スマートフォン(Android、iOS)とサーバ間の通信で行われるクラッキングの内容と対策になります。
解析
WebAPI
https(SSL/TLS)を使用して呼び出している場合は、そのままではクラッキングされることはありません。
- 最近はAndroid/iOS共に、アプリケーションからのhttpアクセスはは許可されていない。そのため、通信内容を簡単には見れません
- バージョンや設定になどにより通信内容を見たり、改変でき、クラッキングされるケースはある
証明書の正当性チェックをしない実装になっていると、証明書を端末にインストールすることで通信内容の読み取りおよび改変されてしまいます。
(デバッグのために証明書チェックを切った状態でリリースしてしまったなど)
証明書の正当性チェックを行なっていても、実行ファイルの証明書チェックコードを無効化されたり。
プログラム実行中にパッチを当てて無効化される可能性があります。
通信内容にチェックサムを付けてリクエスト内容が改変されていないかをサーバ側で確認する必要があります。
チェックサム自身も解析される可能性があります。
対策方法に関しては、静的解析、動的解析の項目を確認してください。
WebAPIのリクエストエラー時に表示するテキストも解析される可能性があります。
リリース時には、エラーコードのみにして詳細なエラー内容を表示するための文字列を含まないようにしましょう。
(エラーコードとエラー内容の対応表をチーム内のみ参照できるようにする)
Tcp、Udp
オリジナルデータ構造をそのまま送信している場合には暗号化されません。
データ内容を読み改変できないように暗号化する。
パケットが改変されていないかチェックサムを付与してチェックする必要があります。
暗号化キーや証明書の管理、チェックサムロジックを解析されないように注意する必要があります。
対策方法に関しては、静的解析、動的解析の項目を確認してください。
ミドルウェア
ミドルウェア(Photon、モノビットエンジンなど)では通信内容を暗号化機能機能を搭載しています。
暗号化キーや証明書の管理に注意する必要があります。
対策方法に関しては、静的解析、動的解析の項目を確認してください。
生成
リプレイ
端末とゲームサーバの中間にProxyサーバを置き、WebAPIやパケット(Tcp/Udp)送信したものをもう一度送る攻撃方法です。
Proxyで一部のパラメータを変更して送信することも可能です。
例えば、スコアの項目を増やして送るなどです。
証明書の正当性チェックを行い通信内容を改変できないようにましょう。
リクエスト生成
解析した情報を元にクライアントを使用せずにゲームの情報が操作できるようになります。(ゲームの仕様に即した範囲までの操作)
WebAPIはcurl。Tcp/UdpはScapyでリクエストを生成できます。
対策
- 暗号化キーやロジック変更する
- 一定タイミングで、暗号化キーを切り替える
- チェックサムのロジック変更
- リクエストの監視をして、一定処理を繰り返している、明らかに実行できないアカウントを抽出する
- アカウントを削除する。もしくは行動制限をする
- F2Pタイトルだとすぐに新しいアカウントが生成できてしまう。そのため、イタチごっこにはなってしまう
BOT
解析した情報を元に、WebAPIやパケット(Tcp/Udp)のリクエスト生成する。キャラクター操作など自動でゲームが進行するように自動的に操作を生成する手法です。6
(MMOなどでは、開発時に負荷チェックやデバッグために使ったりもする)
リクエスト解析を解析するだけではなく、追加のアプリや、OSの機能、エミュレータなどで簡易操作BOTを作成することもできます。
- スマホ(Android)を自動タップ操作でゲームプレイ!Root化不要のオートクリッカーの設定方法・使い方など。キャプテン翼で検証。│生活向上委員会!
- iPhoneで自動タップ!ゲームの周回が超ラクになるスイッチコントロールとは?|ガラクタブログ
- 「NoxPlayer」or「Androidスマホ」で高速リセマラする方法 | 下手だけどゲーム好きのブログ
対策
- 暗号化キーやロジック変更する
- 一定タイミングで、暗号化キーを切り替える
- チェックサムのロジック変更
- リクエストの監視をして、一定処理を繰り返している、明らかに実行できないアカウントを抽出する
- アカウントを削除する。もしくは行動制限をする
- F2Pタイトルだとすぐに新しいアカウントが生成できてしまう。そのため、イタチごっこにはなってしまう
関連資料
- ゲーム世界を崩壊に追い込むチートbot 1日2億件の不正ログインの実態 (1/5) - ITmedia NEWS
- BOT業者の活動を“ほぼ壊滅”に追いやるまでの軌跡――「ドラゴンネスト」運営チームによる1年半の不正行為対策を振り返る - 4Gamer.net
- 検出不可能なゲームのチートが発表、今後のオンラインゲームのデザインはこのチートを前提に設計しなければならない
サーバ
サーバへ行われるクラッキングの内容と対策になります。
サーバはクラウドサービス(orオンプレミス)、マネージドサービス、mBaasなど使用するサービスにより対応するべき範囲が変わります。
例えば、クラウドサービスではサーバ構成、OSからアプリケーションまで自分たちで面倒見なくてはいけません。(オンプレミスだとハードウェアやハウジング環境もプラスされる)
mBaaSではサーバ上で実行するスクリプトを考慮すれば問題ありません。
(正確には、mBaasサービスを運営しているチームがサーバやOSを管理してくれているだけです。
mBaaSの運営チームのスキルレベルにより問題が発生した場合に、自分たちで使用しているmBaaSサービスの解決できない問題になる可能性はあります)
専門ではないので、よく出ているワードと資料へのリンクになります。
- DoS攻撃:サーバリソースを枯渇させてサーバを使用できない状態にする
- インジェクション攻撃:SQLやOSのコマンドを外部から実行さすることができてしまう問題
- ディレクトリ・トラバーサル攻撃:Webサーバをクローリングを行い、不正にアクセスしファイルの閲覧や改ざんをする攻撃
- ゼロデイ攻撃:サーバ、OS、ミドルウェア、アプリケーションが持つ脆弱性が発見されてから、ベンダーによりセキュリティパッチ(修正プログラム)が適用されるまでの期間を狙って実行されるサイバー攻撃
- ブルートフォースアタック:IDとパスワードでユーザー認証する際のパスワードを手当たり次第試して、パスワードを解析しようとする手法
関連資料
その他
ハードウェア
GPS、加速度センサー、ジャイロセンサーなど位置ゲーを作成する場合に使用する。
位置情報は、GPSだけではなく、無線LANのアクセスポイント、mobile(4Gなど)での位置情報計測も含まれる。
位置情報の補正や、歩数などに加速度センサー、ジャイロセンサーを使用している。
- エミュレータやデバッグ機能でデータを設定されていないかを確認する
- チェックに引っかかった場合は、アプリケーションを終了させる。もしくはデータを採用しない。
- 取得したパラメータが、理論上ありえない移動数値だった場合
- データを採用しないようにする
- 合わせてログを自社で管理するサーバ取得して通知するようにする
- 怪しいユーザーがいた場合に、移動量などが可視化するツールを作成して確認できるようにする
ソーシャルハッキング
ソーシャルハッキング(そーしゃるはっきんぐ)とは - コトバンク
ユーザーIDやパスワードを盗み出すのに、技術的な手段を利用せず、直接本人の口から聞き出す、タイプ内容を盗み見る、書類やメモを入手する、といった手段を利用する行為。盗み見た上司のパスワードを使って情報を盗む組織内犯罪や、掃除夫などを装ってオフィスに侵入する手口等がある。システム管理者の技術的な対応では防ぐことが困難であり、個人個人にセキュリティー意識を徹底させることが重要である。
ソフトウェアからだけではなく、人間自身がセキュリティーホールになる場合もあります。
おすすめ資料
合わせて読むと理解が進むと思います。
- リバースエンジニアリングとチート事例から学ぶセキュリティ対策(cedil登録するとダウンロードできる)
- モバイルゲームのチート対策――チーターの動機と手法:CEDEC2019
- 【CEDEC2019】リバースエンジニアリングとチート事例から学ぶセキュリティ対策 - YouTube
- OWASP モバイルセキュリティテストガイド