1 poin oleh GN⁺ 2023-12-06 | 1 komentar | Bagikan ke WhatsApp
  • Di Magic: The Gathering Arena, lawan bisa dipaksa menyerah pada waktu yang diinginkan, sehingga memungkinkan kondisi tidak pernah kalah dalam game matchmaking
  • Game kartu biasanya cocok dengan arsitektur server-authoritative yang mengelola seluruh state di server, tetapi lawan bot MTGA, Sparky, diimplementasikan dengan logika klien lokal
  • Klien MTGA berbasis C# dapat mengakses objek runtime dan field private lewat refleksi, dan nama seperti JoinMatch, ConnectAndJoinMatch, dan HeadlessClient ditemukan dalam kode yang didekompilasi
  • Dalam match bot, struktur yang digunakan memungkinkan koneksi ke kedua seat dengan PersonaID dan JWT dari akun yang sama; ini lalu diterapkan ke match biasa dengan menempelkan headless client ke seat lawan dan memanggil ConcedeGame()
  • Server kemudian ditambal agar dalam game matchmaking kedua seat tidak bisa memakai akun dan JWT yang sama, menjadikannya contoh bagaimana batas antara implementasi bot sisi klien dan verifikasi autentikasi seat berdampak langsung pada keamanan nyata

Mengapa meretas game kartu itu sulit

  • Game kartu berbasis giliran dan tidak banyak informasi yang bolak-balik antara klien dan server, sehingga sangat cocok untuk arsitektur server-authoritative
  • Server mengelola seluruh state permainan dan hanya mengirim informasi yang diperlukan ke klien
    • Informasi yang tidak dibuka, seperti kartu di tangan lawan atau isi deck, tidak ada di lokal
    • Upaya seperti mengubah urutan deck atau memanipulasi kartu yang akan diambil sulit dilakukan karena server yang mengeksekusi tindakan dan hanya memberi tahu hasilnya
  • Berbeda dengan first-person shooter, tindakan pemain dalam game kartu terbatas dan terjadi pada momen yang sudah ditentukan
    • Di FPS, informasi seperti posisi model musuh bisa lebih dulu di-cache di klien sehingga memungkinkan bentuk cheat seperti wallhack
    • Blog Riot tentang anti-wallhack membahas pendekatan untuk mengurangi data posisi pemain di sisi klien
  • Mendeteksi tindakan yang salah juga relatif lebih mudah
    • Memainkan kartu yang tidak ada di tangan
    • Bertindak saat bukan gilirannya

Titik awal analisis: jaringan dan klien C#

  • Sebagai titik awal peretasan game, dipilih pendekatan untuk melihat komunikasi jaringan
  • Presentasi DEF CON oleh Manfred yang membahas kasus peretasan MMO menunjukkan bahwa rekayasa balik protokol jaringan adalah inti dari analisis banyak bug
  • Karena MTGA ditulis dalam C#, objek bisa dimanipulasi saat runtime alih-alih meng-hook fungsi kirim-terima trafik
  • Assembly .NET yang tidak diobfuscate memungkinkan nama fungsi, variabel, dan kelas dilihat dalam bentuk yang bisa dibaca manusia berkat metadata token
    • Karena itu, hasil dekompilasinya nyaris setara dengan review source code

Struktur Sparky yang ditemukan dari JoinMatch

  • Saat mencari inisialisasi masuk match, ditemukan fungsi JoinMatch setelah menelusuri nama fungsi terkait
  • JoinMatch adalah fungsi panjang lebih dari 200 baris, dan di bagian bawah terlihat pemanggilan ConnectAndJoinMatch
    • Fungsi ini tampak sebagai alur yang menerima informasi konfigurasi match lalu terhubung ke server game
  • Dalam alur kode yang sama juga ada percabangan MatchType.NPE dan MatchType.Familiar
    • NPE diduga merupakan match tutorial untuk pengalaman pemain baru
    • Familiar adalah match bot standar
  • Logika yang dipanggil dalam percabangan ini terhubung ke lawan bot MTGA, Sparky
    • Sparky adalah lawan bergaya maskot MTGA yang digunakan dalam tutorial dan pertandingan melawan bot
    • Dalam match bot, logika bot berjalan di dalam klien game pada mesin lokal

