Jump to content
Unity Insider Forum
Sign in to follow this  
camcam

Mobiles Spiel senden von falschen Score verhindern

Recommended Posts

Hallo erstmal,

und zwar habe ich das Problem das ich ein mobiles singleplayer Spiel entwickeln will. Wenn man eine Runde gespielt hat soll immer der Score an einen Server geschickt werden. Jetzt ist es aber wichtig das dieser Score auf keinen Fall manipuliert werden darf. Also dass der Client mir falsche Informationen sendet z.B eine gefälschte Naricht das ein neuer Highscore erreicht wurde. Da ich in diesem Bereich jedoch fast kein Wissen besitze und ich auch nichts richtiges finden konnte, wollte ich euch mal Fragen ob ihr Tipps hättet wie ich das am besten umsetzen kann.

Vielen Dank schonmal an alle die sich Gedanken machen. :)

Share this post


Link to post
Share on other sites

Zuallererst: Absolute Sicherheit gibt es nicht. Es ist schlicht nicht möglich, ein System gegen jeden möglichen Angreifer zu schützen, daher musst du dir

vor 14 Stunden schrieb camcam:

auf keinen Fall manipuliert werden

direkt aus dem Kopf schlagen. Falls du an dieser Aussage Zweifel hast, schau dir mal die offiziellen High Scores zu Left 4 Dead an :)

Der Kampf gegen Hacker und Cheater ist immer ein Spiel des Übertrumpfens. Zuerst erstellst du ein so genanntes "Angreifermodell". Da denkst du dir den mächtigsten Gegner aus, der dein System bedrohen würde, und dann baust du genügend Gegenmaßnahmen, um diesen Angreifer abzuwehren. Es ist zum Beispiel nicht davon auszugehen, dass jemand mehrere tausend Euro in die Hand nimmt, das NSA-Rechenzentrum zur Verfügung hat oder einen Quantencomputer einsetzt, um sich einen Highscore in deinem Spiel zu erschleichen. Das durchschnittliche Scriptkiddie verliert nach zehn Minuten die Lust, sobald es feststellt, dass Request Forgery nicht funktioniert, und Low Level Memory Access ist auf mobilen Endgeräten alles andere als populär.

Was du also tun solltest:

Hash zum Request senden.

Du sendest ja einen (kleinen) Haufen Daten an deinen Server. Vermutlich in einer HTTP-Anfrage, mit den Daten im POST-Dictionary. Deine Anfrage hat dann irgendwo das hier stehen:

score=1683&playername=Hackerboi

Deine Anfrage hat damit zwei Datenpunkte, die sie einzigartig machen. Wenn du jetzt diesen String da oben in einen Hashing-Algorithmus gibst, kommt solcher Kauderwelsch dabei raus:

fc149be11bcc1f6a8e09c0a5b50ca134ad4aa4dd7fc5846afa10b7851637f276

Als Beispiel habe ich sha256 genommen. Falls du Hashing-Algorithmen noch nicht kennst: Das sind Funktionen, in die du einen String reinsteckst. Die Hash-Funktion zerhäckselt den String dann bis zur Unkenntlichkeit, sodass man ohne enormen Rechenaufwand nicht in der Lage ist, wieder den ursprünglichen String auszurechenen. Der Knackpunkt ist aber: Hash-Funktionen sind deterministisch. Das heißt, dass du wieder denselben alphanumerischen Salat rausbekommst, wenn du denselben String noch einmal in dieselbe Hash-Funktion reinstopfst.

Der Trick ist jetzt, dass du deinem Spiel ein geheimes Passwort gibst, und deinem Server dasselbe. Sagen wir, das Passwort lautet

4bh36aB§$abb4aL

Anstatt den String da oben in deine Hash-Funktion zu stecken, hängst du vorher noch das Passwort dran. Du verwurschtest also

score=1683&playername=Hackerboi4bh36aB§$abb4aL

und kriegst damit völlig anderen Salat:

9856b0a2333d58ce31f5748e2ea20992eb8c9ceaac4962e7d412b5e2528c2bef

Diesen Salat hängst du jetzt an deinen Highscore-Request:

score=1683&playername=Hackerboi&hash=9856b0a2333d58ce31f5748e2ea20992eb8c9ceaac4962e7d412b5e2528c2bef

