213

私は、スコアの上限がなく、サーバー上で動きを再生するなどしてスコアを確認する方法がないアクション ゲームについて話しています。

私が本当に必要としているのは、Flash/PHP で可能な最強の暗号化と、Flash ファイル以外から PHP ページを呼び出す人を防ぐ方法です。過去に、単一のスコアに対して複数の呼び出しを行い、チェックサム/フィボナッチ数列などを完成させ、Amayeta SWF Encrypt を使用して SWF を難読化する簡単な方法をいくつか試しましたが、最終的にはすべてハッキングされました。

StackOverflow の回答のおかげで、Adobe からさらに情報を見つけました - http://www.adobe.com/devnet/flashplayer/articles/secure_swf_apps_12.htmlhttps://github.com/mikechambers/as3corelib -暗号化に使用できます。ただし、これで CheatEngine を回避できるかどうかはわかりません。

AS2 と AS3 が異なる場合、両方の最適なソリューションを知る必要があります。

主な問題は TamperData や LiveHTTP ヘッダーのようなものですが、CheatEngine (Mark Webster に感謝) のような、より高度なハッキング ツールがあることも理解しています。

4

18 に答える 18

416

これは、インターネットゲームやコンテストの典型的な問題です。Flashコードはユーザーと連携して、ゲームのスコアを決定します。ただし、ユーザーは信頼されておらず、Flashコードはユーザーのコンピューターで実行されます。あなたはSOLです。攻撃者がハイスコアを偽造するのを防ぐためにできることは何もありません。

  • バイトコードは十分に文書化されており、高級言語(Actionscript)を記述しているため、Flashのリバースエンジニアリングは想像以上に簡単です。Flashゲームを公開するときは、ソースコードを公開するかどうかに関係なく、それを知っているかどうか。

  • 攻撃者はFlashインタープリターのランタイムメモリを制御するため、プログラム可能なデバッガーの使用方法を知っている人はいつでも変数(現在のスコアを含む)を変更したり、プログラム自体を変更したりできます。

システムに対する最も単純な攻撃は、ゲームのHTTPトラフィックをプロキシ経由で実行し、ハイスコアの保存をキャッチして、より高いスコアで再生することです。

各ハイスコアセーブをゲームの単一インスタンスにバインドすることで、この攻撃をブロックすることができます。たとえば、ゲームの起動時に暗号化されたトークンをクライアントに送信すると、次のようになります。

hex-encoding( AES(secret-key-stored-only-on-server, timestamp, user-id, random-number))

(同じ効果でセッションCookieを使用することもできます)。

ゲームコードは、このトークンをハイスコア保存でサーバーにエコーバックします。ただし、攻撃者はゲームを再度起動してトークンを取得し、すぐにそのトークンを再生されたハイスコアセーブに貼り付けることができます。

したがって、次に、トークンまたはセッションCookieだけでなく、ハイスコア暗号化セッションキーもフィードします。これは128ビットのAESキーであり、Flashゲームにハードコードされたキーで暗号化されています。

hex-encoding( AES(key-hardcoded-in-flash-game, random-128-bit-key))

ゲームがハイスコアを投稿する前に、ハイスコア暗号化セッションキーを復号化します。これは、ハイスコア暗号化セッションキー復号化キーをFlashバイナリにハードコーディングしたために実行できます。ハイスコ​​アのSHA1ハッシュとともに、この復号化されたキーを使用してハイスコアを暗号化します。

hex-encoding( AES(random-128-bit-key-from-above, high-score, SHA1(high-score)))

サーバー上のPHPコードは、トークンをチェックしてリクエストが有効なゲームインスタンスからのものであることを確認してから、暗号化されたハイスコアを復号化し、ハイスコアがハイスコアのSHA1と一致することを確認します(この手順をスキップした場合) 、復号化は単にランダムな、おそらく非常に高い、高いスコアを生成します)。

