Telegramのすべてのゲームの履歴をハックする

今、コンピューターゲームはどこにでもあります。 また、Telegramにも存在します。 このメッセンジャーのほぼすべてのゲームがハッキングされ、スコアボードのトップにいる最高クラスのプレーヤーをバイパスしたことについて説明します。 研究結果を共有したい。 ハッキング、不正行為のさまざまな方法、およびカットされたゲームのロジックをバイパスする方法について。







@gamebot



数ヶ月前にレビューされた最初のゲーム-LumberJackは、木こりとしてプレイします。プレーヤーを押しつぶさないように、枝を切る必要があります。 ゲームの目標は、一定時間内にできるだけ多くのブランチを削減することです。







最初は、ゲームのグラフィック読み取りで練習したかったのです。つまり、モニター上のグラフィックデータに基づいて決定を下しました。 プログラムは、画面上の状況に基づいて必要なキーの組み合わせを送信し、人間の反応をエミュレートする必要があります。 現在のゲームのプログラムロジックを構築する原理は次のとおりです。 ツリーの右側にある600x1ピクセルのサイズのスクリーンショットが撮られます。 このような大きなスペースのスクリーンショットを撮るプロセスには時間がかかるため、画面全体ではありません。 次に、プログラムは6ポイントでピクセルの色をチェックし、これに基づいて、一度に6ブランチのプレーヤーの軌跡を計算します。 右側に分岐がある場合は左に進み、そうでない場合は右側にとどまります。 1回の移動で、withで2回ヒットします。 移動が実行された後、スクリーンショットが再度取得され、サイクルが繰り返されます。 これは、時間がなくなるまで続きます。







Ubuntu 16.04 OS上のPython 2.7のプログラムコード



import os, time import pyscreenshot as ImageGrab from Xlib import display def move_left(): os.system("xte 'key Left'") def move_right(): os.system("xte 'key Right'") def exist_branch(x, y): box = (x, y - 6 * 100, x+1, y) im = ImageGrab.grab(box) rgb_im = im.convert('RGB') x, y = im.size result = [] for i in range(0, 6): r, g, b = rgb_im.getpixel((0, y - 1 - i * 100)) summa = r + g + b if summa < 700: result.append(True) else: result.append(False) return result def get_mouse(): while True: data = display.Display().screen().root.query_pointer()._data x = data["root_x"] y = data["root_y"] print '%s,%s - %s' % (str(x), str(y), exist_branch(x, y)) def main(): start_x = 1543 start_y = 641 while True: branches = exist_branch(start_x, start_y) cons_str = "" for elem in branches: if elem: cons_str += 'Left ' else: cons_str += 'Right ' print cons_str for elem in branches: if elem: move_left() time.sleep(0.03) move_left() else: move_right() time.sleep(0.03) move_right() time.sleep(0.2) try: #get_mouse() time.sleep(5) main() except: print 'Exit..'
      
      





実行するには、次の依存関係をインストールする必要があります



 sudo apt-get install xautomation pip install pyscreenshot
      
      





xteユーティリティは、Linuxでキーをエミュレートする役割を担います;詳細については、 こちらをご覧ください 。 pyscreenshotライブラリーは、画面の選択された領域のスクリーンショットを取得する役割を果たします 。詳細はこちらをご覧ください 。 プログラムが機能するためには、最初のポイント(右側の一番下のブランチ、またはそれが配置される可能性のある場所)を設定する必要があります。これには、get_mouse()関数を使用できます。 ブランチ間の高さは100ピクセルです。 キーストローク間の遅延とスクリーンショットの取得間の遅延は、試行錯誤によって設定されます。 これらの値よりも小さい値を設定することはできませんでした。プログラムには画像を処理したり、キーを押したりする時間がありませんでした。 作品の例をビデオに掲載しています。







800ポイントを獲得できるのは1人ではないため、プログラムの結果は勝利と見なすことができます。



作成とデバッグのプロセスには非常に長い時間がかかったため、他のソリューションを検討する必要があります。