und der Server empfängt diese drei Sachen. Jetzt nimmt er die eigentlichen Daten und schmeißt selber noch einmal den Hash-Algorithmus an. Punktzahl und Spielername stammen aus dem Request, das Passwort kennt er selber. Wenn jetzt derselbe Hash dabei rauskommt, wie mit der Anfrage gesendet wurde, dann kann der Server den Highscore akzeptieren.

Wenn du jetzt willst, dass man nicht einfach genau dieselbe Anfrage noch einmal senden kann, kannst du noch das aktuelle Datum in die Hash-Funktion schmeißen und mit dem Request mitsenden. Du speicherst dann den Highscore in deiner Datenbank inklusive Datum und akzeptierst nur neuere Requests.

Geschützt bist du dadurch vor "Request Forgery", also dem Angriff den du erwähntest: HTTP-Request anschauen, Werte kopieren, Punktzahl erhöhen, selber noch einen Request senden. Da der Angreifer das Passwort nicht kennt, ist es ihm nicht möglich, den Hash zu fälschen.

Nicht geschützt bist du damit gegen Angriffe, mit denen jemand das Passwort aus deiner Executable oder gar direkt aus dem Speicher auslesen kann. Ebenfalls nicht geschützt bist du dagegen, dass jemand einfach im Spiel cheatet und das Spiel sozusagen freiwillig einen zu hohen Highscore absendet. Aber wie gesagt... schau erstmal, mit was für einem Angriff du rechnen kannst. Sich gegen die vereinten Kräfte des CCC starkzumachen, um eine Highscoretabelle mit überschaubar vielen Einträgen zu schützen, wäre nicht wirklich zielführend.

Share this post


Link to post
Share on other sites

Aufjedendall schonmal Danke für die Antwort. Das mit dem Hashen der Daten und Server und Client  haben eine Key ist mir auch schon in den Sinn gekommen. Aber wie du bereits sagtest hast du dann das Problem dass Leute den Key mit ein bisschen Aufwand auslesen können. Das Problem an dem Spiel ist, dass es um etwas geht. Also man kann  etwas gewinnen. Darum versuche ich Möglichkeiten zu finden es möglichst schwer zu machen. Mir war schon relativ klar das es 100% sicher nicht geben kann. :) Wenn man an dem Spiel teilnimmt stimmt man vorher auch zu das man keine Manipulationen betreiben darf. Jedoch wird das nicht viel helfen. Ich muss einfach mal bisschen rumprobieten.

Share this post


Link to post
Share on other sites
Am 13.8.2018 um 15:54 schrieb camcam:

mit ein bisschen Aufwand auslesen

Das stimmt so nicht. Wie gesagt, Low Level Memory Profiling gibt's auf mobilen Geräten eigentlich nicht. Und auch auf Desktop-PCs geht das ein bisschen über das Wissen des durchschnittlichen Script Kiddies hinaus. Wenn es wirklich um relevante Beträge geht, dann solltest du vielleicht entsprechend Geld in die Hand nehmen und jemanden für deine Sicherheitstechnik anheuern.

Share this post


Link to post
Share on other sites

Man müsste villeicht auch noch in Betracht ziehen wieviel Kommunikation du mit deinem Server haben willst. Wenn es wirklich um etwas geht und man verhindern will, dass man das Spiel cheatet, sollte man vielleicht drüber nachdenken ob es eine so gute Idee ist, den Highscore vom Client zu berechnen und dann an den Server zu senden. Der Vorschlag von @Sascha schützt dich vielleicht einen Highscore nicht zu manipulieren aber wie auch schon gesagt wurde, ist die wahrscheinlichkeit nicht gering, dass jemand trotzdem cheatet. Da bringt es dir auch nichts wenn man davor geschützt ist, dass ein Highscore beim Senden manipuliert wird, aber nicht davor, dass man den Highscore auch vorher schon manipuliert hat

Man muss sich halt immer entscheiden zwischen Overhead bei den Datenpaketen die hin und her geschickt werden oder zwischen schneller Reaktion des Spiels. Guck dir Agar.io an. Dort wird fast gar nichts vom Spiel selbst berechnet sondern nur die Mauseingaben und Tastertureingaben an den Server gesendet und dort wird dann der gesamte Spielverlauf berechnet. Somit muss gar kein Highscore oder sonstwas vom Spieler aus gesendet werden sondern der Server berechnet den Highscore einfach selbst, da er das Spiel selbst in der Hand hat. Nachteil: Hohe Latenzen und ständige Internetverbindung. Vorteil: Enorme Cheatsicherheit.

Ist die Frage was einem wichtiger ist

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×