Come posso impedire i rapporti sui punteggi falsi nelle tabelle dei punteggi globali?


44

I browser e i giochi mobili hanno comunemente tabelle di punteggi globali. È anche comune che quelle tabelle contengano punteggi di 2.147.483.647 - in cui le persone hanno capito la chiamata al servizio web che riporta i punteggi e l'ha usata per registrare un punteggio fittizio.

Per semplici giochi rompicapo, possiamo difenderci da questo includendo un record di ogni mossa effettuata dal giocatore (e di ogni seme casuale usato per generare il livello) con la chiamata di segnalazione del punteggio. L'intero gioco può quindi essere riprodotto e verificato sul server.

Tuttavia, questo diventa rapidamente impossibile per qualsiasi cosa più grande di Pac-man.

In quale altro modo è possibile prevenire questo tipo di imbrogli?


Ho avuto la stessa identica domanda per quanto riguarda i giochi per iPhone usando la stessa tecnica per creare una tabella dei punteggi globali.
deft_code

Sei sicuro che non sarebbe possibile inviare il replay?
o0 '.

Sì, sono sicuro. :)
teedyay,

Risposte:


9

Il sistema interno che abbiamo usato per Moblox (successivamente sostituito con OpenFeint) ha funzionato in questo modo:

  • Invia un messaggio JSON su HTTP semplice (non HTTPS). Includi un hash MD5 di tutti i campi più una stringa magica.
  • Sul server, verificare l'integrità del messaggio con la stessa operazione.

Per rompere il sistema, dovresti trovare questa corda magica. È possibile con il reverse engineering, ma è doloroso.

OpenFeint, ScoreLoop e CocosLive usano tutti lo stesso trucco, ma con HTTPS. Molto facile da implementare.


29
Sono abbastanza dubbioso che il reverse engineering per trovare la tua corda magica sarebbe così difficile.
Kylotan,

4
Questa è un'applicazione Android in C ++ nativo. Non esiste alcun simbolo, né un buon debugger disponibile. Quindi puoi leggere il codice ARM, ma non rintracciarlo facilmente. La chiave è composta da più operazioni, quindi trovare tutte le stringhe non è sufficiente. Non è perfetto ma abbastanza doloroso.
Ellis,

3
Un esercizio universitario standard, almeno nelle università statunitensi, consiste nel decodificare le password costruite come descritto, leggendo il codice dell'assembly y86 ( cgi2.cs.rpi.edu/~hollingd/comporg-spring2007/notes/Y86/… ).

12
Questa è una tecnica terribilmente debole , che darà agli sviluppatori un falso senso di sicurezza.
o0 '.

2
Questo è un ottimo esempio di en.wikipedia.org/wiki/Security_through_obscurity
kaoD

21

Mentre hai ragione sul fatto che non è sempre possibile inviare interi replay al server per giochi complessi, un sistema simile può essere utilizzato facendo in modo che il server chieda periodicamente (e in modo semi-casuale) al client una parte del suo stato, mentre il il gioco è in esecuzione.

Ad esempio, in un FPS, ogni minuto potresti chiedere "Quante uccisioni hai?", "Dove sono tutti i nemici?", Ecc. Se il cliente non torna con una risposta ragionevole a una sfida in un ragionevole quantità di tempo, stanno barando.

Ovviamente, questo funziona solo se il gioco è online durante l'intera sessione di gioco. Poiché l'obiettivo qui è quello di essere in grado di caricare su una classifica online, penso che sia ragionevole - non cacciare il giocatore dal gioco se rispondono in modo errato, ma non lasciarli nella lista dei punteggi.

Ti incoraggio a riconsiderare l'invio di replay comunque. Tutto ciò di cui hai veramente bisogno è il seme casuale iniziale e l'input timestamp. Dovrebbero essere al massimo poche centinaia di KB. Molti giochi arcade lo fanno già per salvare i replay ai fini della recensione dei giocatori; far convalidare il tuo server potrebbe non essere banale, ma impedisce tutti i tipi di imbrogli, tranne il botting.


10

Puoi limitare gli abusi più flagranti monitorando i risultati più alti nella tabella dei punteggi migliori. A seconda del tuo gioco, potresti avere un "punteggio perfetto", al di sopra del quale qualsiasi punteggio deve essere fraudolento. In caso contrario, è possibile calcolare il "punteggio impossibile" più basso; il giocatore può sparare 10 colpi al secondo, il gioco dura 1 minuto e ogni nemico ucciso vale 100 punti? Quindi qualsiasi punteggio superiore a 60.000 deve essere fraudolento.

Puoi anche aiutare a mitigare il problema inviando insieme alcuni metadati; non la storia completa del gioco, come descrivi, ma solo i componenti che compongono il punteggio. Dì: segna 60000, 500 nemici uccisi e un oggetto bonus afferrato. È quindi possibile eseguire semplici controlli. Questa è "sicurezza attraverso l'oscurità" e quindi non è affatto sicura, ma aiuta a eliminare il più ingenuo degli aggressori.


