Zapobiegaj oszukiwaniu w trybie wieloosobowym

10

Już prawie ukończę tworzenie małej gry wieloosobowej w stylu indie. Chociaż zamierzam pozwolić ludziom oszukiwać w trybie dla jednego gracza, jest to oczywiście niedopuszczalne w trybie dla wielu graczy. Czy ktoś zna jakieś sposoby, aby powstrzymać przeciętnego Joe przed użyciem czegoś takiego jak Cheat-Engine do modyfikowania części gry? Obecnie planuję, aby klient przesyłał skrót MD5 każdego pliku ustawień używanego przez grę (przechowywanego jako XML) na serwerze gry w celu weryfikacji co kilka sekund, ale czy jest coś, co mogę zrobić, aby zatrzymać takie rzeczy, jak edytory pamięci itp. ?

Użytkownik093203920
źródło
2
Poleciłbym ten artykuł, Budowanie gier wieloosobowych - Bezpieczeństwo napisano dla niektórych interfejsów API dla wielu graczy, ale pomysły są dobre i nadal obowiązują
Cyral

Odpowiedzi:

8

Jeśli martwisz się o lokalnie zmodyfikowany kod, to skąd masz pewność, że ktoś nie zmodyfikował Twojego kodu powiadomienia, aby wysłać statyczną listę skrótów MD5, takich samych, jakich oczekujesz? W rzeczywistości nie potrzebujesz nawet modyfikacji kodu, wystarczy prosty serwer proxy (zakładając, że nie ma SSL, ale nawet to można sfałszować przy odrobinie wysiłku).

Jedynym sposobem na zrobienie tego, co chcesz, jest posiadanie serwera i po prostu w ogóle nie ufanie klientowi. Wszystkie obliczenia powinny być obsługiwane na serwerze, a wszystkie działania zweryfikowane jako możliwe. Na przykład nie pozwól klientowi powiedzieć, że chce przejść na jedną stronę mapy, gdy wiesz, że przed chwilą był po drugiej stronie. Bez serwera w środku, który robi wszystko, co jest istotne dla gry, nie można nie oszukiwać, ponieważ ktoś mądry zawszeznaleźć sposób obejścia wszystkiego, co można wbudować w klienta. Nawet z jednym jest to nadal możliwe, jeśli nie przemyślisz wszystkich różnych sposobów lekkiego manipulowania sytuacją. Na przykład walidacja ruchu, o której wspominałem wcześniej: jeśli wykonasz proste obliczenia punkt-punkt, ludzie mogą nadal być w stanie teleportować się przez ściany.

Pytanie brzmi zatem, jak średni jest „przeciętny Joe”? Wspomniałeś już o edytowaniu kodu i edytorach pamięci. To jest ponad to, co osobiście uważam za średni poziom, a jeśli chcesz się martwić o ten poziom, wymagany jest osobny zaufany serwer, który wykonuje wszystkie ciężkie podnoszenie, a klient sprowadza się do samego urządzenia wyświetlającego i wejściowego.

Matthew Scharley
źródło
2
@ user185812: Zazwyczaj dobrym pomysłem jest odczekanie co najmniej kilka godzin przed zaznaczeniem zaakceptowanej odpowiedzi. Chociaż osobiście uważam, że moja odpowiedź jest całkiem dobra (jestem stronniczy), inni prawdopodobnie będą mieli większy wkład, a zobaczenie zaakceptowanej odpowiedzi jest dość odstraszające dla innych.
Matthew Scharley,
@MatthewScharley - bez obaw. ;)
Martin Sojka
11

Klient jest w rękach wroga. ( Prawa projektowania świata online )

Naprawdę, jedynym sposobem na pokonanie większości oszustów jest sprawienie, aby klient był „cienkim klientem”, to znaczy: działał jedynie jako urządzenie wejściowe i wyjściowe i nigdy nie przekazywał mu więcej informacji, niż jest to dokładnie potrzebne.

Nie zatrzyma to automatyzacji i nie zatrzyma pasywnego gromadzenia i analizy informacji, ale możesz zaprojektować swoją grę tak, aby nie miała ona znaczącego wpływu.

To nie powstrzyma ludzi przed hakowaniem się nawzajem za pomocą źle sformułowanych wiadomości, na których opiera się serwer - Twój klient musi chronić się przed wiadomościami z serwera tak samo, jak chroniłbyś swoje witryny przed atakami SQL injection.