そのため、攻撃者はFlashコードを逆コンパイルし、AESコードをすばやく見つけます。これは、親指のように突き出ていますが、そうでない場合でも、メモリ検索とトレーサーを使用して15分で追跡されます(「私は知っていますこのゲームの私のスコアは666なので、メモリ内で666を見つけて、その値に触れるすべての操作をキャッチしましょう---ああ、ハイスコア暗号化コードです!」)。セッションキーを使用すると、攻撃者はFlashコードを実行する必要さえありません。彼女はゲーム起動トークンとセッションキーを取得し、任意のハイスコアを送り返すことができます。

あなたは今、ほとんどの開発者が諦めているところです---次の方法で攻撃者をいじくりまわすか、数か月かかります。

  • XOR演算を使用したAESキーのスクランブリング

  • キーバイト配列をキーを計算する関数に置き換える

  • 偽のキーの暗号化と高スコアの投稿をバイナリ全体に分散させます。

これはほとんど時間の無駄です。言うまでもなく、SSLも役に立ちません。2つのSSLエンドポイントのいずれかが悪である場合、SSLはユーザーを保護できません。

ハイスコ​​ア詐欺を実際に減らすことができるいくつかのことがあります:

  • ゲームをプレイするにはログインが必要であり、ログインでセッションCookieを生成し、同じセッションで複数の未処理のゲームを起動したり、同じユーザーに対して複数の同時セッションを許可したりしないでください。

  • これまでにプレイされた最短の実際のゲームよりも長く続くゲームセッションからのハイスコアを拒否します(より洗練されたアプローチについては、平均ゲーム期間より2標準偏差未満続くゲームセッションのハイスコアを「隔離」してみてください)。サーバーサイドでゲームの継続時間を追跡していることを確認してください。

  • ゲームを1回または2回しかプレイしていないログインからのハイスコアを拒否または隔離するため、攻撃者は、作成するログインごとに、合理的な外観のゲームプレイの「紙の証跡」を作成する必要があります。

  • ゲームプレイ中の「ハートビート」スコア。これにより、サーバーは1つのゲームプレイの存続期間にわたってスコアの増加を確認できます。妥当なスコア曲線に従わないハイスコアを拒否します(たとえば、0から999999にジャンプします)。

  • ゲームプレイ中の「スナップショット」ゲームの状態(たとえば、弾薬の量、レベル内の位置など)。これは、後で記録された中間スコアと照合できます。そもそも、このデータの異常を検出する方法さえ必要ありません。あなたはそれを集める必要があります、そしてそれからあなたは物事が怪しげに見えるかどうかそれを分析することができます。

  • セキュリティチェックの1つに失敗したユーザーのアカウントを無効にします(たとえば、検証に失敗した暗号化されたハイスコアを送信するなど)。

ただし、ここではハイスコア詐欺を阻止しているだけであることを忘れないでください。もしそうなら、あなたが防ぐことができることは何もありません。あなたのゲームにお金があれば、誰かがあなたが思いついたシステムを打ち負かすでしょう。目的は、この攻撃を阻止することではありません。それは、単にゲームを上手くやってそれを打ち負かすよりも、攻撃をより高価にすることです。

于 2008-09-16T17:32:22.097 に答える
25

あなたは間違った質問をしているかもしれません。あなたは、人々がハイスコア リストを駆け上がるために使用している方法に注目しているように見えますが、特定の方法をブロックすることには限界があります。私は TamperData の経験がないので、それについて話すことはできません。

質問する必要があるのは、「提出されたスコアが有効で本物であることをどのように確認できますか?」ということです。それを行う具体的な方法は、ゲームによって異なります。非常に単純なパズル ゲームの場合、特定の開始状態と終了状態になった一連の動きと共にスコアを送信し、サーバー側で同じ動きを使用してゲームを再実行することができます。記載されたスコアが計算されたスコアと同じであることを確認し、それらが一致する場合にのみスコアを受け入れます。

于 2008-09-16T16:09:55.057 に答える
19

これを行う簡単な方法は、ハイスコア値の暗号化ハッシュとそれ自体のスコアを提供することです。たとえば、HTTP GETを介して結果を投稿する場合: http ://example.com/highscores.php?score = 500&checksum = 0a16df3dc0301a36a34f9065c3ff8095