HTTPリクエストを分析する場合、ゲームの最後に2種類のリクエストが送信されます。 ユーザーが新しいレコードに到達していない場合。



 POST /api/getHighScores HTTP/1.1 Host: tbot.xyz Accept: */* Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Content-Length: 197 Content-Type: text/plain;charset=UTF-8 Connection: close data=[..some_base_64_code..]
      
      





新記録



 POST /api/setScore HTTP/1.1 Host: tbot.xyz User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0 Accept: */* Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Referer: https://tbot.xyz/lumber/ Content-Length: 206 Content-Type: text/plain;charset=UTF-8 Connection: close data=[..some_base_64_code..]&score=some_score
      
      





some_scoreを何らかの値に置き換えるだけで十分であり、新しい数値がテーブルに追加されます。



Base64は、アカウントに関する情報、つまりid、ゲームをクリックしたプレーヤーの名前、ゲームの名前、およびチャットIDを送信します。



このゲームが@gamebotボットに属していることは注目に値します。これにはさらに2つのゲームMath BattleCorsairsがあります。 ゲームMath Battleについて詳しく説明しました。







スコア付きのHTTPリクエストも同様に送信されます。 ブラウザのインス​​ペクターを介してリクエストを送信することは価値があります。



デバッガーモードを開いたら、ソースコードmain.min.jsを開きます。 いくつかのブレークポイント(ブレークポイント)を置き、ゲームを開始し、ポイントの数を格納する変数rを見つけます。 コンソールを介して、この値を変更できます。







デバッグモードをオフにすると、ポイントを送信する機能が実行されるため、既に設定されているポイント数を送信できます。 インスペクターをオフにするなど、何度もクリックしないようにするには、 JS Beautifierサービスによって編集されたソースコードmain.min.jsを少し理解する価値があります。 以下に3つの興味深い機能を示します。



 function ba(a, b, d) { var c = new XMLHttpRequest, e = [], f; for (f in b) e.push(encodeURIComponent(f) + "=" + encodeURIComponent(b[f])); c.onreadystatechange = function() { 4 == c.readyState && 200 == c.status && d(JSON.parse(c.responseText)) }; c.open("POST", a, !0); c.send(e.join("&")) } function na() { n && ba("/api/setScore", { data: n, score: r || 0 }, function(a) { e = a.scores; Y(); I(); a["new"] && l && (z = !0, x(M, "shown", z)) }) } function ca() { n && ba("/api/getHighScores", { data: n }, function(a) { e = a.scores; Y(); I() }) }
      
      





新しいレコードに到達するとna()関数が呼び出され、ゲームのスコアボードを取得するためだけにca()が必要になります。 ところで、どの関数を呼び出すかは、この行のU()関数で決定されます。



 r > Z ? na() : ca();
      
      





パラメータrを変更して関数na()を呼び出す場合、デバッグモードを有効にする必要があります。 このようなものでなければなりません。







ソースコードは少し難読化されているため、分析が難しくなりますが、基本的なことは明らかです。



@gamebotボットにも関連するCorsairsゲームは、上記のすべての方法で解決されます。 サーバーへのさまざまなリクエストに対して、私は禁止され、スコアボードに追加できません、アカウントは禁止リストにあります。 このボットのゲームをテストするときは注意する必要があります。



@gamee



@gameeボットは非常に人気がありました。 Quboゲームが選択されました。







ゲーム終了時に送信されるリクエストは次のとおりです。



 POST /set-web-score-qkfnsog26w7173c9pk7whg0iau7zwhdkfd7ft3tn HTTP/1.1 Host: bots.gameeapp.com Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Length: 247 Origin: https://www.gameeapp.com Connection: close {"score":2,"url":"/game/u0yXP5o-7c87f893be9fbc72d9dae3826b7037a53d331dd1","play_time":76,"hash":"{\"ct\":\"q3Qv2QtaFAlihlaAvZSp+ahHSq7y4Uut5bLd80nYX1pp9rz0jh03si8Nx2HIe91x\",\"iv\":\"93b55f8f4105a269e74a58bec5e0e0a0\",\"s\":\"da96bc85b70f149d\"}"}
      
      





前のボットのように、スコアの置換は失敗します。 スコア、play_timeなどに署名するハッシュが生成されるため、このような簡単な方法でポイントを取得できません。 デバッガーには多くの変数があったため、あまり役に立ちませんでした。







コードを手動で分析する必要がありました。 ゲームページのソースコードで、このようなコードを見つけることができます。







