1 पॉइंट द्वारा GN⁺ 2023-12-06 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Magic: The Gathering Arena में प्रतिद्वंद्वी को मनचाहे समय पर हार मानने के लिए मजबूर किया जा सकता था, जिससे matchmaking गेम में कभी न हारने की स्थिति बनाई जा सकती थी
  • कार्ड गेम आमतौर पर उस server-authoritative architecture के लिए उपयुक्त होते हैं जिसमें पूरा state server संभालता है, लेकिन MTGA का bot opponent Sparky local client logic के रूप में implement किया गया था
  • C# आधारित MTGA client में reflection के जरिए runtime objects और private fields तक पहुँचा जा सकता था, और decompiled code में JoinMatch, ConnectAndJoinMatch, HeadlessClient जैसे नाम दिखे
  • bot match में एक ही account के PersonaID और JWT से दोनों seats पर connect होने वाली संरचना इस्तेमाल होती थी, और इसे सामान्य match पर लागू कर opponent seat पर headless client जोड़ने के बाद ConcedeGame() कॉल किया जा सकता था
  • बाद में server पर patch किया गया ताकि matchmaking गेम में दोनों seats एक ही account और JWT का उपयोग न कर सकें, और यह client-side bot implementation तथा seat authentication validation की सीमा का व्यावहारिक security पर सीधे असर दिखाने वाला उदाहरण बना

कार्ड गेम को हैक करना कठिन क्यों है

  • कार्ड गेम turn-based होते हैं और client तथा server के बीच बहुत अधिक जानकारी का आदान-प्रदान नहीं होता, इसलिए वे server-authoritative architecture के लिए अच्छी तरह उपयुक्त हैं
  • server पूरा game state संभालता है और client को केवल ज़रूरी जानकारी भेजता है
    • प्रतिद्वंद्वी के hand या deck जैसी सार्वजनिक न होने वाली जानकारी local में मौजूद नहीं होती
    • deck क्रम बदलने या अगला card manipulate करने जैसी कोशिशें कठिन होती हैं, क्योंकि server कार्रवाई चलाता है और केवल परिणाम बताता है
  • first-person shooter से अलग, कार्ड गेम में player actions सीमित होते हैं और तय समय पर होते हैं
    • FPS में enemy model location जैसी जानकारी client में पहले से cache हो सकती है, इसलिए wallhack जैसी तकनीकें संभव होती हैं
    • Riot का anti-wallhack ब्लॉग client-side player location data घटाने के दृष्टिकोण पर चर्चा करता है
  • गलत व्यवहार का पता लगाना भी तुलनात्मक रूप से आसान है
    • हाथ में न होने वाला card खेलना
    • अपनी turn न होने पर action करना

विश्लेषण की शुरुआत: नेटवर्क और C# client

  • game hacking की शुरुआत के लिए network communication देखने का तरीका चुना गया
  • MMO hacking के मामलों पर Manfred की DEF CON प्रस्तुति दिखाती है कि network protocol reverse engineering कई bugs के विश्लेषण में अहम होती है
  • MTGA, C# में लिखा गया है, इसलिए traffic send/receive functions को hook करने के बजाय runtime में objects को manipulate किया जा सकता था
    • .NET reflection से private fields और methods तक भी पहुँचना संभव है
    • संबंधित बुनियादी उदाहरण के रूप में Unity game reflection hacking tutorial जुड़ा है
  • obfuscate न किए गए .NET assemblies में metadata token की वजह से functions, variables और classes के नाम मानव-पठनीय रूप में देखे जा सकते हैं
    • इसी कारण decompiled output लगभग source code review जैसा बन जाता है