Puoi anche contrassegnare un utente (possibilmente tramite IP) se invia un punteggio che non corrisponde ai metadati. Quindi, se provano a inviare di nuovo un punteggio che ha i metadati corretti, è possibile esaminarlo e possibilmente vietarli del tutto. Puoi anche inviare un messaggio sfacciato da lì inviare la richiesta di punteggio :)
Adam Harte,

Penso che questa risposta sia migliore della risposta accettata. Basta capire quale numero è il massimo che i tuoi giocatori possono raggiungere. Qualunque cosa più in alto, scartala.

6
Quindi, se un giocatore che va in un'università imbroglia, tutti nella rete ora sono un "imbroglione"
AttackingHobo

6

Alla fine puoi solo escludere punteggi incredibilmente alti, perché il resto è (per definizione) semplicemente non plausibile, e quindi potrebbe essere un giocatore legittimo (e fantastico).

Altrimenti devi fare affidamento su tecniche di offuscamento (come la crittografia e l'invio di altre statistiche oltre il semplice punteggio).

Potresti anche inviare periodicamente il punteggio mentre il gioco è in corso, il che aggiungerebbe un altro livello di complessità ai cheat - cioè il server può decidere se il gioco è stato giocato abbastanza a lungo da giustificare un punteggio particolare, e garantire anche che rapporti intermedi sufficienti sono stati ricevuti durante il tempo di gioco (semplicemente non farlo al 100% o il treno che entra in un tunnel mentre torno a casa mi farà buttare il telefono fuori dal finestrino).

Alla fine qualcuno troverà comunque un modo per romperlo, quindi non ucciderti cercando di fermarli.


6

Ho aggiunto una tabella dei punteggi rapidi / sporchi a un mio progetto qualche tempo fa e non essendo per nulla esperto di sicurezza su Internet / ecc. Si è rivelato un po 'imperfetto. Sorprendentemente, con quasi 1.200.000 di punteggi registrati, ho avuto forse solo 5 o 6 occasioni di lotti di punteggi palesemente errati che hanno raggiunto la vetta della classifica. La maggior parte dei punteggi sembrava anche più un difetto nel gioco, che un vero "hacking".

Quindi immagino che un punto importante sia: assicurati che il sistema di punteggio del tuo gioco sia ermetico , o almeno esegui un ottimo controllo della fattibilità del punteggio; ora, questo gioco di cui sto parlando era una voce di Ludum Dare 48 ore, quindi non era la cosa più stabile in circolazione .. ma nel complesso penso che sia spesso più probabile che il giocatore occasionale scopra / sfrutti un problema tecnico avere qualcuno "hackerare" direttamente la classifica.

Detto questo, sto lavorando a una riscrittura di questo progetto in questo momento, e sto andando fuori con l'offuscamento. Non entrerò in troppi dettagli, ma fondamentalmente ho tutti i punteggi che inviano un valore chiave basato su un gruppo di valori casuali e hash e una stringa magica, quindi qualsiasi punteggio che supera quel controllo ed è abbastanza alto da rendere effettivo " La classifica "X" deve superare un altro round di convalida (questa volta con un valore chiave in scadenza generato sul lato server e controlli di fattibilità più approfonditi).

Consiglio anche di usare un tracciante di pacchetti di qualche tipo per testare quali tipi di cose sono visibili (originariamente stavo facendo una verifica molto più semplice che significava che qualcuno poteva usare un tracciante di pacchetti per trovare e duplicare la richiesta http di un punteggio caricato, senza sapere la stringa magica o altro (significa che prima avevi bisogno di un punteggio legittimo, ma potresti inviare duplicati di quel punteggio quanto volevi ..)). Ho usato Wireshark per testare questo.

Huh, questo è risultato un po 'lungo, ma spero che aiuti ...


Certamente. Sembra che un hash salato sia una buona strada da percorrere. Non avevo considerato che avrebbero rinviato lo stesso punteggio valido molte volte. Un GUID e un timestamp inclusi nel pacchetto (e nell'hash) dovrebbero essere pagati a tale scopo: posso verificare la presenza di duplicati sul server. Grazie.
teedyay,

3

Non sono un esperto in questo campo, ma se fossi in te, proverò a crittografare il punteggio con una chiave incorporata nel tuo codice. Queste persone dovranno applicare il reverse engineering sul codice anziché sul testo normale utilizzato per i servizi Web.


2
Vorrei andare ancora oltre. Genera un hash dal codice eseguendo l'hashing del file exe (o parte di esso). Quando si inviano i punteggi, inviare il numero di versione e il server può convalidare utilizzando una tabella con costanti semplici numero di versione-> codice hash. Quindi ottieni il bonus aggiuntivo che se qualcuno tradisce modificando il programma, il suo punteggio più alto non conta.
configuratore

7
Se qualcuno sta modificando il programma, può già inviare la chiave desiderata.

2
@Joe Wreschnig, possono inviare tutte le chiavi che desiderano, ma il server deve essere impostato per accettare solo chiavi valide.
AttackingHobo,

5
Penso che il punto di Joe fosse che non devono usare l'hash del programma appena modificato, ma possono semplicemente inviare qualunque sia l'hash precedente.
Kylotan,

1
@ gd1: in che modo aiuta?
Kylotan,

1

Gli Speedrun stanno praticamente registrando ogni pressione di un tasto e stanno registrando su TUTTO un gioco. Quindi sì, puoi registrare l'intero gioco, non è impossibile. Qualsiasi altro modo per farlo è crackabile attraverso il reverse engineering (non posso sottolinearlo abbastanza: non stai aggiungendo sicurezza, stai aggiungendo oscurità).

Tuttavia, anche se lo fai in questo modo, potrebbero effettivamente inviare uno speedrun. Non puoi fare nulla per impedirlo.


2
Di solito la riproduzione, non la registrazione, è la parte inaccessibile per il server. Se il client gioca da un paio d'ore, la resimulazione sul lato server potrebbe richiedere molti minuti della CPU o peggio. Questo non è davvero accettabile se ci sono molte persone che inviano punteggi.

2
La dimensione del pacchetto di dati diventerebbe un problema per i giochi per dispositivi mobili, specialmente se il giocatore paga per la larghezza di banda del byte.
teedyay

Oh, quello che entrambi dite è vero. Tuttavia, non esiste altra soluzione "reale".
o0 '.

11
Non devi convalidare tutte le registrazioni inviate, devi solo convalidare quelle che arrivano ai primi 10. Non ha molto senso imbrogliare per diventare # 11. E non devi farlo in tempo reale. Il processo batch periodico andrebbe bene.
grigio

@teedyay Supponiamo che il giocatore esegua in media 5 azioni al secondo e che ogni azione possa essere completamente descritta in 32 bit. Sono 20 byte al secondo o 72 kB all'ora. Il prezzo tipico dei dati mobili negli Stati Uniti è di $ 10 per GB, o 1 centesimo per 1000 kB.
Damian Yerrick,

1

Mentre ci sei, c'è la questione se un punteggio alto sia semplicemente un giocatore che ha trovato un exploit (ad esempio, se alcune cose nel gioco danno una penalità di punteggio, e un bug fa sì che un punteggio negativo si "avvolga" diventare altamente positivo ... o solo un giocatore che trova una certa condizione di gioco come un punto sicuro sul tabellone in cui può semplicemente sedersi lì e non doversi preoccupare di perdere indefinitamente).

Per capire la differenza tra un hack e un exploit di gioco, caricare almeno alcuni dati di gioco sarebbe buono. Ti aiuterà almeno a correggere gli exploit.

Per alcuni giochi (in particolare quelli a turni), puoi effettivamente far giocare il gioco attraverso il server, dove tutta la logica di gioco esiste sul lato server e il client è solo un'interfaccia. Ciò non solo rende molto più difficile l'hacking dei punteggi, ma consente anche di registrare banalmente tutte le azioni dei giocatori sul server e quindi di riprodurre qualsiasi gioco in qualsiasi momento. Mi rendo conto di qualcosa come uno sparatutto d'azione a contrazione, questo potrebbe essere poco pratico.


1

Crea tutta la casualità da un seme e memorizza l'input per ogni frame. Ogni volta che si ottiene un punteggio elevato richiesto (diciamo i primi 50), inviare il seme e l'input completo al server. Rigioca il gioco sul server e aggiorna la classifica se ottieni un punteggio elevato.

Se lo ritieni impossibile per giochi più sofisticati a causa delle dimensioni della richiesta, dai un'occhiata a questo esempio.

Supponiamo che il gioco abbia 8 pulsanti di input (1 pad e 4 pulsanti) e funzioni a 60fps. Un input di gioco di un'ora può essere trasmesso con 3,6 KB senza compressione. La tua sessione avrà probabilmente meno di un'ora e la compressione dovrebbe ridurla di molto, perché l'input umano ha molta ridondanza.

La sfida è rendere il gioco deterministico, giocabile dall'input registrato ed eseguibile sul server.


0

Non l'ho mai implementato prima ma ...

Invia punteggi in modo incrementale con i timestamp. Questo ti dà un registro per vedere quanto spesso il punteggio è migliorato e un modo per tracciare il "momento" del punteggio più alto.

Dovresti quindi impostare pietre miliari / criteri per i tuoi punteggi.

Ad esempio: un punteggio superiore a 20.000 non può arrivare nei primi 20 secondi di una partita. Un punteggio maggiore di 250.000 non può arrivare senza un ingresso maggiore di 200.000.

Questo non è esattamente uguale all'invio di uno stato di gioco, ma vicino ad esso.

Vantaggio secondario: pensa a tutte le utili statistiche di gioco che otterrai da questo. Qualcuno probabilmente pagherebbe un buon prezzo per questo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.