Bot lokal dan HeadlessClient

  • Handler logika inti bot berada di dalam kelas HeadlessClient
  • HeadlessClient adalah headless client yang tidak merender game board, tetapi tetap terhubung ke server dan memainkan game
  • Klien bot yang dibuat secara lokal menggunakan informasi autentikasi pengguna yang sama dengan klien game
    • PersonaID yang berperan sebagai ID pengguna
    • JSON web token yang diberikan ke game setelah login
  • Dalam match bot, strukturnya membuat server tidak menganggap bermasalah jika klien yang sama pada dasarnya terhubung ke kedua sisi match
  • Seat digunakan untuk membedakan siapa pemainnya di dalam game
    • Dalam match bot, dimungkinkan mengisi seat yang berbeda dengan informasi autentikasi yang sama

Cara mengambil alih match biasa

  • Logika match bot diterapkan ke match biasa untuk menguji apakah bisa terhubung ke kedua seat
  • Informasi yang diperlukan diambil dari objek game saat runtime
    • konfigurasi match saat ini
    • host dan port server match
    • controllerFabricUri
    • matchId
    • PersonaID
    • Jwt
    • database kartu
    • manajer match
    • sistem pencarian aset
  • Seat lawan dihitung berdasarkan seat milik sendiri
    • Dalam kode, seat lainnya didapatkan dengan man.LocalPlayerSeatId % 2U + 1U
  • UnityFamiliar.SpawnFamiliar_DEBUG(...) digunakan untuk menghubungkan bot ke seat lawan
  • Setelah menemukan objek UnityFamiliar yang dibuat, dipanggil cheatbot.Client.Gre.ConcedeGame() agar langsung menyerah

Hasil dan patch

  • Cara ini juga bekerja dalam match biasa
    • Bahkan tetap berfungsi saat lawan sudah terhubung dan game sedang berlangsung
    • Karena ini adalah game matchmaking, hadiah tetap diberikan seolah-olah mengalahkan lawan manusia
  • Inti kerentanannya adalah server match biasa mengizinkan koneksi ke kedua seat dengan akun dan JWT yang sama
  • Server kemudian ditambal agar dalam game matchmaking kedua seat tidak bisa menggunakan akun dan JWT yang sama
  • Kode InstaWin di lampiran adalah MonoBehaviour Unity yang membuat tombol GUI; saat tombol diklik, ia mengumpulkan informasi match saat ini, menempelkan bot ke seat lawan, lalu memaksanya menyerah

