- Magic: The Gathering Arena’da rakibi istenen anda teslim olmuş saydırmak mümkün olduğundan, eşleştirme oyunlarında kaybetmeyen bir durum oluşturulabiliyordu
- Kart oyunları genelde sunucunun tüm durumu yönettiği sunucu otoriteli mimariye uygundur; ancak MTGA’daki bot rakip Sparky, yerel istemci mantığıyla uygulanmıştı
- C# tabanlı MTGA istemcisinde reflection ile çalışma zamanındaki nesnelere ve private alanlara erişilebiliyordu; decompile edilmiş kodda
JoinMatch,ConnectAndJoinMatch,HeadlessClientgibi adlar görüldü - Bot maçlarında aynı hesabın
PersonaIDdeğeri ve JWT ile iki koltuğa da bağlanılan bir yapı kullanılıyordu; bu genel maçlara uygulanarak rakibin koltuğuna headless istemci bağlanıpConcedeGame()çağrılabiliyordu - Sunucu daha sonra eşleştirme oyunlarında iki koltuğun aynı hesabı ve JWT’yi kullanamaması için yamalandı; bu, istemci taraflı bot uygulaması ile koltuk kimlik doğrulama denetiminin sınırının gerçek güvenliği doğrudan etkilediği bir örnek oldu
Kart oyunlarını hacklemenin neden zor olduğu
- Kart oyunları sıra tabanlıdır ve istemci ile sunucu arasında gidip gelen bilgi fazla olmadığından sunucu otoriteli mimariye iyi uyar
- Sunucunun tüm oyun durumunu yönetip istemciye yalnızca gerekli bilgileri iletmesi yeterlidir
- Rakibin eli veya destesi gibi açık olmayan bilgiler yerelde bulunmaz
- Deste sırasını değiştirmek ya da çekilecek kartı manipüle etmek gibi girişimler zordur; çünkü eylemi sunucu gerçekleştirir ve yalnızca sonucu bildirir
- Birinci şahıs nişancı oyunlarının aksine kart oyunlarında oyuncu eylemleri sınırlıdır ve belirli anlarda gerçekleşir
- FPS’lerde düşman modeli konumu gibi bilgiler istemcide önceden cache’lenebildiği için wallhack gibi biçimler mümkün olabilir
- Riot’un anti-wallhack blog yazısı, istemci tarafındaki oyuncu konumu verilerini azaltma yaklaşımını ele alıyor
- Hatalı eylemleri tespit etmek de görece kolaydır
- Elde olmayan bir kartı oynamak
- Kendi sırası değilken eylem yapmak
Analizin başlangıç noktası: ağ ve C# istemcisi
- Oyun hacklemenin başlangıç noktası olarak ağ iletişimini inceleme yaklaşımı seçildi
- MMO hackleme örneklerini ele alan Manfred’in DEF CON sunumu, ağ protokolü tersine mühendisliğinin birçok hata analizinin merkezinde olduğunu gösteriyor
- MTGA C# ile yazıldığı için, trafik gönderme/alma fonksiyonlarını hook’lamak yerine çalışma zamanında nesneler manipüle edilebiliyordu
- .NET reflection ile private alanlara ve metotlara da erişmek mümkündür
- İlgili temel örnek olarak Unity oyunlarında reflection ile hackleme öğreticisi bağlantısı veriliyor
- Obfuscate edilmemiş .NET assembly’leri, metadata token sayesinde fonksiyon, değişken ve sınıf adlarının insan tarafından okunabilir biçimde görülmesini sağlar
- Bu nedenle decompile sonucu fiilen kaynak kod incelemesine yakın hale gelir
JoinMatch içinde bulunan Sparky yapısı
- Maça katılım başlatmasını bulmak için ilgili fonksiyon adları aranırken
JoinMatchfonksiyonu bulundu JoinMatch200 satırı aşan uzun bir fonksiyondu ve alt kısmındaConnectAndJoinMatchçağrısı görüldü- Bu fonksiyon, maç ayar bilgilerini alıp oyun sunucusuna bağlanma akışı gibi görünüyordu
- Aynı kod akışında
MatchType.NPEveMatchType.Familiardalları vardıNPE, yeni oyuncu deneyimi olduğu tahmin edilen eğitim serisi maçlarıFamiliar, standart bot maçı
- Bu dallarda çağrılan mantık, MTGA’nın bot rakibi Sparky ile bağlantılıydı
- Sparky, eğitimlerde ve bot karşılaşmalarında kullanılan MTGA’nın maskot benzeri rakibidir
- Bot maçlarında bot mantığı, yerel makinedeki oyun istemcisinin içinde çalışır
Yerel bot ve HeadlessClient
- Botun gerçek mantık işleyicisi
HeadlessClientsınıfının içindeydi HeadlessClient, oyun tahtasını render etmeyen bir headless istemcidir; sunucuya bağlanıp oyunu yürütür- Yerelde oluşturulan bot istemcisi, oyun istemcisiyle aynı kullanıcı kimlik doğrulama bilgilerini kullanır
- Kullanıcı kimliği rolündeki
PersonaID - Girişten sonra oyuna verilen JSON web token
- Kullanıcı kimliği rolündeki
- Bot maçlarında aynı istemcinin fiilen maçın iki tarafına da bağlanmasını sunucu sorun olarak görmeyen bir yapı vardı
- Koltuk (seat), oyunda hangi oyuncu olunduğunu ayırt etmek için kullanılır
- Bot maçlarında aynı kimlik doğrulama bilgileriyle farklı koltukları dolduran bir yapılandırma mümkündü
Normal maçı ele geçirme yöntemi
- Bot maçı mantığının normal maçlara uygulanıp iki koltuğa da bağlanmanın mümkün olup olmadığı test edildi
- Gerekli bilgiler çalışma zamanındaki oyun nesnesinden alındı
- Mevcut maç ayarları
- Maç sunucusu host’u ve port’u
controllerFabricUrimatchIdPersonaIDJwt- Kart veritabanı
- Maç yöneticisi
- Varlık sorgulama sistemi
- Kendi koltuğu temel alınarak rakibin koltuğu hesaplandı
- Kodda diğer koltuk
man.LocalPlayerSeatId % 2U + 1Uile elde ediliyor
- Kodda diğer koltuk
UnityFamiliar.SpawnFamiliar_DEBUG(...)ile rakibin koltuğuna bot bağlandı- Oluşturulan
UnityFamiliarnesnesi bulunupcheatbot.Client.Gre.ConcedeGame()çağrılarak anında teslim olması sağlandı
Sonuç ve yama
- Bu yöntem normal maçlarda da çalıştı
- Rakip zaten bağlıyken ve oyun devam ederken bile çalışıyordu
- Eşleştirme oyunu olduğu için insan rakibi yenmiş gibi ödül alındı
- Açığın özü, normal maç sunucusunun aynı hesap ve JWT ile iki koltuğa da bağlanılan duruma izin vermesiydi
- Sunucu daha sonra eşleştirme oyunlarında iki koltuğun aynı hesabı ve JWT’yi kullanamaması için yamalandı
- Ekteki
InstaWinkodu, UnityMonoBehaviourile GUI düğmesi oluşturup düğmeye tıklandığında mevcut maç bilgilerini toplayarak botu rakibin koltuğuna bağlayan ve teslim ettiren akışı içeriyor
1 yorum
Hacker News görüşleri
Linux’u ilk kez gerçekten derinlemesine kurcalamama vesile olan şey, EverQuest için ShowEQ ile ağ trafiğini incelemekti
O dönemde trafik şifrelenmemişti ve içinde çok faydalı bilgiler vardı. Trafiği bir hub üzerinden Linux makinesine kopyalayıp bölgenin gerçek zamanlı haritasını çiziyor, canavarların, NPC’lerin ve oyuncuların konumlarını gösteriyor, hatta canavarların taşıdığı ganimetleri bile göstererek sadece belirli canavarları hedeflemeyi mümkün kılıyordu. Elle yapılan bir yöntem olduğu için tespit edilememesi avantajdı; sonunda SOE bunu fark edip trafiği şifrelemeye başladı
Sonra karşı taraf anahtar tabanlı imza ekliyor, siz yeniden istemciden anahtarı çalmaya çalışıyor, şifrelemeyi kırıyor ve ardından hile önleme sistemleri devreye girince kedi-fare oyunu başlıyor
Oyunda avantaj sağlamak açısından değdi mi? Hayır. Zaten ciddi oynamıyordum; kuruluma 2 hafta harcayıp yaklaşık 1 hafta kullanmıştım, ama öğrenme deneyimi olarak harikaydı
Örneğin hell level’ın varlığı, deneyim bonusunu insanların değil halfling’lerin aldığı ve gerçekten ırk/sınıf bazlı deneyim farkları olduğu, ilk dönem Shaman alchemy sisteminin gerçekten bozuk olduğu gibi şeyler. Ve sanırım bu iş sonradan eqemulator.org’a da uzanmıştı
Mevcut EQ sahibinin buna pek aldırmadığı anlaşılıyor, bu yüzden kullanmak genelde sorun olmuyor. Yine de iki uygulama da, görünen ekipman dışında, canavarların taşıdığı ganimetleri hiç göstermedi. Zamanla bazı veriler de değişti; eskiden tam canavar canı gönderilirken artık sadece yüzde bilgisi gönderiliyor
“Magic: The Gathering için rastgele oyunları oynayabilen neredeyse tam bir botun yerel makinede çalışabilecek kadar küçük olması” kısmını pek anlamadım
Eğer MTG yapay zekası istemci makinesinde çalıştırılamayacak kadar ağırsa, sunucuda da çalıştırılmaz gibi geliyor. Kart oyunu bot maçları genelde maç başına ücretlendirilen bir şey değil, dolayısıyla maliyet büyür. Sunucular da sihirli değil; çoğu, yerel makineyle aynı x86 CPU’ları kullanıyor ve çoğu zaman masaüstünden daha düşük saat hızına sahip oluyor. Yerele göre bot tur süresini düşürmek istiyorsanız, oyuncunun makinesinden çok daha fazla çekirdek kullanmanız gerekir; oyuncu başına 8–16 ayrılmış çekirdek, eşzamanlı oyuncu zirvesinde kabus gibi olurdu. CPU oyuncusu çok çekirdeği desteklemiyorsa, yerelde çalışması zaten daha hızlı olmalı
Yani botun kural motorunun eski iPhone veya Android cihazların belleğine sığabilecek kadar küçük olması. Sunucuda ise durum makinelerini veya kural motorlarını bellekte bolca tutabilirsiniz; hatta belirli bir isteği çalıştırmak için neredeyse hiç işlem gücü gerekmeyebilir
Daniel, bir kez daha ana sayfa gönderin için tebrikler. Bu yazı çıktıktan sonra ben de MTGA’yı hacklemeyi denedim ve GitHub’da biraz bahsettim [0]
İlgilenenler için söyleyeyim, şu anda neredeyse işlevsiz bir MTGA gayriresmî istemcisi üzerinde düşük tempoda çalışıyorum. Amaç, sıralamalı oyun oynamayı otomatikleştirmek ve daha güçlü bir bot rakip sunmak. Son zamanlarda başka işler yüzünden geri planda kaldı; ayrıca net görülebilen iyi bir UI’ı nasıl yapacağım konusunda da hâlâ kafam karışık, bu yüzden en azından işe yarar hâle ne zaman geleceğini tahmin etmek bile zor. Bunun dışında Daniel’in ya da başkalarının oyun hackleme hikâyelerini duymaya devam etmek isterim. Bu tür bug’ları nasıl buldukları, hackledikten sonra ban konusunda neden kaygılanmadıkları, @aethros’un söylediği gibi bug’ları açıklama yöntemleri ve gayriresmî kart oyunu istemcilerini nasıl yapılandırdıkları gibi şeyleri daha çok duymak isterim
[0] https://github.com/MayerDaniel/mayerdaniel.github.io/issues/...
MTG gibi karmaşık bir oyunda yapay zeka rakip yapmanın ek yükünün büyük olacağını düşünmek bile aslında epey büyük bir küçümseme
Çünkü oyun neredeyse Turing-complete ve insanlar, sonsuz döngüler hariç tutulsa bile, bununla çok eğleniyor. Yine de yapay zeka stratejisi tarafında muhtemelen zaten çok çalışma yapılmıştır. Ayrıca bu gönderi doğrudan yazarın kendi yazısı olduğuna göre, başlıkta “Show HN:” olması da makul görünüyor
Botu yazan kişi için zor olanın ikincisi olduğu anlaşılıyor
Örneğin oyuna giriş/çıkış/untap etkileriyle token yaratık üretip öldürmek gibi. Bu tür döngüler her zaman taraflardan birine hasar vermek zorunda da değil
MTG’yi hiç oynamadım ama bu iddia, kazanma amacıyla değil de özellikle durum taşıyan bir yapı kurarsanız teknik olarak mümkün olduğu anlamına geliyor gibi görünüyor
Oğlumla birlikte fiziksel kartlarla old-school Magic 93/94 oynamaktan gerçekten keyif alıyorum
Her yıl Madrid'e gidip 7pts Singleton dünya şampiyonasına katılıyoruz. Bu yaz oğlum 9. oldu ve bununla çok gurur duyuyorum. 7pts Singleton, çok çeşitli deste kurulumlarına izin veren ve nispeten makul bir maliyetle dengeli bir oynanış sunan harika bir format (https://7pts-singleton.com)
7pts Singleton'da hepsini kullanamasanız bile bunlardan tek biri bile birkaç bin ila on binlerce dolara mal oluyor. Yine de oğlunuzla oyunun keyfini çıkarmanız güzel, dereceye girmesini de tebrik ederim
Oyun mantığının tamamen istemci tarafında olması şaşırtıcı. Eskiden küçük oyunlar yaparken tepkisellik için oyun mantığını istemciye koymam gereken zamanlar olmuştu, ama sunucuda aynı mantığı tekrar çalıştırmamak için hiçbir sebep yoktu, ben de öyle yapmıştım
FPS ya da RTS gibi gerçek zamanlı oyunlarda bu zor olabilir ama kart oyunlarında bunun bahanesi yok. Böyle bir kart oyununda istemciye gerçek oyuncunun görebileceğinden fazlasını göndermemek gerekir. Örneğin rakibin elindeki kartların içeriğini göndermek yerine sadece kart sayısını göndermelisiniz. Sunucuya gönderilen eylemler de yalnızca kişinin kendisiyle ilgili olmalı; dolayısıyla rakibin teslim olduğunu ilan edebilmeniz mümkün olmamalı. “Teslim oluyorum!” derseniz, sunucu bunu benim teslim oluşum olarak yorumlamalı
Açık, ikinci bir istemci başlatıp o an devam eden oyuna rakip koltuğundan bağlanabilmenizdi. Bunu yaptıktan sonra teslim olma dahil rakibin eylemlerini gönderebiliyordunuz
Yazarın istismar ettiği şey istemci tarafı oyun mantığı değil, yetkilendirme ve oyuna bağlanma kodundaki bir sorundu. “Rakip adına teslimiyet ilan edememelisiniz” demek, yazarın bulduğu açığın nasıl çalıştığını sadece tekrar etmekten ibaret
League of Legends'ta belirli şampiyon ve eşya kombinasyonlarında bir sıfıra bölme hatası vardı; bu da sunucunun tüm oyuncuları oyundan atıp çökmesine yol açıyordu
Kötüye kullanan oyuncu en son atıldığı için onun takımı galibiyet alıyor, karşı takım ise normal sonuç yerine Loss Prevented alıyordu
Bu yazı hem kolay okunuyor hem de içgörülü ayrıntılar içeriyor
Yine de gerçek bir maç sırasında bota bağlanılması kısmını anlamıyorum. Oyun neden maç ortasında katılıma izin veriyor ve bot teslim olduğunda bu neden rakibin teslim olması olarak işleniyor? 3 oyunculu bir oyun yapsanız bile 3. oyuncu teslim olunca 2. oyuncu da teslim olmuş sayılmamalı
Kod, hesabımın koltuk indeksini öğrenip botu diğer koltuk indeksine katıyor. Sorun, katılan kullanıcının o koltukta bulunması gereken doğru kullanıcı olup olmadığının doğrulanmaması. Zaten bağlı olan bir koltuğa tekrar bağlanılmasına izin verilmemesi gerektiği düşünülebilir, ama oyun mobil de destekliyorsa bağlantı kopması zaman aşımını epey uzun tutmak isteyebilirsiniz. Kısa süreliğine kopup zaman aşımı önceki bağlantının öldüğünü anlamadan yeniden bağlanan oyuncuyu engellemek istemezsiniz. Başka oyunlarda da yeniden bağlanmaya çalışınca yaklaşık 10 saniye boyunca “devam eden oyuna katılamaz” yazdığını, sonra ancak yeniden bağlandığını gördüm. Benzetmek gerekirse, mahalledeki kart dükkânındaki bir MTG turnuvasına gidip birini sandalyesinden iterek oturuyor ve “Teslim oluyorum!” diye bağırıyorsunuz; hakem de sandalyede oturan kişi bunu ilan ettiğine göre oyuncu B çekildi diye kabul ediyor
Bu yüzden rakip adına teslim olabiliyordu gibi görünüyor. Geliştiriciler muhtemelen kimsenin özellikle böyle bir şey deneyeceğini düşünmediği için bunu kontrol etmedi
Diablo 2 döneminde, aynı giriş paketini yeniden kullanarak open server karakterlerini (LAN) resmi bnet internet sunucularına bağlamanın mümkün olduğu zamanları hatırlattı
Open server verileri tamamen yerelde tutulduğu için normalde var olmaması gereken her türlü eşyayı oluşturabiliyor ve resmi sunucu da bunları kabul ediyordu
Kısa süre önce MTGA sayesinde MTG'ye geri döndüm. Unity oyunu ve il2cpp değil, bu yüzden hızlıca decompile ettim; il2cpp olsaydı bile pek koruma sağlayacağını sanmıyorum ve oldukça ilginç şeyler buldum
Epic Launcher derlemesi için anahtarlar ve belgelenmemiş API'ler gibi şeyler vardı. Hile yapmak istemiyorum, sadece bir savaş günlüğü olmasını isterdim. Hangi maçları kazanıp kaybettiğimi ve bitmiş oyunların masa durumunu tekrar görme gibi şeyler. Bu yazıya da bakacağım, umarım çabuk yamalanır
Kayıtlara bakmak istiyorsanız https://untapped.gg/en adresine göz atabilirsiniz. Onlarla biraz konuşmuştum; pratikte istediğiniz şeyi yapıyor. Bilgilerin çoğunu MTGA uygulama dizinindeki MTG debug log'undan alıyorlar, dolayısıyla isterseniz kendi takip aracınızı da yapabilirsiniz. Sitede de bu anlatılıyor: https://help.hearthsim.net/en/articles/3620440-how-do-i-supp...
O logu kullanarak takip yapan epey uygulama olduğunu hatırlıyorum