このチェックサムを計算するときは、共有シークレットを使用する必要があります。このシークレットはネットワーク経由で送信されるべきではありませんが、PHPバックエンドとフラッシュフロントエンドの両方でハードコーディングされている必要があります。上記のチェックサムは、文字列「secret」をスコア「500」の前に付加し、md5sumを実行することによって作成されました。

このシステムは、ユーザーが任意のスコアを投稿することを防ぎますが、ユーザーが以前に計算されたスコアとハッシュの組み合わせを再投稿する「リプレイアタック」を防ぐことはできません。上記の例では、スコアが500の場合、常に同じハッシュ文字列が生成されます。このリスクの一部は、ハッシュされる文字列にさらに多くの情報(ユーザー名、タイムスタンプ、IPアドレスなど)を組み込むことで軽減できます。これによりデータの再生が妨げられることはありませんが、データセットが一度に1人のユーザーに対してのみ有効であることが保証されます。

リプレイ攻撃の発生を防ぐには、次のような何らかの種類のチャレンジレスポンスシステムを作成する必要があります。

  1. フラッシュゲーム(「クライアント」)は、パラメーターなしでhttp://example.com/highscores.phpのHTTPGETを実行します。このページは、ランダムに生成されたソルト値と、共有シークレットと組み合わされたそのソルト値の暗号化ハッシュの2つの値を返します。このソルト値は、保留中のクエリのローカルデータベースに保存する必要があり、おそらく1分後に「期限切れ」になるように、タイムスタンプを関連付ける必要があります。
  2. フラッシュゲームは、salt値を共有シークレットと組み合わせ、ハッシュを計算して、これがサーバーによって提供されたものと一致することを確認します。この手順は、ソルト値が実際にサーバーによって生成されたことを確認するため、ユーザーによるソルト値の改ざんを防ぐために必要です。
  3. フラッシュゲームは、ソルト値を共有シークレット、ハイスコア値、およびその他の関連情報(ニックネーム、IP、タイムスタンプ)と組み合わせて、ハッシュを計算します。次に、この情報をHTTP GETまたはPOSTを介して、ソルト値、ハイスコア、およびその他の情報とともにPHPバックエンドに送り返します。
  4. サーバーは、クライアントと同じ方法で受信した情報を組み合わせ、ハッシュを計算して、これがクライアントから提供された情報と一致することを確認します。次に、保留中のクエリリストにリストされているソルト値がまだ有効であることも確認します。これらの条件が両方とも当てはまる場合、ハイスコアをハイスコアテーブルに書き込み、署名された「成功」メッセージをクライアントに返します。また、保留中のクエリリストからsalt値を削除します。

ユーザーが共有シークレットにアクセスできるようになると、上記の手法のセキュリティが危険にさらされることに注意してください。

別の方法として、クライアントにHTTPS経由でサーバーとの通信を強制し、クライアントが、ユーザーだけがアクセスできる特定の認証局によって署名された証明書のみを信頼するように事前構成されていることを確認することで、このやりとりの一部を回避できます。 。

于 2008-09-16T16:51:32.400 に答える
11

私は tpqf が言ったことを気に入っていますが、不正行為が発見されたときにアカウントを無効にするのではなく、ハニーポットを実装して、ログインするたびにハッキングされたスコアを確認し、荒らしとしてマークされていると疑わないようにします. 「phpBB MOD Troll」を Google で検索すると、独創的なアプローチが表示されます。

于 2008-09-17T02:47:13.760 に答える
4

受け入れられた回答では、 tqbf はスコア変数のメモリ検索を行うことができると述べています(「私のスコアは666なので、メモリ内で666という数字を探します」)。

これを回避する方法があります。ここにクラスがあります:http://divillysausages.com/blog/safenumber_and_safeint

基本的に、スコアを保存するオブジェクトがあります。セッターでは、渡された値に乱数 (+ および -) を乗算し、ゲッターでは、保存された値をランダム乗数で除算して元に戻します。シンプルですが、メモリ検索を停止するのに役立ちます。

