非 Web ゲーム向けの安全なオンライン ハイスコア リスト
-
09-06-2019 - |
質問
私が書いているネイティブ (非 Web) シングルプレイヤー ゲームで遊んでいるのですが、毎日/毎週/オールタイムのゲームがあることに気づきました。 オンラインハイスコアリスト (Xbox Live Leaderboard を思い浮かべてください) コミュニティと競争が (少量ではありますが) 追加されれば、ゲームはさらに面白くなります。しかし、人々はそのような機能をハッキングへの誘いと見るのではないかと心配しており、ありえないほど高いスコアのために通常のプレイヤーの意欲をそぐことになるでしょう。
私はそのような試みを防ぐ明白な方法 (公開鍵/秘密鍵の暗号化など) を考えましたが、ハッカーが私の考えをすべて回避できるかなり簡単な方法を見つけ出しました (バイナリから公開鍵を抽出し、偽の暗号化されたデータを送信する)。たとえばスコアなど)。
オンラインのハイスコア リストやリーダーボードを実装したことがありますか?これを実装する合理的にハッカー耐性のある方法は見つかりましたか?もしそうなら、どうやってやったのですか?ハッキングの試みについてどのような経験がありますか?
解決
結局のところ、あなたはクライアントを信頼することに依存しています。クライアントがリプレイをサーバーに送信する場合、成功したプレイスルーを複製または変更してサーバーに送信することは簡単です。
最善の策は、不正行為のハードルを、プレイヤーが乗り越える価値があると考えるレベルよりも高くすることです。これを行うには、実証済みの (ただしあまり言及されていない) テクニックを使用できます。
- ブラックリストに登録された詐欺師をハニーポットに放置します。彼らは自分のスコアを見ることができますが、他の人は見ることができません。別のアカウントでログインして確認しない限り、ゲームのハッキングに成功したと考えられます。
- 誰かが不正行為者としてフラグを立てられた場合、将来の特定の時点までアカウントへの影響が現れるのを延期します。この点は 1 ~ 3 日以内にランダムに設定します。通常、詐欺師は複数の方法を試し、最終的には成功します。アカウントステータスのフィードバックを後日まで延期すると、何が原因で引っかかったのか理解できなくなります。
- すべてのゲーム ユーザー コマンドをキャプチャし、サーバーに送信します。特定のデルタ内の他のスコアと比較してそれらを検証します。たとえば、プレーヤーがシュート アクションを 200 回使用して 200,000 のスコアを獲得したが、ゲーム内の隣のプレーヤーが 5,000 回シュートして 210,000 のスコアを獲得した場合、その人物にさらなる続行またはヒューマン フラグを立てるしきい値がトリガーされる可能性があります。調査。
- ユーザー アカウントに価値と永続性を追加します。ユーザー アカウントにゲームのロック解除機能がある場合、またはゲームの購入が必要な場合、ユーザーは Web ベースのプロキシ経由で新しいアカウントを作成するだけでは以前のアカウント ステータスを取り戻すことができないため、禁止の重みは大きくなります。
他のヒント
ユーザーの管理下にあるシステム上でゲームが実行されている間は、完璧な解決策はありませんが、システムのハッキングをより困難にするために実行できる手順がいくつかあります。結局のところ、目的は、システムのハッキングをその価値以上に困難にすることだけです。
- ハイスコアリクエストとともにいくつかの追加情報を送信し、サーバー側で検証します。X ごとに 5 ポイントを獲得し、ゲームに X が 10 個しか含まれていない場合、ハッカーがスコアを有効なものとして受け入れるために飛び越えるための追加のフープがいくつかあります。
- サーバーに、そのオフセットからのゲームのバイナリの数バイトで満たされる必要があるランダムなチャレンジを送信させます。つまり、ハッカーはバイナリの元のコピーを手元に置いておく必要があります (少し手間がかかります)。
- ライセンス キーをお持ちの場合は、ライセンス キーを含めるには高スコアを要求します。これにより、システムのハッキングを発見したユーザーを禁止できます。これにより、上で定義した無効な試行を追跡して、有効なスコアを送信する前にプロトコルをテストする人を禁止することもできます。
しかし全体として、このゲームを人々がハッキングしようと思うほど人気を得るのは、おそらくはるかに大きな課題だろう。
正直に言ってそれは不可能だと思います。
私は、圧縮バイナリを使用した非常に単純なキー暗号化を使用する前にそれを実行しました。これは、必要なセキュリティには十分に機能しましたが、誰かがあなたのオンラインハイスコアテーブルのクラッキングをハッキングだと考えたら、それは行われるだろうと正直に思います。
世の中には、とても悲しい人もいますが、たまたまとても明るい人もいます。それらをすべて解決できない限り、それは失われた原因です。
ゲームにリプレイ システムが組み込まれている場合は、リプレイをサーバーに送信し、サーバーにリプレイからスコアを計算させることができます。
この方法は完璧ではありませんが、ゲームの速度を遅くしたり (アクションベースの場合)、ボットを作成したりすることで不正行為を行うことができます。
私はこれを Flash ゲームでいくつかやっていますが、本当に負け戦です。特に ActionScript の場合は、あまり手間をかけずにある程度読みやすいコードに逆コンパイルできます。
私がこれまで行ってきた方法は、スコアとプレイヤー名をプレーンテキストで送信し、その後 2 つのハッシュ (適切にソルト処理) を送信するという、かなり従来的なアプローチです。それを理解するために努力するほどの決意を持っている人はほとんどいませんし、少数の人はとにかくそれを実行し、それに費やしたすべての時間を無効にします。
要約すると、私の哲学は、ゲームをより良くすることに時間を費やし、不正行為が十分に困難になるようにすることです。
非常に効果的と思われることの 1 つは、プレイ中にゲームにスコアをサーバーに数回送信させ、そのたびに少しのゲームプレイ情報を送信して、スコアが「現実的」かどうかを検証できるようにすることです。しかし、それは実際には少しやりすぎかもしれません。
それは本当に難しい質問です。
私はそのようなことを実装したことはありませんが、簡単な近似は次のとおりです。
主な懸念は、ハッカーがアプリケーションが何をしているかを推測し、独自の結果を送信することです。
まず第一に、あなたのアプリケーションが大成功しない限り、私は心配しません。そのようなことを行うのは非常に困難です。
暗号化しても問題は解決しません。ご存知のとおり、暗号化は途中でデータを保護するのには役立ちますが、データが暗号化される前 (主な脆弱性が存在する可能性がある) まではトランザクションのどちらの側も保護しません。したがって、確実に暗号化すれば、データのプライバシーは保たれますが、安全ではありません。
本当に心配な場合は、コードを難読化し、何が行われているかが完全に明らかではない方法でスコア システムを設計することをお勧めします。ここでは、暗号化プロトコルからいくつかのものを借用できます。以下に例を示します。
- スコアがある数値 m だとしましょう
- スコアに対して何らかのチェックを計算します (たとえば、CRC やフィートが表示されるその他のシステムなど)。実際、何かを発明すれば、たとえそれがどんなにダサくても、うまくいくでしょう)
- ユーザー (D) の秘密キーをリモート サーバーから (明らかに安全な接続経由で) 取得します。この鍵を知っているのはあなただけです。
- X=m^D mod n (n は公開鍵/秘密鍵アルゴリズムの公開モジュール) を計算します (つまり、暗号化します:P)
ご覧のとおり、これは別の種類の難読化にすぎません。好きなだけその道を下りることができます。たとえば、X に最も近い 2 つの素数を検索し、それらを使用して CRC を暗号化し、それをサーバーにも送信することで、CRC とスコアを別々に、異なる暗号化スキームで取得できます。
これを難読化と組み合わせて使用すると、ハッキングが困難になると思います。それにもかかわらず、それさえもリバースエンジニアリングできる可能性があり、それはすべてハッカーの興味と能力に依存しますが...真剣に、ゲームの結果を変えるのにどんな変人がそんなに努力するのでしょうか?(WoWか何かでない限り)
最後に注意事項
他の回答にあるように、潜在的に悪意のあるクライアントを信頼する必要があり、小規模なゲームには単純な抑止力と人間による監視で十分です。
もっと贅沢したい場合は、クレジット カード会社が請求データを調べるのと同じように、スコア データから不正パターンを探す必要があります。クライアントがサーバーに通信する状態が増えるほど、コードを介して正しい動作または誤った動作のパターンを見つけることが容易になる可能性があります。例えば。たとえば、クライアントがスコアの時間ベースの監査ログをアップロードする必要があるとします (これを使用して、他のクライアントにトップゲームを視聴させることもできます)。その後、サーバーはスコア ログがゲーム ルールに違反していないかどうかを検証できます。
結局のところ、これはスコアボードの不正行為を阻止するのに十分なコストを設定することを目的としています。検証システムに対する新たな攻撃に対処するために、いつでもサーバー コードを (更新が簡単に) 改善できるシステムが必要です。
@マーティン。
これがマリオカートWiiの仕組みだと私は信じています。追加のボーナスは、ハイスコア保持者がどのようにしてハイスコアを獲得したかを他のプレイヤー全員に観察させることができることです。これの面白い点は、最速でチェックアウトすると、グランブル火山" タイム トレイルを辿ると、誰かがトラックの 95% をスキップできるショートカットを見つけたことがわかります。彼らが今もそれを最速タイムとして記録しているかどうかはわかりません。
信頼されていないクライアント プラットフォームではこれを行うことはできません。実際には、一部の「信頼できる」プラットフォームさえも破ってしまう可能性があります。
一般的なケースでは検出することが不可能なさまざまな攻撃が存在します。主にメモリ内の変数を変更するものです。自分のプログラムの変数を信頼できない場合、実際には大きな成果を上げることはできません。
上記で概説した他の手法は役立つかもしれませんが、信頼されていないプラットフォームで実行するという基本的な問題は解決できません。
興味本位でハイスコアテーブルをハッキングしようとする人がいると思いますか?私はもう 2 年以上、簡単に解読できるハイスコア テーブルを使用してオンライン ゲームをプレイしています。多くの人がそれをプレイしましたが、誰もハイスコアを破ろうとしたという証拠はありません。
通常、不正行為やハッキングに対する最大の防御策はコミュニティの監視です。スコアがかなり疑わしいと思われる場合、ユーザーは不正行為としてスコアを報告できます。そして、十分な数の人がそのスコアを報告すると、管理者がリプレイの妥当性をチェックすることができます。すでに多数のプレイヤーが完全に合法的にゲームをプレイしている場合、ボットと実際のプレイヤーの違いを確認するのは非常に簡単です。
管理者は、問題が発生したスコアのみを監視する必要があります。これは、多くのユーザーが苦労して獲得した完全なスコアを削除するために便乗する可能性が低いためです。また、管理者は報告される少数のスコアを確認するだけでよいため、時間はそれほどかかりません。小規模なゲームであればなおさらです。
頑張ってボットを作っても、通報システムによってまた撃墜されるだけだということを知っているだけでも、それ自体が抑止力になります。
おそらくリプレイデータを暗号化しても問題はないでしょう。再生データは小さいことが多く、暗号化してもそれほど多くのスペースは必要ありません。そして、それを改善するために、サーバー自体が制御ログによる再生を試み、それが達成されたスコアと一致することを確認します。
アンチチート システムが見つけられないものがあったとしても、ユーザーはそれを見つけます。