Ponieważ chcesz również używać tego samego klienta do gry dla jednego gracza, rozwiązaniem byłoby uruchomienie lokalnego serwera w osobnym procesie / wątku i potraktowanie go wewnętrznie jako ustawienia klient / serwer. „Cheaty” działałyby wtedy po stronie serwera. Minecraft robi coś podobnego, choć w żadnym wypadku nie jest to pierwsza gra, która w taki sposób oddzieliła silnik gry od interfejsu.

Sugerowane czytanie:

Martin Sojka
źródło
2

W podstawowej grze wieloosobowej oszukiwanie w rodzaju Cheat-Engine po prostu nie działa. Klienci wysyłają tylko dane i czynności, do których je zaprojektowałeś. Zwykle to niewiele więcej niż to, co „zrobił” gracz, np. W jakim kierunku biegnie, jeśli strzela i tak dalej. Zmiany, które wprowadzi do pamięci, wpłyną tylko na jego własną grę, ale pozostali gracze nie zobaczą żadnej zmiany, tak zwanej desynchronizacji. Większość gier wykrywa takie desynchronizacje i usuwa z gry desynchronizowanego gracza.

Istnieją również inne sposoby oszukiwania, ale wszystkie dotyczą sposobu zaprojektowania gry.

Aby zabezpieczyć się przed najłatwiejszymi włamaniami, którymi są fałszywe wiadomości sieciowe, serwer powinien sprawdzić te pakiety pod kątem ich zdrowia. „Ten facet właśnie przeskoczył 5 ekranów? To niemożliwe, odmów pakietowi.” (Pamiętaj, że możesz również przejść w pełni zsynchronizowaną trasę - oznacza to, że wszystko jest zsynchronizowane i tylko „Jakie przyciski nacisnął odtwarzacz”. - wysyłane są wiadomości - co sprawia, że ​​fałszywe wiadomości sieciowe są bezużyteczne z założenia).

Ostatnim sposobem oszukiwania w trybie dla wielu graczy są włamania do widoczności, które modyfikują klienta tak, aby pokazywał graczowi dane, których nie zna. Przykłady tego nie pokazują mgły wojny, możliwości patrzenia przez ściany, wyświetlania minimapy lub innych rzeczy. Nie można temu zapobiec.

API-Beast
źródło
Nie zgadzam się co do hacków widoczności. Czy nie można temu zapobiec, nie podając informacji o kliencie, dopóki jego postać nie będzie tego świadoma? Nie zrozum mnie źle, może to nie być dobry projekt. Ale to różni się od niemożności uniknięcia.
xuincherguixe
@xuincherguixe Myślę, że w niektórych okolicznościach jest to niemożliwe. Na przykład obaj klienci grają pod tym samym adresem IP i tym samym portem. W takim przypadku tylko dobra wola klienta uniemożliwia mu odczyt danych przeznaczonych dla drugiego.
Wodzu
1

Aby zapobiec podstawowym atakom Cheat Engine, które manipulują wartościami twoich zmiennych, musisz je ukryć. Zazwyczaj Cheat Engine służy do identyfikowania lokalizacji w pamięci interesujących zmiennych (np. Ilość złota lub życia lub poziom ulepszenia umiejętności) poprzez wyszukiwanie znanej wartości tej zmiennej, rozegranie większej części gry i spowodowanie, że wartość zmień, a następnie Cheat Engine wykona nowe wyszukiwanie na podstawie wyników poprzedniego wyszukiwania nowej wartości. Pozwala to oszustowi na przybliżenie miejsca w pamięci wartości, teraz mogą zmienić wartość tego miejsca w pamięci za pomocą Cheat Engine.

Na przykład mam 245 GOLD ... z Cheat Engine Robię wyszukiwanie 245 i znajduję wiele miejsc w pamięci. Następnie gram trochę więcej i zwiększam swoje złoto do 314, a następnie przeszukuję poprzednie wyniki wyszukiwania pod kątem wartości 314 i łatwo znajduję miejsce w pamięci, w którym przechowywane jest ZŁOTO.

