Questo è un classico problema con giochi e concorsi su Internet. Il tuo codice Flash funziona con gli utenti per decidere un punteggio per un gioco. Ma gli utenti non sono affidabili e il codice Flash viene eseguito sul computer dell'utente. Sei SOL. Non c'è niente che tu possa fare per impedire a un attaccante di ottenere punteggi alti:
Flash è ancora più facile da decodificare di quanto si possa pensare, dal momento che i bytecode sono ben documentati e descrivono un linguaggio di alto livello (Actionscript) --- quando pubblichi un gioco Flash, pubblichi il tuo codice sorgente, sia che tu saperlo o no.
Gli aggressori controllano la memoria di runtime dell'interprete Flash, in modo tale che chiunque sappia utilizzare un debugger programmabile può modificare qualsiasi variabile (incluso il punteggio corrente) in qualsiasi momento o il programma stesso.
Il più semplice attacco possibile al tuo sistema è quello di eseguire il traffico HTTP per il gioco attraverso un proxy, catturare il salvataggio con punteggio più alto e riprodurlo con un punteggio più alto.
Puoi provare a bloccare questo attacco vincolando ogni salvataggio con punteggio elevato in una singola istanza del gioco, ad esempio inviando un token crittografato al client all'avvio del gioco, che potrebbe apparire come:
hex-encoding( AES(secret-key-stored-only-on-server, timestamp, user-id, random-number))
(È inoltre possibile utilizzare un cookie di sessione con lo stesso effetto).
Il codice di gioco fa eco a questo token al server con il salvataggio dei punteggi migliori. Ma un attaccante può ancora lanciare di nuovo il gioco, ottenere un gettone e quindi incollarlo immediatamente in un salvataggio di punteggio elevato rigiocato.
Quindi, successivamente, non solo si alimenta un token o un cookie di sessione, ma anche una chiave di sessione con crittografia di punteggio elevato. Questa sarà una chiave AES a 128 bit, a sua volta crittografata con una chiave hardcoded nel gioco Flash:
hex-encoding( AES(key-hardcoded-in-flash-game, random-128-bit-key))
Ora, prima che il gioco pubblichi il punteggio più alto, decodifica la chiave di sessione di crittografia con punteggio elevato, cosa che può fare perché hai codificato la chiave di sessione di crittografia con punteggio elevato nella chiave di decodifica nel file binario di Flash. Crittografate il punteggio più alto con questa chiave decifrata, insieme all'hash SHA1 del punteggio più alto:
hex-encoding( AES(random-128-bit-key-from-above, high-score, SHA1(high-score)))
Il codice PHP sul server controlla il token per assicurarsi che la richiesta provenga da un'istanza di gioco valida, quindi decodifica il punteggio più alto crittografato, verificando che il punteggio più alto corrisponda allo SHA1 del punteggio più alto (se salti questo passaggio , la decrittazione produrrà semplicemente punteggi casuali, probabilmente molto alti, alti).
Quindi ora l'attaccante decompila il tuo codice Flash e trova rapidamente il codice AES, che sporge come un pollice dolente, anche se anche se non lo facesse sarebbe rintracciato in 15 minuti con una ricerca di memoria e un tracciante ("Lo so il mio punteggio per questo gioco è 666, quindi troviamo 666 in memoria, quindi prendiamo qualsiasi operazione che tocchi quel valore --- oh guarda, il codice di crittografia del punteggio più alto! "). Con la chiave di sessione, l'attaccante non deve nemmeno eseguire il codice Flash; prende un gettone di lancio del gioco e una chiave di sessione e può rispedire un punteggio alto arbitrario.
Ora sei al punto in cui la maggior parte degli sviluppatori si arrende --- dà o impiega un paio di mesi a scherzare con gli aggressori:
Scrambling i tasti AES con operazioni XOR
Sostituzione di array di byte chiave con funzioni che calcolano la chiave
Spargimento di crittografie di chiavi false e registrazioni di punteggi elevati in tutto il binario.
Questo è tutto principalmente una perdita di tempo. Inutile dire che SSL non ti aiuterà neanche; SSL non può proteggerti quando uno dei due endpoint SSL è male.
Ecco alcune cose che possono effettivamente ridurre le frodi ad alto punteggio:
Richiede un accesso per giocare, fare in modo che l'accesso produca un cookie di sessione e non consentire più avvii di gioco in sospeso nella stessa sessione o più sessioni simultanee per lo stesso utente.
Rifiuta i punteggi più alti delle sessioni di gioco che durano meno delle partite reali più brevi mai giocate (per un approccio più sofisticato, prova a "mettere in quarantena" i punteggi più alti per le sessioni di gioco che durano meno di 2 deviazioni standard al di sotto della durata media del gioco). Assicurati di tenere traccia delle durate dei giochi sul lato server.
Rifiuta o metti in quarantena i punteggi più alti dagli accessi che hanno giocato al gioco solo una o due volte, in modo che gli attaccanti debbano produrre una "traccia cartacea" di gioco dall'aspetto ragionevole per ogni accesso che creano.
I punteggi di "Heartbeat" durante il gioco, in modo che il tuo server veda la crescita del punteggio nel corso della vita di un gioco. Rifiuta i punteggi più alti che non seguono curve di punteggio ragionevoli (ad esempio, saltando da 0 a 999999).
Stato del gioco "Istantanea" durante il gioco (ad esempio, quantità di munizioni, posizione nel livello, ecc.), Che è possibile riconciliare successivamente con i punteggi intermedi registrati. Non devi nemmeno avere un modo per rilevare anomalie in questi dati per cominciare; devi solo raccoglierlo e poi puoi tornare indietro e analizzarlo se le cose sembrano sospette.
Disabilita l'account di qualsiasi utente che non supera uno dei tuoi controlli di sicurezza (ad esempio, inviando sempre un punteggio elevato crittografato che non supera la convalida).
Ricorda però che stai solo scoraggiando le frodi ad alto punteggio qui. Non c'è niente che puoi fare per prevenire se. Se ci sono soldi in gioco nel tuo gioco, qualcuno sta per sconfiggere qualsiasi sistema tu abbia inventato. L'obiettivo non è fermare questo attacco; è per rendere l'attacco più costoso del semplice diventare bravo nel gioco e sconfiggerlo.