Jest to klasyczny problem z grami i konkursami internetowymi. Twój kod Flash współpracuje z użytkownikami w celu ustalenia wyniku dla gry. Ale użytkownicy nie są zaufani, a kod Flash działa na komputerze użytkownika. Jesteś SOL. Nic nie możesz zrobić, aby uniemożliwić atakującemu osiągnięcie wysokich wyników:
Flash jest jeszcze łatwiejszy do inżynierii wstecznej, niż ci się wydaje, ponieważ kody bajtowe są dobrze udokumentowane i opisują język wysokiego poziomu (ActionScript) --- kiedy publikujesz grę Flash, publikujesz swój kod źródłowy, niezależnie od tego, czy wiem to czy nie.
Atakujący kontrolują pamięć wykonawczą interpretera Flash, dzięki czemu każdy, kto umie korzystać z programowalnego debuggera, może w dowolnej chwili zmienić dowolną zmienną (w tym bieżącą ocenę) lub sam program.
Najprostszym możliwym atakiem na Twój system jest uruchomienie ruchu HTTP do gry przez serwer proxy, przechwycenie zapisu o wysokim wyniku i odtworzenie go z wyższym wynikiem.
Możesz spróbować zablokować ten atak, wiążąc każdą zapisaną rekord z jednym wynikiem gry, na przykład wysyłając zaszyfrowany token do klienta podczas uruchamiania gry, który może wyglądać następująco:
hex-encoding( AES(secret-key-stored-only-on-server, timestamp, user-id, random-number))
(Możesz również użyć ciasteczka sesyjnego w tym samym celu).
Kod gry powtarza ten token z powrotem na serwer z zapisanym wynikiem. Ale atakujący nadal może po prostu ponownie uruchomić grę, zdobyć token, a następnie natychmiast wkleić ten token do odtworzonego rzutu wolnego.
Następnie podajesz nie tylko token lub sesyjny plik cookie, ale także klucz sesji szyfrujący najlepsze wyniki. Będzie to 128-bitowy klucz AES, który jest zaszyfrowany kluczem zapisanym na stałe w grze Flash:
hex-encoding( AES(key-hardcoded-in-flash-game, random-128-bit-key))
Teraz, zanim gra opublikuje najwyższy wynik, odszyfrowuje klucz sesji szyfrowania najlepszych wyników, co może zrobić, ponieważ zapisałeś klucz szyfrujący klucza sesji-szyfrowania w pliku binarnym Flash. Zaszyfrujesz najwyższy wynik za pomocą tego odszyfrowanego klucza wraz z skrótem SHA1 o wysokim wyniku:
hex-encoding( AES(random-128-bit-key-from-above, high-score, SHA1(high-score)))
Kod PHP na serwerze sprawdza token, aby upewnić się, że żądanie pochodzi z prawidłowej instancji gry, a następnie odszyfrowuje zaszyfrowany najlepszy wynik, sprawdzając, czy najlepszy wynik odpowiada SHA1 najwyższego wyniku (jeśli pominiesz ten krok , deszyfrowanie spowoduje po prostu losowe, prawdopodobnie bardzo wysokie, wysokie wyniki).
Więc teraz atakujący dekompiluje kod Flash i szybko znajduje kod AES, który wystaje jak obolały kciuk, chociaż nawet jeśli nie, zostałby wyśledzony w ciągu 15 minut za pomocą wyszukiwania pamięci i znacznika („Wiem mój wynik dla tej gry to 666, więc znajdźmy 666 w pamięci, a następnie złapmy każdą operację, która dotknie tej wartości --- och, spójrz, kod szyfrujący wysoki wynik! ”). Dzięki kluczowi sesji atakujący nie musi nawet uruchamiać kodu Flash; chwyta token uruchomienia gry i klucz sesji i może odesłać dowolny wynik.
Jesteś teraz w punkcie, w którym większość programistów po prostu się poddaje - daj lub weź kilka miesięcy na bałagan z atakującymi przez:
Mieszanie kluczy AES z operacjami XOR
Zastępowanie tablic bajtów klucza funkcjami obliczającymi klucz
Rozpraszanie fałszywych szyfrów kluczy i wpisów o wysokich wynikach w całym pliku binarnym.
To wszystko głównie strata czasu. Oczywiste jest, że SSL też ci nie pomoże; SSL nie może cię chronić, gdy jeden z dwóch punktów końcowych SSL jest zły.
Oto kilka rzeczy, które mogą faktycznie ograniczyć oszustwa o wysokim wyniku:
Wymagaj logowania, aby zagrać w grę, poproś o wygenerowanie pliku cookie sesji i nie zezwalaj na wiele zaległych uruchomień gry w tej samej sesji lub na wiele równoczesnych sesji dla tego samego użytkownika.
Odrzuć wysokie wyniki z sesji gier, które trwają krócej niż najkrótsze prawdziwe gry, w jakie kiedykolwiek grałeś (dla bardziej wyrafinowanego podejścia, spróbuj „poddać kwarantannie” wysokie wyniki dla sesji gier, które trwają mniej niż 2 standardowe odchylenia poniżej średniego czasu gry). Upewnij się, że śledzisz czas trwania gry na serwerze.
Odrzuć lub poddaj kwarantannie wysokie wyniki z logowań, w które grałeś tylko raz lub dwa razy, aby atakujący musieli stworzyć „papierową ścieżkę” rozsądnie wyglądającej rozgrywki dla każdego loginu, który utworzą.
„Heartbeat” zdobywa punkty podczas gry, dzięki czemu Twój serwer widzi wzrost wyniku w ciągu jednej gry. Odrzuć wysokie wyniki, które nie są zgodne z rozsądnymi krzywymi wyników (na przykład, skacząc z 0 do 999999).
Stan „Migawki” podczas gry (na przykład ilość amunicji, pozycja na poziomie itp.), Którą można później uzgodnić z zapisanymi wynikami tymczasowymi. Na początek nie musisz nawet wykrywać anomalii w tych danych; po prostu musisz go zebrać, a następnie możesz wrócić i przeanalizować, czy wszystko wygląda podejrzanie.
Wyłącz konto każdego użytkownika, który nie przejdzie jednego z twoich kontroli bezpieczeństwa (na przykład poprzez przesłanie zaszyfrowanego wysokiego wyniku, który nie przejdzie weryfikacji).
Pamiętaj jednak, że powstrzymujesz się jedynie od oszustw związanych z wysokim wynikiem. Tam nic nie można zrobić, aby zapobiec jeśli. Jeśli w twojej grze są pieniądze, ktoś pokona każdy system, który wymyślisz. Celem nie jest powstrzymanie tego ataku; ma sprawić, że atak będzie droższy niż tylko bycie naprawdę dobrym w grze i pokonanie go.