Aby temu zapobiec, nigdy nie należy przechowywać rzeczywistej wartości w miejscu pamięci. Na przykład przechowuję wartość w obiekcie, który musi obliczyć rzeczywistą wartość na żądanie, gdy jest to wymagane. Powiedzmy, że gracz ma 245 ZŁOTA. Jeśli szukają lokalizacji pamięci o wartości 245, mogą znaleźć wiele, ale żadna z nich nie będzie lokalizacją pamięci, w której faktycznie przechowywana jest wartość złota, to znaczy dlatego, że nie przechowujesz wartości 245 dla złota. Gdy gra musi wiedzieć, ile złota, zapyta obiekt, który ma dla niego wartość, która obliczy ją na żądanie.

Pytanie więc brzmi: jak dokładnie przechowujesz wartość w sposób, który jej nie ujawnia? To staje się trochę trudne i brzydkie i jestem pewien, że można to zrobić na wiele sposobów. Lubię przechowywać tablicę boolowską (lub tablicę bajtów). Długość tablicy może być dowolna, ale powiedzmy, że wynosi 13. Wtedy masz licznik, który pokazuje, ile razy 13 przechodzi w tę rzeczywistą wartość. Więc jeśli chcemy przedstawić 245, to licznik miałby wartość 18. Teraz tablica miałaby wszystkie booleany ustawione na true dla reszty 245/13 ... w zasadzie moduł. W tym przypadku jest to 11, więc pierwsze 11 boolanów w tablicy zostanie ustawione na true, a pozostałe na false. Aby pobrać wartość, wystarczy pomnożyć licznik przez długość tablicy, a następnie dodać 1 dla każdego logicznego zestawu wartości true (zatrzymanie przy pierwszym false). Teraz liczba 245 nigdy nie byłaby nigdzie przechowywana i trudno byłoby znaleźć miejsce w pamięci, które musiałoby zostać zmanipulowane, aby zmienić ilość złota. Podczas tworzenia tego obiektu możesz chcieć ustawić długość tablicy na różne rozmiary (być może losowo wybrać liczbę z pewnego rozsądnego zakresu).

EDYCJA: Przydaje się w trybie dla wielu graczy i dla jednego gracza. Oszukiwania można dokonać także w trybie wieloosobowym, w którym wartości w pakietach mogą ulec zmianie. Wymagałoby to różnych technik, takich jak podpisywanie każdego pakietu.

Jose Martinez
źródło
1
Zazwyczaj, aby zapobiec oszustwom, gry wieloosobowe obliczają wszystko na serwerze, więc modyfikowanie wartości na kliencie lub w pakiecie wysyłanym do serwera nie zmienia niczego w rzeczywistej grze. Ale reszta odpowiedzi jest interesująca.
Vaillancourt
@AlexandreVaillancourt Dobra uwaga. Niepokoi mnie procesor serwera obliczający sygnatury. Chcę, aby serwer był szybki, po prostu przesyłając pakiety między dwoma graczami, ale przyjrzę się teraz, gdy już to zauważyłeś.
Jose Martinez,
Jeśli wysyłasz tylko dane wejściowe od klienta do serwera, nie musisz podpisywać każdego pakietu. Na serwerze, jeśli dane wejściowe nie mają sensu, są po prostu odrzucane lub klient zostaje wyrzucony za oszustwo. Serwer oblicza następny stan gry, a następnie wysyła nowy stan do wszystkich graczy, tak zazwyczaj unika się oszustwa (nie pozbywasz się takich botów, ale przynajmniej unikasz przypadkowego oszustwa ze strony graczy) .
Vaillancourt
1
Aby tego uniknąć, pozwalasz serwerowi aktualizować nowe życie, a następnie wysyłać nowe życie do klienta. Wszystko jest obliczane na serwerze i niech klienci będą po prostu „głupimi terminalami” dla wszystkich ważnych rzeczy: klient będzie odpowiedzialny za przechwytywanie danych wejściowych z odtwarzacza („kliknięty na x, y w czasie T”, „hit” przycisk X w czasie T ”), wysyłając je na serwer i odbierając nowy stan z serwera („ gracz jest teraz w pozycji X, Y ”,„ gracz ma życie ZZZ ”) i wyświetlając go graczowi.
Vaillancourt
1
Dzięki temu oszust (człowiek w środku) może zepsuć wszystko, co chce z pakietami, nie zmieni to stanu gry na serwerze, ponieważ serwer upewni się, że dane wejściowe są prawidłowe („hmm klient kliknął w pięciu różnych miejscach w ciągu ostatnich 0,03 sekundy, to nie jest normalne, odrzućmy te kliknięcia ”) i uruchom całą samą symulację.
Vaillancourt