スクリプトは通常の方法ではなくjsのリクエストを介して接続されるため、インスペクターには表示されないことに注意してください。 2つの興味深いファイルはgameUI.min.jsgameUIdesktop.min.jsです。 最初のファイルで、gameeUIオブジェクトのメソッドである関数が見つかりました。



 saveScore: function(e) { var a = window.location.pathname, t = gameeUI.user, n = (new Date).getTime(), o = $("#dataId").data(), i = CryptoJS.AES.encrypt(JSON.stringify({ score: e, timestamp: n }), o.id, { format: CryptoJSAesJson }).toString(), s = { score: e, url: a, play_time: gameeUI.playTime, hash: i, username: t, anonymous_id: gameeUI.anonymous_id }; if (isFacebook()) { var r = FacebookUserData.getUserData(); s.app_scoped_user_id = r.app_scoped_user_id, s.user_id = r.user_id } gameeUI.sendScoreData(s) }
      
      





明らかに、入力パラメーターeはサーバーに送信されるポイントです。 コンソールでgameeUI.saveScore(some_score)の行を送信することで、大切なポイント数を取得できます。



このボットには、ゲーム "3 + 3"、 "Karate Kido"、 "Space Traveler"、 "Hexonix"などが含まれます。 上記の方法ですべて解決されます。 次のボットのゲームの1つが特定の方法で解決されると、このボットの他のゲームもそれによって解決されると結論付けることができます。



@GamesHDBot



かなり複雑なロジックは、ゲーム「Galaxy Space Shooter」と呼ぶことができます。 美しいグラフィック、ゲーム中にたくさんの豪華な、あなたはポイントとコインを獲得することができます。







しかし、インスペクターを調べて、TlgAdapterオブジェクトとそのputScoreメソッドを見つけるだけで十分でした。







@ludeiBot



このボットは好奇心が強いことが判明しました。 テスト用のゲームはジャンプ潜水艦です。







ゲーム終了時のリクエストは次のとおりです。



 POST /v1/setscore HTTP/1.1 Host: telegram-games.ludei.com Accept: */* Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Content-Type: application/json;charset=UTF-8 Content-Length: 73 Origin: https://angrypianohtml5.ludei.com Connection: close {"inlineId":"token","userId":"user_id","score":some_score}
      
      





ポイントは簡単に交換できます。 驚くべきことに、user_idはクリアテキストで送信されます。 チャット内のすべてのユーザーのIDを見つけた場合、次のスパム攻撃を行うことができます。 これは、Telegram APIを使用して実行できます。







アイデアは、テーブル内の別のプレイヤーのポイントを変更できるだけでなく、一般的なチャットでスパムを送信して、現在のゲームの新しい勝者に関する通知を送信できるということです。 正しく行われた場合、これはかなり深刻な攻撃です。 実際に誰がポイントを獲得したかを判断することは不可能であり、チャットからその人(攻撃者または「スパム」をしている人)を除外した後でも、混乱を続けることができます。 管理者を含むチャット参加者に代わって「スパム」を行い、チャット管理者に特定の人を強制的に除外させることができます。 このような不明瞭さを止める唯一の方法は、チャット管理者が提案されたゲームのメッセージを削除することです。



このボットには、ゲーム「iBasket」、「Sumon」、「Angry Piano」も含まれています。



しゅう



5つのゲームがこのボットに属し、上記の種類の攻撃に使用できます。

たとえば、ゲーム、おなじみのサッパー。







要求は次のとおりです。



 GET /embed/telegram-game-bot/?user_id=user_id&inline_message_id=chat_id&score=score HTTP/1.1 Host: meduza.io Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Connection: close
      
      





これはさらに簡単です。 チャットIDとユーザーIDを知っている通常のGET要求で、スパムを手配できます。



@foragamesbot



ゲームは1つだけです-「DevRunner」







ゲームの終了後、2つのリクエストが送信されます



 POST /game/scored HTTP/1.1 Host: devrunner.fora-soft.com User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Accept: */* Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Content-Type: application/x-www-form-urlencoded Referer: https://devrunner.fora-soft.com/?uid=453743655&imi=AgAAAKwAAAAnlAsbCh1sirM6oOQ Content-Length: 97 Cookie: _ga=GA1.2.2104866484.1507563316; _gid=GA1.2.1543721993.1507563316 Connection: close user_id=453743655&score=111111&chat_id=&message_id=&inline_message_id=AgAAAKwAAAAnlAsbCh1sirM6oOQ
      
      





 POST /game/scores_image HTTP/1.1 Host: devrunner.fora-soft.com Accept: */* Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Content-Type: application/x-www-form-urlencoded Content-Length: 47 Connection: close crutches=1&bugs=2&scores=31&level=0&rank=Intern
      
      





2番目のクエリでは、現在のポイント数を持つプレーヤーがどこにいるかを確認できます。 テストが開始される前は、2000〜3000ポイントのプレーヤーが最初でした。面白いことに、合計で約1万3千人がゲームをプレイしました。 これらの人は誰もこのゲームをしのぐことを考えていなかったことがわかります:)クエリをポイント数111113に置き換えることが第一位でした。







しゅう



このゲームのボットは間違いなく最も退屈だと言えます。



例はチェスです。 評価なし、勝利の警告など。 ゲームはクライアント側のみです。







しゅう



このゲームは、このボットで唯一のジャンパーカエルです。







ゲーム終了時にリクエストする



 POST /score HTTP/1.1 Host: microgames-ijwqbqxfic.now.sh User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Accept: */* Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Content-Type: application/json; charset=UTF-8 Referer: https://microgames-ijwqbqxfic.now.sh/games/jumper_frog/?token=eyJhbGciOiJIUzUxMiJ9.eyJnYW1lIjoia... Content-Length: 14 Connection: close {"score": 700}
      
      