1 komentar

 
GN⁺ 2023-12-06
Komentar Hacker News
  • Hal yang pertama kali membuat saya benar-benar mendalami Linux adalah memakai ShowEQ untuk EverQuest guna mengintip traffic jaringan
    Saat itu traffic belum dienkripsi dan berisi banyak informasi berguna. Dengan hub, traffic diduplikasi ke mesin Linux untuk menggambar peta zona secara real-time, menampilkan posisi monster, NPC, dan pengguna, bahkan menunjukkan loot yang dibawa monster sehingga bisa memilih monster tertentu saja untuk diburu. Kelebihannya, karena caranya pasif, tidak bisa dideteksi; pada akhirnya SOE mengetahuinya dan mulai mengenkripsi traffic

    • Data pada akhirnya harus didekripsi agar bisa dibaca, jadi orang pun merekayasa balik klien untuk menemukan cara dekripsi real-time
      Lalu pihak lawan memperkenalkan tanda tangan berbasis kunci, orang kembali mencoba mencuri kunci dari klien dan memecahkan enkripsi, dan setelah sistem anti-cheat masuk, dimulailah permainan kucing dan tikus
    • Saat remaja saya juga pernah mencoba hal serupa di Dark Age of Camelot, dan itu sangat berguna untuk belajar network sniffing, perbedaan hub dan switch, serta Linux
      Apakah itu cukup bernilai untuk mendapat keuntungan dalam game? Tidak. Saya tidak bermain dengan serius, jadi saya menghabiskan 2 minggu untuk instalasi dan hanya memakainya sekitar 1 minggu, tetapi sebagai pengalaman belajar itu luar biasa
    • Saya ingat ShowEQ dipakai untuk membuktikan berbagai teori dan bug yang terus disangkal Verant/Sony
      Contohnya keberadaan hell level, fakta bahwa bukan manusia melainkan halfling yang mendapat bonus pengalaman dan bahwa memang ada perbedaan pengalaman berdasarkan ras/kelas, serta fakta bahwa alchemy Shaman awal benar-benar rusak. Dan saya rasa ini kemudian mengarah ke eqemulator.org
    • Saya penasaran bagaimana enkripsi bisa membantu. Klien pada akhirnya tetap harus mendekripsinya, jadi bukankah tinggal menumpang di situ?
    • ShowEQ masih berfungsi, dan ada juga MySEQ berbasis Windows yang membaca memori
      Pemilik EQ saat ini tampaknya tidak terlalu peduli, jadi relatif aman untuk dipakai. Namun, kecuali perlengkapan yang terlihat, kedua aplikasi itu tidak pernah menampilkan loot yang dibawa monster. Seiring waktu sebagian data juga berubah; dulu health monster yang akurat dikirim, tetapi sekarang hanya persentasenya
  • Saya kurang memahami bagian “bot yang hampir lengkap dan bisa memainkan game arbitrer Magic: The Gathering cukup kecil untuk berjalan di mesin lokal”
    Kalau AI MTG terlalu berat untuk dijalankan di mesin pelanggan, saya rasa mereka juga tidak akan menjalankannya di server. Pertandingan bot dalam game kartu biasanya tidak ditagih per partai, jadi biayanya bisa besar. Server juga bukan sihir; kebanyakan memakai CPU x86 yang sama seperti mesin lokal, dan clock-nya sering kali lebih rendah daripada desktop. Untuk mengurangi waktu giliran bot dibanding lokal, mereka harus memakai jauh lebih banyak core daripada pelanggan; kalau 8–16 core teralokasi per pemain, itu terdengar seperti mimpi buruk saat puncak pengguna bersamaan. Kalau pemain CPU tidak mendukung multicore, eksekusi lokal bagaimanapun seharusnya lebih cepat

    • Yang dimaksud di sini bukan performa pemrosesan, melainkan penggunaan memori
      Maksudnya, rules engine bot cukup kecil untuk muat di memori iPhone atau perangkat Android lama. Di server, mereka bisa menaruh banyak state machine atau rules engine di memori, dan mungkin hampir tidak memakai performa pemrosesan untuk menjalankan permintaan tertentu
    • Kalau desktop, itu benar, tetapi perlu diingat juga bahwa MTGA berjalan di ponsel
    • MTG adalah game dengan sistem aturan yang sangat kompleks
  • Daniel, sekali lagi selamat karena tulisannya masuk peringkat atas. Setelah tulisan ini muncul, saya mencoba meretas MTGA dan sedikit berdiskusi juga di GitHub [0]
    Untuk yang tertarik, saat ini saya sedang mengerjakan secara tidak aktif klien MTGA tidak resmi yang hampir belum punya fitur. Tujuannya adalah mengotomatiskan permainan ranked dan menyediakan lawan bot yang lebih kuat. Belakangan tersisih oleh pekerjaan lain, dan saya juga masih belum punya gambaran bagaimana membuat UI yang bagus dan mudah dilihat, jadi sulit menebak kapan bahkan versi minimal yang berguna akan tersedia. Selain itu, saya tetap ingin mendengar lebih banyak cerita Daniel atau orang lain tentang hacking game. Saya ingin mendengar lebih banyak tentang bagaimana bug seperti ini ditemukan, bagaimana tidak khawatir kena ban setelah hacking, cara mengungkap bug seperti yang disebut @aethros, dan bagaimana menyusun klien game kartu tidak resmi
    [0] https://github.com/MayerDaniel/mayerdaniel.github.io/issues/...

  • Mengatakan bahwa perkiraan overhead untuk membuat lawan AI di game sekompleks MTG akan besar itu cukup meremehkan
    Game ini hampir Turing-complete, dan bahkan jika loop tak terbatas dikecualikan, orang-orang banyak bermain-main dengannya. Meski begitu, riset di sisi strategi AI sepertinya sudah banyak dilakukan. Dan karena ini tulisan yang diunggah langsung oleh penulisnya, sepertinya judulnya boleh diberi “Show HN:”

    • Show HN ditujukan untuk proyek yang bisa dicoba langsung oleh orang, bukan tulisan blog: https://news.ycombinator.com/showhn.html
    • Pernyataan “bisa mengenkode mesin Turing dengan game” sama sekali tidak sama dengan “sulit menulis program yang bisa melakukan tindakan legal di semua situasi”
      Yang sulit bagi penulis bot tampaknya adalah yang kedua
    • Memang benar Turing-complete: https://arxiv.org/abs/1904.09828
    • Set baru terus berotasi sehingga game terus berubah, tetapi setahu saya dalam interaksi tertentu bisa dibuat loop tak terbatas, atau pernah bisa pada beberapa titik
      Misalnya membuat dan membunuh creature token dengan efek masuk/keluar/untap. Loop seperti ini juga tidak selalu merugikan salah satu pihak
    • Saya penasaran apakah ada strategi nyata yang mendekati kompleksitas ini
      Saya belum pernah memainkan MTG, tetapi klaim ini terdengar seperti secara teknis mungkin jika sengaja membuat struktur yang memiliki state, bukan untuk tujuan menang
  • Bermain Old School Magic 93/94 dengan kartu fisik bersama anak saya benar-benar menyenangkan
    Setiap tahun kami pergi ke Madrid untuk ikut Kejuaraan Dunia 7pts Singleton. Musim panas ini anak saya menempati peringkat ke-9, dan saya sangat bangga. 7pts Singleton adalah format yang bagus karena memungkinkan beragam susunan deck dan menawarkan gameplay yang seimbang dengan biaya yang relatif tidak membebani (https://7pts-singleton.com)

    • Sulit menyebut format yang melegalkan Black Lotus, Ancestral Recall, dan Moxen sebagai murah
      Meski di 7pts Singleton tidak bisa memakai semuanya, satu saja harganya bisa ribuan hingga puluhan ribu dolar. Tapi tetap menyenangkan bisa menikmati game bersama anak, dan selamat juga karena masuk peringkat atas
  • Logika game murni di sisi klien, ya. Dulu saat membuat game kecil, ada kalanya saya harus menaruh logika game di klien demi responsivitas, tetapi tidak ada larangan untuk menjalankan ulang logika yang sama di server, jadi itulah yang saya lakukan
    Untuk game real-time seperti FPS atau RTS mungkin sulit, tetapi untuk game kartu tidak ada alasan. Untuk game kartu seperti ini, semestinya klien tidak dikirimi informasi di luar yang benar-benar bisa dilihat pemain. Misalnya, jangan kirim isi kartu di tangan lawan, cukup jumlah kartunya saja. Aksi yang dikirim ke server juga seharusnya hanya tentang diri sendiri, jadi tidak boleh bisa mendeklarasikan lawan menyerah. Kalau saya berkata “menyerah!”, server harus menafsirkannya sebagai saya yang menyerah

    • Dari artikelnya, bisa dianggap game memang ditulis dengan cara seperti itu. Hanya menerima informasi yang dibutuhkan pada saat dibutuhkan, dan hanya mengirim aksi milik sendiri
      Celahnya adalah bisa menjalankan klien kedua dan masuk ke game yang sedang berlangsung sebagai kursi lawan. Setelah itu, aksi lawan, termasuk menyerah, bisa dikirim
    • Seperti yang jelas tertulis di artikel, gameplay seluruhnya diproses di sisi server
      Yang dimanfaatkan penulis bukanlah logika game di sisi klien, melainkan masalah pada otorisasi dan kode untuk bergabung ke game. Pernyataan “seharusnya tidak bisa mendeklarasikan menyerah atas nama lawan” pada dasarnya hanya mengulang persis bagaimana exploit yang ditemukan penulis bekerja
    • Sepertiga awal artikel secara eksplisit mengatakan bahwa game diimplementasikan seperti itu
  • Di League of Legends pernah ada bug pembagian dengan nol pada kombinasi champion dan item tertentu, yang membuat server mengeluarkan semua pemain lalu crash
    Karena pelaku exploit dikeluarkan paling akhir, timnya dihitung menang, sementara tim lawan mendapat Loss Prevented alih-alih hasil normal

    • Kalau lawan tidak menerima hasil normal berupa kekalahan, tim yang menang juga seharusnya tidak mendapat kemenangan
  • Artikel ini enak diikuti dan punya detail yang bernas
    Namun saya tidak paham soal menghubungkan bot saat pertandingan berlangsung. Mengapa game mengizinkan masuk di tengah pertandingan, dan mengapa ketika bot menyerah itu diproses sebagai lawan yang menyerah? Kalau yang dibuat adalah game 3 pemain, pemain ke-3 yang menyerah seharusnya tidak membuat pemain ke-2 ikut menyerah

    • Itu tidak menjadi game 3 pemain, melainkan tetap game 2 pemain
      Kodenya mencari tahu indeks kursi akun saya, lalu memasukkan bot ke indeks kursi yang lain. Masalahnya adalah tidak ada verifikasi bahwa pengguna yang bergabung memang pengguna yang benar untuk kursi tersebut. Bisa saja terpikir bahwa kursi yang sudah terhubung tidak boleh diakses lagi, tetapi untuk game yang juga mendukung mobile, Anda mungkin ingin timeout putus koneksi cukup panjang. Sebab Anda tidak ingin memblokir pemain yang sempat terputus lalu menyambung kembali sebelum timeout menyadari koneksi sebelumnya sudah mati. Saya juga pernah melihat di game lain, saat mencoba reconnect muncul pesan “tidak bisa bergabung ke game yang sedang berlangsung” sekitar 10 detik, baru kemudian bisa reconnect. Analogi kasarnya, seseorang datang ke turnamen MTG di toko kartu lokal, mendorong orang lain dari kursinya, duduk, lalu berteriak “Saya menyerah!”, dan juri mengakui pemain B drop karena orang yang duduk di kursi itu yang menyatakan demikian
      1. Kemungkinan besar ini cara menangani reconnect setelah putus koneksi. Koneksi lama diakhiri
      2. Bot menggantikan pemain 2 lalu mengirim aksi menyerah, dan server mencatatnya sebagai pemain 2 menyerah
    • MTG: Arena tidak mengizinkan game 3 pemain, jadi bot menyusup ke kursi lawan
      Karena itu tampaknya ia bisa menyerah atas nama lawan. Para developer mungkin tidak membayangkan ada orang yang punya alasan untuk mencoba hal seperti itu, sehingga tidak menambahkan pemeriksaan
  • Ini mengingatkan saya pada masa Diablo 2, ketika paket koneksi yang sama bisa digunakan ulang untuk menghubungkan karakter server terbuka (LAN) ke server internet bnet resmi
    Karena seluruh data server terbuka disimpan lokal, kita bisa membuat segala macam item yang seharusnya tidak ada, dan server resmi pun menerimanya

  • Baru-baru ini saya kembali masuk ke MTG lewat MTGA. Karena ini game Unity dan bukan il2cpp, saya cepat-cepat mendekompilasinya; sekalipun il2cpp, sepertinya itu juga bukan perlindungan besar, dan saya menemukan beberapa hal yang cukup menarik
    Ada hal-hal seperti key untuk build Epic Launcher dan API yang tidak terdokumentasi. Saya tidak ingin memakainya untuk curang; saya hanya ingin ada riwayat pertandingan. Misalnya fitur untuk melihat match mana yang menang atau kalah, serta meninjau kembali keadaan board pada game yang sudah selesai. Saya juga akan mengecek artikel ini, dan semoga cepat ditambal

    • Kerentanan ini sudah ditambal sebelum artikelnya ditulis, dan sudah diungkapkan ke MTG
      Kalau ingin melihat riwayat, coba cek https://untapped.gg/en. Saya sempat sedikit berbicara dengan mereka, dan pada dasarnya layanan itu melakukan hal yang Anda inginkan. Sebagian besar informasinya diambil dari log debug MTG yang ada di direktori aplikasi MTGA, jadi jika mau Anda juga bisa membuat tracker sendiri. Situsnya juga menjelaskan ini: https://help.hearthsim.net/en/articles/3620440-how-do-i-supp...
    • https://www.17lands.com/ mengumpulkan statistik menang-kalah untuk game Limited, dan juga menyimpan riwayat game per giliran untuk Limited maupun Constructed. Saya ikut berkontribusi di sana
    • Untuk pengumpulan data permainan, setahu saya https://mtgaassistant.net/ termasuk yang paling umum dipakai
    • Setahu saya fitur ini sudah ada. Kemungkinan besar namanya player log
      Saya ingat ada cukup banyak aplikasi yang memakai log itu untuk pelacakan