しかし、今ではこれはすでに十分ではありませんでした- 別のアプローチを使用すると 、その時点で私の偉業はすでに追い出され 、さらには超えています (記事によると、最終結果は400万ポイントに近づいています)。 そのため、サーバーへのリクエストをゲームの結果に単純に置き換えようとする、別の明らかなステップを踏むことにしました。 スクリーンショットからわかるように、試行は正常に完了しました。
原理
不正行為に対するこのアプローチの原則は、恥をかきやすいものです。 プレイヤーからの超高速反応を必要とするゲームでは、サーバー上のすべての「移動」をチェックするのは非効率的です。インターネットのわずかなジャグリングと高速プレイヤーは、即座にエンミタードプレイヤーに変わります。 そして、サーバーの負荷は不必要です。1人のプレイヤーから毎秒12のリクエストをチェックしたい人はいますか? したがって、これ以上苦労することなく、ゲームの作成者はクライアント側にゲームロジックを転送し、計算されたポイント数だけがサーバーに送信されます。 実際の結果の代わりに偽物をサーバーに送信すると、次にゲームを開始したときに、上記で示したような写真を見ることができます。
そのような偽物からサーバーを保護する方法は? 厳密に言えば-この状況では原則としてこれは不可能です。 ゲームの結果をサーバーに通知するリクエストがクライアント上で作成されます-これは、その形成に関するすべてのルールがすでにあることを意味します。 それにもかかわらず、ハッカーは次の方法でタスクを複雑にすることができます(そしてもちろんそれらの組み合わせ)。
- クライアントに配線されたキーで送信された情報に署名する、
- サーバーから受け取ったキーで送信された情報に署名する。
- 現在の時刻で送信された情報に署名する(別のフィールドで送信される)
- 送信された情報を暗号化する、
- クライアントコードを難読化して、暗号化アルゴリズム、署名アルゴリズム、フラッシュされたキーの値を認識できないようにします。
これらの手法のどれが問題のゲームの開発者によって使用されたかを見てみましょう。
操作傍受
Fiddlerなど、ある種のWebトラフィックスニファーを配置します。 HTTPのみをインターセプトできます(それでも常にではありません)が、ここではそれで十分です。 スニファーを起動し、ゲームのあるページを開いて、1つのゲームをプレイします。 Fiddlerに戻ります。
おもちゃサーバー(ddg.wooga.com)へのリクエストはまばらです-すべては期待どおりです。 ゲームの始まり( / game / use_lifeへのリクエスト/ -各ゲームに費やされた人生の中心を使う)とその終わり( / game / eor / -ラウンドの終わり)をはっきりと見ることができ、その間には何もありません。
ゲームの最後には、 ddg.wooga.com / game / eorへの要求と、 ddg.t.wooga.com / w / eorへの要求の2つがあります。 最初の分析を開始します。
リクエスト:
POST ddg.wooga.com/game/eor/?timestamp=1314395650744&signature=V5rwMEQJS_2diWc...ulj2VBs%3D&session=1100447b5bb0d08c12 HTTP/1.1
Host: ddg.wooga.com
Connection: keep-alive
Content-Length: 99
Origin: 8kubpeu8314p2efdd7ljdo-a-oz-opensocial.googleusercontent.com
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1
content-type: application/json
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.3
Cookie: _dd_rails_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIljA4NmUzZDZiNjk5MGYxZDQzNWQ%3D--3e580eae77a1037b347dae6229bb6d
{"user_id":"104465643407894900734","level":21,"sound":1,"score":144768,"xp":130,"gems_removed":348}
答えは:
(以降、ハイフネーションなしで収まるように一部の行が短縮されます)HTTP/1.1 200 OK
Server: nginx
Date: Fri, 26 Aug 2011 21:54:12 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Vary: Accept-Encoding
Status: 200 OK
Cache-Control: no-cache
X-UA-Compatible: IE=Edge,chrome=1
Set-Cookie: _dd_rails_session=BAh7BkkiD3GOgZFR...wNDUxNTc%3D--b85c8953db82adcb0; path=/; HttpOnly
X-Runtime: 0.009475
Content-Length: 120
{"timestamp":"1314395652","user_id":"104465643407894900734","signature":"PAfgcneDa83-fR5_-CzJWpQ="}
シンプルで明確なJSON。暗号化されていません。 確かに、アドレスにはタイムスタンプ 、 署名 、およびセッションが含まれているため、何らかの署名があります。 実際、答えは特に意味がありません。サーバーは、署名データも吐き出します。
アクティブなアクション
まあ、私たちは馬鹿げています: ゲームを開始することなく、完全に同一のリクエストを送信し、 スコアフィールドの値のみを99999999に置き換えます。幸いなことに、Fiddlerにはこれに適したツールがあります-リクエストビルダー。
奇妙なことに、応答として、異なるタイムスタンプと署名を除いて、まったく同じ200 OKを取得します。 サーバーの気楽な反応に驚いています。ゲームでページを更新しようとしています。 更新すると、さらに驚くことになります。ゲームは私たちを信じていましたが、99,000,000の代わりに16,777,215を数えました。これは「天井」であるようです。データベースには、おそらくUNSIGNED MEDIUMINT(3バイト整数)最大値。
これで停止することは可能ですが、アプリケーションの「セキュリティ」の観点からこのような落ち込みが発生した後、思わず不思議に思う人がいます。大きな穴はありますか?
進む
ご覧のとおり、サーバーへのリクエストではuser_idが渡されます-Google +のページの識別子です。 そして、このuser_idが本当に私たちのものかどうかをサードパーティのサーバーが理解できるように、署名は明らかに正確に必要です。 うーん、彼は本当にこれを理解していますか? それとも、彼はだまされやすいので、他の誰かに代わって「勝つ」ことができますか?
友人の1人のページに登り、アドレスから彼のIDをドラッグし、同じリクエスト内のすべてを掌握します(修正するためのタイムスタンプも記録します)。 ええ、すべてはここでうまくいくようです:400 Bad Request ...いいえ、ちょっと待ってください:
HTTP/1.1 400 Bad Request
Server: nginx
Date: Fri, 26 Aug 2011 22:07:06 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Status: 400 Bad Request
Cache-Control: no-cache
X-UA-Compatible: IE=Edge,chrome=1
Set-Cookie: _dd_rails_session=BAh7BkkiZ...Tk5NmFkOTA%3D--b96793945142dd62b0e5ea9a; path=/; HttpOnly
X-Runtime: 0.002774
Content-Length: 124
Signature mismatch! Got: V5rwMEQJS_2diQ8sdZMXBs= computed: gcLO6NdBJtwBtOwrWIpwL9LliuA=
計算済み?! 実際、状況はほぼ次のとおりです。他の人のアカウントにログインしようとしています。 パスワードを知らなくても、何でも入力してください。 応答として、エラーメッセージだけでなく、正しいパスワードも取得します。 素晴らしい。
応答から署名を素直にコピーし、要求に置き換えて送信します。 あなたはおそらく、完全に友好的な200 OKが応答することをすでに推測していました。 そして期待される結果:
(上記は私のアカウントで、以下は「実験的な」友人です)
結論またはなぜこれがすべて「偽の」不正行為であるか
ゲームダイアモンドダッシュの開発チームは、おそらく、過失のせいにされるべきです-間違いに対応して正しい署名を示す価値はありませんでした...しかし、それらに厳しすぎることはできません。 結局のところ、これは単なるカジュアルグッズであり、冒頭で述べたように、不正行為を避けることはできません。 実際、不正行為と戦うための唯一の真の方法が使用されました。評価テーブルはユーザーの友人からのみコンパイルされます。 したがって、 不正行為の結果は、不正行為者の友人にのみ表示されます (ただし、署名にバグがある場合は、そうではありません)。
ご清聴ありがとうございました-そして、私の記事が主にチートではなく、それに対する防御の開発に役立つことを願っています:)