トークンの一部は切り取られますが、意味は明確でなければなりません。 スコアのみがサーバーにデータとして送信されます。 交換は簡単です。 質問は異なります。特定の人がプレイしていることをサーバーがどのように認識し、テレグラムチャットでスコアボードに書き込みましたか? そして、すべてが簡単です-サーバーは、上記のトークンのRefererヘッダーからデータを取得します。 奇妙な松葉杖、笑。 論理的な質問は、このゲームへの直接リンクに移動するとどうなりますか? 上記のリクエスト(リファラーなし)に応じてポイントを獲得した場合にのみ、この種の答えが返ってきます。







ファイルへの絶対パスを明らかにするエラーをキャッチしました。 たとえば、LFIとの互換性では、すでに多くの有用なデータを取得できます。 しかし、タスクはゲームの欠陥を検出することであり、特定のゲームの本格的なペンテストを実施することではなかったため、これで停止することにしました。



@foxgamebot



ゲーム「トリッキーフォックス」について説明します。これは、すべての中で最も複雑な構造であり、他のすべてのゲームに比べてセキュリティレベルが高く、回避に長い時間がかかりました。 著者はよくできており、彼は非常に適切なゲームを作成しました。それを分解するのは面白かったです。 このゲームを解決するプロセスを詳細に説明したいと思います。 プレイヤーの仕事は、島から島へジャンプして鶏を食べることです。 電話の画面でマウスの左ボタンまたは指を押し続けると、キツネを目的の距離に飛ばすことができます。







ゲームの終わりに、そのようなリクエストが送信されます



 POST /game-api/expandScore HTTP/1.1 Host: play.alexbelov.xyz Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Content-Type: application/json;charset=utf-8 Content-Length: 432 Connection: close {"hash":"d5139c23e94113af55baa5a5b48c42f03c0438d768588aa28057f3da72c938aa4e9db142b6ba0dacbde4aa0fd6ebedf1447d4493f53608a4ff321fee1549c115fc5e3eca98c23c45539982ae08a8ce2627db050eeb73fb13339727b03294739d98b88e9b372be8df37689393794d894108e6c5afe024bfbe451a955100d02649eb5e8fb0091a2186f2303be5a2d4af374cbb1ad0cfd3914b8dbe406ebcd4fe0443f0d05224067088043ac51962ada7207d480d249a10ab595ae0da3627942637","session":"bf102fd528a0..."}
      
      





どのようなハッシュがまだ明確ではありません。 明らかに16進数でもbase64でもありません。 元の3万行で、コードを読み取り可能な形式に再フォーマットする場合。 JS Beautifierサービスが使用されました。 そのようなフィルター-ポスト "でサブストリングを探すのは論理的です。そのような関数が見つかりました。



 key: "setScore", value: function(e) { console.log(e); var t = "expandScore"; return this.apiRequest(t, { hash: e }, { method: "post" }) }
      
      