また、ハッキングに対抗するためのさまざまな方法について話している、PushButton エンジンの背後にいる何人かのビデオをチェックしてください: http://zaa.tv/2010/12/the-art-of-hacking-flash-ゲーム/ . 彼らはクラスの背後にあるインスピレーションでした。

于 2011-08-18T16:03:23.903 に答える
3

クライアントが返すデータは信頼できません。検証はサーバー側で実行する必要があります。私はゲーム開発者ではありませんが、ビジネス ソフトウェアを作成しています。どちらの場合も、金銭が関与する可能性があり、人々はクライアント側の難読化技術を破ります。

定期的にデータをサーバーに送り返し、検証を行うかもしれません。アプリケーションが存在する場所であっても、クライアント コードに注目しないでください。

于 2012-05-23T17:46:07.800 に答える
3

既知の (秘密の) 可逆キーを使用して暗号化するのが最も簡単な方法です。私は AS に完全に精通しているわけではないので、どのような種類の暗号化プロバイダーがあるかわかりません。

ただし、ゲームの長さ (これも暗号化されています) やクリック数などの変数を含めることができます。

このようなことはすべてリバース エンジニアリングできるため、大量のジャンク データを投入して人々を混乱から遠ざけることを検討してください。

編集:一部のPHPセッションでもチャッキングする価値があるかもしれません。ゲームの開始をクリックしてセッションを開始し、(この投稿へのコメントにあるように) 時間を記録します。彼らがスコアを提出するとき、彼らが実際にオープン ゲームを持っていて、スコアを提出するのが早すぎたり大きすぎたりしていないことを確認できます。

1 秒 / 1 分あたりのプレイの最大スコアを確認するには、スカラーを計算する価値があるかもしれません。

これらはどちらも回避できないものではありませんが、人々が見ることができる Flash にロジックを配置することは役に立ちます。

于 2008-09-16T16:11:38.017 に答える
3

私の経験では、これはプログラミングの問題ではなく、ソーシャル エンジニアリングの問題としてアプローチするのが最善です。カンニングを不可能にすることに焦点を当てるのではなく、カンニングのインセンティブを取り除いて退屈にすることに焦点を当てます。たとえば、主なインセンティブが一般に公開されているハイスコアである場合、ハイスコアが表示されるタイミングを遅らせるだけで、不正行為者の正のフィードバック ループが排除され、不正行為を大幅に減らすことができます。

于 2009-01-05T17:04:30.340 に答える
2