JoinMatch में मिली Sparky की संरचना

  • match join initialization खोजने के लिए संबंधित function names ढूँढते हुए JoinMatch function मिला
  • JoinMatch 200 से अधिक lines वाला लंबा function था, और नीचे ConnectAndJoinMatch कॉल दिखाई दी
    • यह function match configuration information लेकर game server से connect होने वाला flow लगता था
  • उसी code flow में MatchType.NPE और MatchType.Familiar branches थीं
    • NPE संभवतः नए खिलाड़ियों के experience वाली tutorial match श्रेणी थी
    • Familiar standard bot match था
  • इस branch में कॉल होने वाला logic MTGA के bot opponent Sparky से जुड़ा था
    • Sparky tutorial और bot battles में इस्तेमाल होने वाला MTGA का mascot-जैसा opponent है
    • bot matches में bot logic local machine के game client के भीतर चलता था

local bot और HeadlessClient

  • bot का वास्तविक logic handler HeadlessClient class के भीतर था
  • HeadlessClient एक headless client है जो game board render नहीं करता, बल्कि server से connect होकर game चलाता है
  • local में बनाए गए bot client ने game client जैसी ही user authentication information का उपयोग किया
    • user ID की भूमिका वाला PersonaID
    • login के बाद game को दिया जाने वाला JSON web token
  • bot matches में server इसे समस्या नहीं मानता था कि मूल रूप से एक ही client match की दोनों sides से connect हो जाए
  • seat का उपयोग game में यह अलग करने के लिए होता है कि कौन-सा player कौन है
    • bot match में एक ही authentication information से अलग-अलग seats भरना संभव था

सामान्य match पर कब्ज़ा करने का तरीका

  • bot match logic को सामान्य matches पर लागू कर यह जाँचा गया कि क्या दोनों seats से connect हुआ जा सकता है
  • ज़रूरी जानकारी runtime के game objects से ली गई
    • वर्तमान match configuration
    • match server host और port
    • controllerFabricUri
    • matchId
    • PersonaID
    • Jwt
    • card database
    • match manager
    • asset lookup system
  • अपनी seat के आधार पर opponent seat की गणना की गई
    • code में man.LocalPlayerSeatId % 2U + 1U से दूसरी seat निकाली गई
  • UnityFamiliar.SpawnFamiliar_DEBUG(...) से opponent seat पर bot connect कराया गया
  • बने हुए UnityFamiliar object को ढूँढकर cheatbot.Client.Gre.ConcedeGame() कॉल किया गया, जिससे तुरंत हार मान ली गई

परिणाम और patch

  • यह तरीका सामान्य matches में भी काम करता था
    • प्रतिद्वंद्वी पहले से connected हो और game चल रहा हो, तब भी यह काम करता था
    • क्योंकि यह matchmaking game था, इसलिए इंसानी opponent को हराने जैसा reward मिलता था
  • vulnerability का मूल यह था कि सामान्य match server एक ही account और JWT से दोनों seats पर connection की अनुमति दे रहा था
  • बाद में server पर patch किया गया ताकि matchmaking गेम में दोनों seats एक ही account और JWT का उपयोग न कर सकें
  • परिशिष्ट में दिया गया InstaWin code एक Unity MonoBehaviour है, जो GUI button बनाता है, और button click पर मौजूदा match information इकट्ठा कर bot को opponent seat पर जोड़कर उससे हार मँगा देता है