検索でこの関数を検索することにより、呼び出される場所をいくつか見つけることができます。 たとえば、これらのオブジェクト-this.ApiServiceまたはthis.scoreViewから。 しかし、それらのどれも検査官を通してアクセスできませんでした。 次に、どの種類のハッシュが送信され、どのようにデコードするかを決定することにしました。



さらに、検索はテキストsetScoreですでに実行されています。 暗号化がどのように行われるかを大まかに説明したすばらしい機能がありました。



 key: "saveResults", value: function() { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, n = window, r = n.gameMe, i = f.default.extend({ key: r._shard }, p), o = d.encrypt(i, JSON.stringify(t).split("").reverse().join("")); this.ApiService.setScore(o).then(function(t) { e.updateMe() }) }
      
      





最初に、まだ知られていないデータのJSON形式が文字列に変換され、次にこの文字列が配列内の文字に分割され、これらの文字の順序に逆方向に変更され、文字列が再び接着されます。 開発者からの小さなアンチリバースチップ? スクリーンショットのようにブレークポイントを設定することにより、特に行14016で使用可能なすべての現在の機能とオブジェクトへのアクセスが取得されました。







これで、いくつかの興味深いオプションにアクセスできます。







ECBモードでは、すべてのデータがAES 256アルゴリズムで暗号化されていることがわかります。 しかし、はっきりしていないのは、対称暗号化の優れたサービスを得たことです。







一方、プログラムは異なる結果をもたらしました。







暗号化アルゴリズムも変更されたことが判明しました。これは、アンチリバースと運用プロセスのための別のチップです。 ただし、これは最大の問題ではありません。 サーバーに送信されるポイントの数ではなく、JSON形式のデータ配列(読みやすくするためにフォーマットされ、リクエストにはハイフネーションはなく、単一のスペースはありません)。



 { "_s":"1", "_f":[200,440.412834676673], "_p":0.61, "_r":0.44048586944056, "_t":1507933273148, "_n":{ "_s":"2", "_f":[200,531.1135607680883], "_p":0.64, "_r":0.5711409299481298, "_t":1507933274848, "_n":{ "_s":"3", "_f":[200,583], "_p":0.73, "_r":0.06360827768619635, "_t":1507933277447, "_n":{ "_s":"4", "_f":[200,374.96787925000024], "_p":0.54, "_r":0.4264300320950012, "_t":1507933278662 } } } }
      
      





_tのロジックに基づいて、これはミリ秒単位で次の鶏が食べられた時間です。_f-島または鶏の座標、_s-数、_n-鶏が食べられた次の島。 サーバーは、採点されたポイントの数ではなく、雌鶏が食べられたときに記録されたデータを処理しません。 ゲームのセキュリティに関して非常に良いアイデアです。



いくつかのゲームを費やした後、_pと_rが何であるかを判別できませんでした。ほとんどの場合、それらは注意をそらしてコードの理解を複雑にする開発者の別の機能です。 しかし、すべての変数は特定の制限内で変化し、必要な時間と必要なポイント数に基づいてJSON配列を生成するスクリプトが作成されました。



 import time import json import random score = 3 #time = time.time() * 1000 time = 1507761372191 def generate(counter, time, score): if counter < 10: _s = counter else: _s = chr(counter + 87) _f = [200, random.randrange(360, 600) + random.randrange(2*10^14, 9*10**14)/(10.0*10**14)] _p = random.randrange(15, 80) / 100.0 _r = random.randrange(2*10^19, 9*10**19)/(10.0*10**19) _t = time result = {'_s' : _s, '_f' : _f, '_p' : _p, '_r' : _r, '_t' : _t} if counter < score: time += random.randrange(1000, 6000) result['_n'] = generate(counter + 1, time, score) return result def start_generate(time, score): result = generate(1, time, score) result = json.dumps(result) result = result.split(' ') result = ''.join(result) return result def console_str(time, score): return "d.encrypt(i, '" + start_generate(time, score) + "'.split('').reverse().join(''));" print console_str(time, score)
      
      









結果をコンソールに挿入してから、HTTPリクエストを置換する必要がありました。 残念ながら、これはいくつかのポイントで機能し、アカウントは禁止されました。 どうやらスクリプトですべてが考慮されたわけではないようです。