私は通常、ゲームセッションの「ゴーストデータ」をハイスコアエントリに含めます。したがって、レーシングゲームを作成している場合は、リプレイデータを含めます。多くの場合、リプレイ機能またはゴーストレース機能(最後のレースと対戦するか、リーダーボードの男#14のゴーストと対戦する)のリプレイデータがすでにあります。

これらをチェックすることは非常に手作業ですが、コンテストの上位10エントリが合法であるかどうかを確認することが目標である場合、これは他の人がすでに指摘しているセキュリティ対策の武器に役立つ可能性があります。

目標がハイスコアリストを誰も見なくても時間の終わりまでオンラインに保つことである場合、これはあなたに多くをもたらさないでしょう。

于 2009-01-05T14:53:14.787 に答える
2

あなたは、いわゆる「クライアントの信頼」の問題について話している。クライアント (つまり、ブラウザーで実行される SWF) は、その目的で設計された処理を行っているためです。ハイスコ​​アを保存します。

問題は、「スコアの保存」リクエストが、任意の HTTP リクエストではなく、Flash ムービーからのものであることを確認したいということです。これに対する考えられる解決策は、サーバーによって生成されたトークンをリクエスト時に ( flasmを使用して) SWF にエンコードすることです。これは、ハイスコアを保存するためにリクエストに付随する必要があります。サーバーがそのスコアを保存すると、トークンは期限切れになり、リクエストに使用できなくなります。

これの欠点は、ユーザーがフラッシュ ムービーのロードごとに 1 つのハイ スコアしか送信できないことです。ユーザーが新しいスコアを再生するには、SWF を強制的に更新/再ロードする必要があります。

于 2008-09-16T16:55:33.857 に答える
2

新しい人気のあるアーケード mod が行う方法は、データをフラッシュから php に送信し、フラッシュに戻して (または再ロードして)、次に php に戻すというものです。これにより、データを比較したり、ポストデータ/復号化ハックなどをバイパスしたりしたいことは何でもできます. これを行う 1 つの方法は、php からフラッシュに 2 つのランダム化された値を割り当て (リアルタイムのフラッシュ データ グラバーを実行している場合でも取得または表示することはできません)、数式を使用してランダムな値でスコアを追加し、次を使用してチェックすることです。同じ式を逆にして、最終的にphpに移動したときにスコアが一致するかどうかを確認します。これらのランダムな値は表示されることはなく、トランザクションが発生する時間を計ります。

あなたが私に尋ねると、これはかなり良い解決策のように思えますが、この方法を使用して何か問題があると思いますか? またはそれを回避する方法はありますか?

于 2010-01-05T03:31:38.987 に答える
2

最も簡単な方法は、ゲームが追加するスコアを登録するたびに RegisterScore(score) のような関数を呼び出し、それをエンコードしてパッケージ化し、php スクリプトに文字列として送信することだと思います。PHPスクリプトは、それを適切にデコードする方法を知っています。これにより、スコアを強制しようとすると圧縮解除エラーが発生するため、php スクリプトへの直接の呼び出しが停止します。

于 2012-01-18T18:03:06.297 に答える
2

これは、すべてのゲームロジックをサーバー側に保持することによってのみ可能です。サーバー側は、ユーザーの知識がなくてもスコアを内部に保存します。経済的および科学的な理由から、人類はターンベースを除くすべてのゲーム タイプにこの理論を適用することはできません。たとえば、サーバー側で物理学を維持することは、計算コストが高く、手の速度として応答するのが困難です。チェスをプレイしている間に、誰でも AI チェスのゲームプレイを対戦相手と一致させることができます。したがって、優れたマルチプレイヤー ゲームには、オンデマンドの創造性も含まれている必要があります。

于 2012-03-06T19:29:53.770 に答える
2

ハイスコ​​ア システムが、Flash アプリケーションが暗号化されていない/署名されていないハイスコア データをネットワーク経由で送信するという事実に基づいている場合はいつでも、それは傍受され、操作/再生される可能性があります。答えは次のとおりです。ハイスコア データを暗号化 (適切に!) するか、暗号で署名します。これにより、少なくとも、SWF ファイルから秘密鍵を抽出する必要があるため、ハイスコア システムをクラックすることが難しくなります。ここで諦めてしまう人も多いのではないでしょうか。一方、キーを抽出してどこかに投稿するのに必要なのは、1 人だけです。

実際のソリューションでは、Flash アプリケーションとハイスコア データベースとの間でより多くの通信が行われるため、ハイスコア データベースは与えられたスコアがある程度現実的であることを検証できます。ゲームの種類によっては、これはおそらく複雑です。

于 2008-09-16T16:11:58.420 に答える
2

SWF は簡単に逆コンパイルできるため、完全にハッキングできないようにする方法はありません。熟練した開発者ハッカーがコードを追跡し、使用する可能性のある暗号化システムをバイパスする方法を見つけ出す可能性があります。

ただし、TamperData などの単純なツールを使用して子供の不正行為を止めたい場合は、起動時に SWF に渡す暗号化キーを生成できます。次に、http://code.google.com/p/as3crypto/などを使用してハイスコアを暗号化してから、PHP コードに戻します。次に、データベースに保存する前にサーバー側で復号化します。

于 2008-09-16T16:17:20.187 に答える
1

あなたが望むものを達成することは本当に不可能です。Flash アプリの内部は、特にCheatEngineなどの使用方法を知っている場合は常に部分的にアクセスできます。つまり、Web サイトとブラウザーとサーバーの通信がどれほど安全であっても、克服するのは比較的簡単です。

于 2008-09-16T16:27:55.293 に答える
1

AMFPHPを介してバックエンドと通信することをお勧めします。少なくとも怠け者がブラウザー コンソール経由で結果をプッシュしようとするのを思いとどまらせるはずです。

于 2014-05-13T22:17:15.497 に答える