1 टिप्पणियां

 
GN⁺ 2023-12-06
Hacker News की राय
  • Linux को पहली बार सच में गहराई से समझने की शुरुआत EverQuest के लिए ShowEQ से network traffic देखने से हुई थी
    उस समय traffic encrypted नहीं था और उसमें बहुत-सी उपयोगी जानकारी होती थी। Hub के ज़रिए traffic को Linux machine पर mirror करके zone का real-time map बनाया जाता था, और monster·NPC·user की locations दिखाई जाती थीं, यहाँ तक कि monster के loot भी दिखते थे, इसलिए सिर्फ़ चुने हुए monster को target किया जा सकता था। इसका फ़ायदा यह था कि यह manual तरीका था, इसलिए detect करना संभव नहीं था, और आख़िरकार SOE को इसका पता चल गया और उसने traffic encryption शुरू कर दी

    • डेटा को आख़िरकार decrypt करके पढ़ना ही पड़ता है, इसलिए client का reverse engineering करके real-time decryption का तरीका खोज लिया गया
      फिर दूसरी तरफ़ key-based signing लाई जाती है, उसके बाद फिर client से key चुराने की कोशिश होती है, encryption तोड़ी जाती है, और फिर anti-cheat system आने के साथ बिल्ली-चूहे का खेल शुरू हो जाता है
    • किशोरावस्था में Dark Age of Camelot में भी ऐसा ही कुछ किया था, और network sniffing, hub और switch का फ़र्क, और Linux सीखने में यह बहुत उपयोगी रहा
      क्या यह game में फ़ायदा लेने लायक था? नहीं। मैं इतना serious player नहीं था, इसलिए setup पर 2 हफ़्ते लगाए और लगभग 1 हफ़्ता इस्तेमाल किया, बस, लेकिन learning experience के रूप में यह शानदार था
    • याद है कि ShowEQ का इस्तेमाल Verant/Sony द्वारा लगातार नकारे जा रहे कई theories और bugs को साबित करने में हुआ था
      उदाहरण के लिए hell level का अस्तित्व, यह कि इंसानों को नहीं बल्कि halfling को experience bonus मिलता था और सचमुच race/class के हिसाब से experience में फ़र्क था, शुरुआती Shaman alchemy वास्तव में टूटी हुई थी, आदि। और शायद यही आगे चलकर eqemulator.org तक पहुँचा, अगर मैं सही याद कर रहा हूँ
    • यह समझ नहीं आ रहा कि encryption कैसे मदद करती है। Client को तो वैसे भी decrypt करना ही है, तो फिर उसी पर ride नहीं किया जा सकता क्या?
    • ShowEQ आज भी काम करता है, और Windows-आधारित memory reader MySEQ भी है
      लगता है कि EQ के मौजूदा मालिक को इसकी ज़्यादा परवाह नहीं है, इसलिए इसे इस्तेमाल करना काफ़ी हद तक ठीक माना जाता है। हालाँकि दोनों apps ने visible gear को छोड़कर कभी monster के loot नहीं दिखाए। समय के साथ कुछ data भी बदल गया है; पहले monster की सटीक health भेजी जाती थी, अब सिर्फ़ percentage भेजी जाती है
  • “Magic: The Gathering का कोई भी arbitrary game खेलने वाला लगभग पूर्ण bot इतना छोटा है कि local machine पर चल सके” — यह हिस्सा ठीक से समझ नहीं आया
    अगर MTG AI इतना भारी होता कि उसे customer machine पर चलाना मुश्किल हो, तो शायद उसे server पर भी नहीं चलाया जाता। Card game bot match आम तौर पर per-match billing वाले नहीं होते, इसलिए cost बड़ी हो जाती है। Server भी कोई जादू नहीं हैं; ज़्यादातर local machine जैसे ही x86 CPU इस्तेमाल करते हैं, और कई बार desktop से कम clock speed पर। अगर local से कम bot turn time चाहिए, तो customer की तुलना में कहीं ज़्यादा cores लगाने पड़ेंगे, और अगर player per 8~16 allocated cores जैसी बात हो, तो peak concurrency पर यह डरावना सपना लगेगा। अगर CPU player multi-core support नहीं करता, तो local execution को किसी भी हाल में ज़्यादा तेज़ होना चाहिए

    • यहाँ बात processing performance की नहीं बल्कि memory usage की थी
      मतलब यह कि bot का rules engine इतना छोटा है कि पुराने iPhone या Android device की memory में समा सके। Server पर state machine या rules engine की कई copies memory में रखी जा सकती हैं, और किसी specific request को execute करने में शायद processing performance लगभग लगे ही नहीं
    • Desktop के लिए यह सही है, लेकिन यह भी याद रखना चाहिए कि MTGA फ़ोन पर भी चलता है
    • MTG बहुत जटिल rules system वाला game है
  • Daniel, एक बार फिर front page पर आने की बधाई। यह पोस्ट आने के बाद मैंने भी MTGA को hack करके देखा और GitHub पर थोड़ा लिखा भी [0]
    दिलचस्पी रखने वालों के लिए, मैं इस समय लगभग बिना features वाले एक unofficial MTGA client पर निष्क्रिय रूप से काम कर रहा हूँ। लक्ष्य ranked game play का automation और ज़्यादा मजबूत bot opponent देना है। हाल में यह दूसरे कामों के कारण पीछे चला गया है, और साफ़-सुथरा, समझ में आने वाला अच्छा UI कैसे बनाया जाए, इस पर भी अभी तक स्पष्टता नहीं है, इसलिए यह न्यूनतम रूप से उपयोगी कब बनेगा, इसका अंदाज़ा लगाना भी मुश्किल है। इसके अलावा Daniel या दूसरों की game hacking कहानियाँ सुनने में भी दिलचस्पी है। ऐसे bugs कैसे ढूँढे जाते हैं, hack करने के बाद ban की चिंता कैसे नहीं की जाती, @aethros की तरह bugs को public कैसे किया जाता है, unofficial card game client को कैसे structure किया जाता है — इन सब पर और सुनना चाहूँगा
    [0] https://github.com/MayerDaniel/mayerdaniel.github.io/issues/...

  • MTG जैसे जटिल game में AI opponent बनाने के लिए overhead बड़ा होगा, यह कहना काफ़ी बड़ा understatement है
    यह game लगभग Turing complete है, और infinite loops को छोड़ भी दें तो लोग उससे बहुत खेलते हैं। फिर भी AI strategy पर काफ़ी research पहले से हुई होगी, ऐसा लगता है। और चूँकि यह पोस्ट लेखक ने ख़ुद डाली है, इसलिए title में “Show HN:” भी होना चाहिए था

    • Show HN blog post के लिए नहीं, बल्कि ऐसे projects के लिए है जिन्हें लोग ख़ुद छूकर देख सकें: https://news.ycombinator.com/showhn.html
    • “Game में Turing machine encode की जा सकती है” और “हर स्थिति में legal action लेने वाला program लिखना कठिन है” — ये दोनों बातें बिल्कुल एक जैसी नहीं हैं
      bot बनाने वाले के लिए मुश्किल दूसरी वाली बात लगती है
    • यह वास्तव में Turing complete है: https://arxiv.org/abs/1904.09828
    • नए sets rotate होते रहते हैं, इसलिए game लगातार बदलता रहता है, लेकिन कुछ interactions में infinite loop बन सकता है, या अलग-अलग समय पर बन सकता था, ऐसा मुझे पता है
      उदाहरण के लिए enter/leave/untap effects के ज़रिए token creature बनाना और मारना। ऐसे loops में हमेशा किसी एक पक्ष को damage हो, यह ज़रूरी नहीं
    • जानना चाहता हूँ कि क्या real strategies में भी इस complexity के आसपास कुछ आता है
      मैंने MTG खेला नहीं है, लेकिन यह दावा जीतने के उद्देश्य से ज़्यादा, जानबूझकर stateful structure बनाने पर तकनीकी रूप से संभव होने जैसा लगता है
  • बेटे के साथ old-school Magic 93/94 को फिजिकल कार्ड्स से खेलना सचमुच बहुत मज़ेदार है
    हम हर साल Madrid जाते हैं और 7pts Singleton विश्व चैम्पियनशिप में भाग लेते हैं। इस गर्मियों में मेरा बेटा 9वें स्थान पर आया, जिस पर मुझे बहुत गर्व है। 7pts Singleton एक शानदार फ़ॉर्मैट है, जिसमें डेक बनाने की बहुत विविधता मिलती है और अपेक्षाकृत कम लागत पर संतुलित gameplay देता है (https://7pts-singleton.com)

    • जिस फ़ॉर्मैट में Black Lotus, Ancestral Recall, और Moxen legal हों, उसे सस्ता कहना मुश्किल है
      भले ही 7pts Singleton में इन सबको एक साथ इस्तेमाल न किया जा सके, इनमें से सिर्फ़ एक की कीमत भी हज़ारों से लेकर दसियों हज़ार डॉलर तक होती है। फिर भी, बेटे के साथ गेम का आनंद लेना अच्छी बात है, और रैंक में आने पर बधाई
  • पूरी तरह client-side game logic? जब मैंने पहले छोटे गेम बनाए थे, तब responsiveness के लिए कभी-कभी client में game logic डालना पड़ता था, लेकिन ऐसा कोई नियम नहीं था कि server उसी logic को दोबारा execute न करे, इसलिए हमने ऐसा किया
    FPS या RTS जैसे real-time games में यह मुश्किल हो सकता है, लेकिन card games में इसका कोई बहाना नहीं है। ऐसे card game में client को खिलाड़ियों की वास्तव में दिखने वाली जानकारी से ज़्यादा कुछ नहीं भेजना चाहिए। उदाहरण के लिए, opponent के hand की card contents भेजने के बजाय सिर्फ़ cards की संख्या भेजनी चाहिए। server को भेजे जाने वाले actions भी सिर्फ़ अपने बारे में होने चाहिए, इसलिए opponent की surrender घोषित करने की अनुमति नहीं होनी चाहिए। अगर मैं “surrender!” कहूँ, तो server को उसे मेरी surrender के रूप में समझना चाहिए

    • लेख से यही समझना चाहिए कि गेम वास्तव में इसी तरह लिखा गया है। ज़रूरत के समय सिर्फ़ ज़रूरी जानकारी मिलती है, और सिर्फ़ अपने actions भेजे जाते हैं
      कमजोरी यह थी कि दूसरा client चलाकर चल रहे गेम में opponent की seat के रूप में connect किया जा सकता था। एक बार ऐसा हो जाने पर, surrender सहित opponent के actions भेजे जा सकते थे
    • जैसा कि लेख में साफ़ लिखा है, gameplay पूरी तरह server-side पर संभाला जाता है
      लेखक ने client-side game logic का नहीं, बल्कि authorization और game access code की समस्या का फ़ायदा उठाया था। “opponent की ओर से surrender घोषित नहीं कर पाना चाहिए” कहना बस वही दोहराना है कि लेखक द्वारा खोजा गया exploit कैसे काम करता था
    • लेख के पहले एक-तिहाई हिस्से में साफ़ तौर पर कहा गया है कि गेम ऐसा ही implement किया गया है
  • League of Legends में एक ख़ास champion और item combination के साथ divide-by-zero bug हुआ करता था, जिससे server crash होने से पहले सभी खिलाड़ियों को बाहर निकाल देता था
    क्योंकि exploiter सबसे आख़िर में निकाला जाता था, उसकी team को जीत मिलती थी, और दूसरी team को सामान्य result की जगह Loss Prevented मिलता था

    • अगर दूसरी टीम को सामान्य हार नहीं दी जा रही, तो जीतने वाली टीम को भी win नहीं मिलनी चाहिए
  • इस लेख में आसान भाषा और insightful details का अच्छा संतुलन है
    लेकिन मुझे यह समझ नहीं आता कि असली मैच के दौरान bot को connect कैसे किया जा सकता है। गेम बीच मैच में join करने की अनुमति क्यों देता है, और bot के surrender करने पर उसे opponent की surrender क्यों माना जाता है? अगर यह 3-player game बन भी रहा हो, तो player 3 के surrender करने से player 2 की भी surrender नहीं मानी जानी चाहिए

    • यह 3-player game नहीं बनता, बल्कि 2-player game ही बना रहता है
      code मेरे account की seat index पता करता है, फिर bot को दूसरी seat index के रूप में join करवाता है। समस्या यह है कि join करने वाला user उस seat पर होने वाला सही user है या नहीं, इसकी जाँच नहीं होती। यह भी कहा जा सकता है कि पहले से connected seat पर दोबारा connection की अनुमति नहीं होनी चाहिए, लेकिन अगर गेम mobile भी support करता हो, तो आप disconnect timeout काफ़ी लंबा रखना चाहेंगे। क्योंकि आप उस player को रोकना नहीं चाहेंगे जो थोड़ी देर के लिए disconnect हुआ और timeout के पुराने connection को dead मानने से पहले ही reconnect करना चाहता है। दूसरे गेमों में भी मैंने देखा है कि reconnect करने पर लगभग 10 सेकंड तक “चल रहे गेम में शामिल नहीं हो सकते” दिखता है, और बाद में ही reconnect होता है। एक तुलना करें तो जैसे आप स्थानीय card shop के MTG tournament में पहुँचें, किसी को उसकी कुर्सी से हटाकर खुद बैठ जाएँ और चिल्लाएँ “मैं surrender करता हूँ!”, और judge यह मान ले कि उस कुर्सी पर बैठे व्यक्ति ने घोषणा की है, इसलिए player B ने concede कर दिया
      1. संभवतः यह disconnect के बाद reconnect को संभालने का तरीका था। यानी पुराने connection को बंद कर दिया जाता होगा
      2. bot player 2 की जगह ले लेता है, फिर surrender submit करता है, और server उसे player 2 की surrender के रूप में रिकॉर्ड कर लेता है
    • MTG: Arena 3-player games की अनुमति नहीं देता, इसलिए bot opponent की seat में घुसपैठ कर रहा था
      शायद इसी वजह से वह opponent की ओर से surrender कर सका। हो सकता है developers ने सोचा ही न हो कि कोई जानबूझकर ऐसा करने की कोशिश करेगा, इसलिए उन्होंने वह check नहीं लगाया
  • Diablo 2 के दिनों की याद आ गई, जब उसी login packet को दोबारा इस्तेमाल करके open server characters (LAN) को आधिकारिक bnet internet servers पर connect किया जा सकता था
    open server data पूरा का पूरा local में stored होता था, इसलिए आप हर तरह के ऐसे items बना सकते थे जो मूल रूप से मौजूद ही नहीं होने चाहिए थे, और official server भी उन्हें स्वीकार कर लेता था

  • मैंने हाल ही में MTGA के ज़रिए फिर से MTG खेलना शुरू किया। यह Unity game है और il2cpp नहीं है, इसलिए मैंने इसे जल्दी decompile करके देखा; और भले ही यह il2cpp होता, मुझे नहीं लगता कि वह बहुत सुरक्षा देता। कुछ काफ़ी दिलचस्प चीज़ें मिलीं
    जैसे Epic Launcher build के लिए keys और undocumented APIs। मेरा cheating में इस्तेमाल करने का इरादा नहीं है, बस काश combat log जैसी कोई चीज़ होती। जैसे कौन-सा match जीता या हारा, या खत्म हुए गेम का battlefield state फिर से देखने की सुविधा। मैं इस लेख को भी देखूँगा, और उम्मीद है इसे जल्दी patch कर दिया जाएगा

    • इस vulnerability को लेख लिखे जाने से पहले ही patch कर दिया गया था, और MTG को इसकी जानकारी दे दी गई थी
      अगर आप records देखना चाहते हैं, तो https://untapped.gg/en देख सकते हैं। मैंने वहाँ के लोगों से थोड़ा बात की है, और वह लगभग वही करता है जो आप चाहते हैं। ज़्यादातर जानकारी MTGA application directory में मौजूद MTG debug logs से ली जाती है, इसलिए चाहें तो आप अपना tracker भी बना सकते हैं। साइट पर यह भी समझाया गया है: https://help.hearthsim.net/en/articles/3620440-how-do-i-supp...
    • https://www.17lands.com/ limited games की win/loss statistics इकट्ठा करता है, और limited तथा constructed दोनों में turn-by-turn game records भी save करता है। मैं contributor रहा हूँ
    • play data collection के लिए https://mtgaassistant.net/ सबसे आम विकल्पों में से एक है, ऐसा मुझे लगता है
    • मेरी जानकारी में यह फ़ीचर पहले से मौजूद है। शायद यह player logs होगा
      मुझे याद है कि उस log का इस्तेमाल करके track करने वाले काफ़ी apps थे