別のテストアカウントを取得し、ソースコードの調査とテストの実施を続けなければなりませんでした。 ソースにはさまざまな奇妙なものがあります。たとえば、すべての種類のAES暗号化が実装されている、またはハッシュテーブルを使用したこのような奇妙なコードです。







または、たとえば、目的のキーがbase64にある理由が不明です(md5キーは暗号化中に送信されました)。







そして、ここに彼のトランスクリプトがあります。







これらは、コードに見られるすべての奇妙なものではありません。 しかし、さらに数時間のデバッグの後、私は何か面白いものを見つけました。catchAnimals関数です。



 key: "catchAnimals", value: function() { var e = this, t = [this.foxOffsetX, this.foxy.position.y], n = this.getHitAreaAnimal(this.foxy, t, this.foxOffsetX); if (n) { window.score = ++this.score; var r = v.Utils.getRandomInt(0, 100) / 100; r < .9 ? gameSounds && ion.sound.play("chicken_3") : gameSounds && ion.sound.play("chicken_1"), this.scoreView.setScore(this.score), this._passIslands || (this._passIslands = {}); var i = { _s: this.score.toString(20), _f: t, _p: r, _r: Math.random() * r, _t: (new Date).getTime() }, o = this.getListHead(this._passIslands); o._t ? o._n = i : y.default.extend(o, i), isWebGLRenderer && game.getFPS() > 45 && f.Main.CanvasWidth > 2500 && ! function() { var t = new l.ScoreIncrementer; t.addScore(1, n.animalType, function() { e.removeChild(t), t.destroy(), t = null }), e.addChild(t) }(), this.animationAttractor.append(n.getRebornNumber(), n, function(e) { return e.explode() }) }
      
      





それから、配列がどのように生成されるかが明らかになります。 キツネが別の鶏を食べるたびに、この関数が呼び出され、新しいデータブロックが既存の配列に追加され、_n変数に配置されます。 また、スコアにはスコアが記録され、これは小数の代わりに別の計算に転送され、小数システムの数値は開発者による別の反逆テクニックであるスコアに記録されました。 スクリプトを改善する代わりに、ブレークポイントを設定し、スコアをその場で置き換えることにしました。







コードでスコアを設定する直前。 コンソールで値を変更し、スクリプトを続行します。







そして、私は自分の仕事に報われました。







少し後で一般的なスコアボードに追加されました。







1つの配列だけでポイントを変更できることは注目に値します。 _sパラメーターで、20桁の計算システムで必要なポイント数を書き留め、生成されたキー(md5形式)を使用して、これらすべてをカスタムaesアルゴリズムで暗号化します。 キーはチャットIDに基づいて発行され、ゲーム中に変更されないことに注意してください。 このゲームのidアカウントに基づいて、少なくとも10万人がプレイしたと結論付けることができます。



サーバーの脆弱性が原因でこの攻撃が完了したことに注意してください。 コードはJSONで受信され、復号化されます。おそらく、最大の_sを持つ配列がデータ配列から取得され、1つだけであることは問題ではありません。 これは簡単に修正できます。配列全体を解析して_sの増分を増やし、このパラメーターの値がJSONツリーの出現数と一致することを確認する必要があります。



どのような結論を出すことができますか? クライアント側で処理されるものはすべて変更、置換できます。データの暗号化の難易度やコードの難読化の程度は問題ではありません。 よくできた開発者のゲーム「Tricky Fox」に非常に満足しています。 これは、最大1〜2時間を費やす必要があるゲームですが、不正行為を防ぎ、ロジックをバイパスするための対策を講じる必要があります。 メガネを変更することに不注意な態度を持つ他のより人気のあるゲームの背景に対して、ゲームは非常によくできています。 親愛なる読者が独自のゲームを開発したい場合、この記事のケースを実際に分析して、美しく興味深いゲームだけでなく、非常に保護されたゲームを作成できます。



検討する価値のある興味深いゲームがあり、上記の方法では解決できない場合は、 VKまたはテレグラムまたはコメントを送ってください。検討を試みます。 要求の傍受にはBurpSuiteを使用しました。



PS多くのゲームのポイントを置き換えるには、 Telegram Cheatsサービスを使用できます。 しかし、そこには、すべてのゲームがだまされるわけではありません。



All Articles