Como impedir relatórios de pontuação falsa em tabelas globais de recordes?

44

Os jogos para navegadores e dispositivos móveis geralmente têm tabelas de recordes globais. Também é comum que essas tabelas contenham pontuações de 2.147.483.647 - nas quais as pessoas descobriram a chamada de serviço da web que relata pontuações e a usaram para registrar uma pontuação fictícia.

Para jogos simples, podemos nos defender contra isso incluindo um registro de todos os movimentos que o jogador fez (e quaisquer sementes aleatórias usadas para gerar o nível) com a chamada de relatório de pontuação. O jogo inteiro pode ser reproduzido e verificado no servidor.

No entanto, isso rapidamente se torna inviável para qualquer coisa maior que o Pac-man.

De que outra forma pode evitar fraudes desse tipo?

teedyay
fonte
Eu tinha exatamente essa mesma pergunta sobre jogos para iPhone usando a mesma técnica para criar uma tabela de recordes global.
Deft_code 30/09/10
Tem certeza de que seria inviável enviar o replay?
o0 '.
Sim eu tenho certeza. :)
teedyay 15/02/2012

Respostas:

9

O sistema interno que usamos para o Moblox (posteriormente substituído pelo OpenFeint) funcionou assim:

  • Envie uma mensagem JSON por HTTP simples (não HTTPS). Inclua um hash MD5 de todos os campos mais uma sequência mágica.
  • No servidor, verifique a integridade da mensagem com a mesma operação.

Para quebrar o sistema, você teria que encontrar essa corda mágica. É possível com a engenharia reversa, mas dolorosa.

OpenFeint, ScoreLoop e CocosLive usam o mesmo truque, mas com HTTPS. Muito fácil de implementar.

Ellis
fonte
29
Eu sou bastante duvidoso que a engenharia reversa para encontrar sua corda mágica seria tão difícil.
Kylotan
4
Este é um aplicativo Android em C ++ nativo. Não há símbolo nem bom depurador disponível. Portanto, você pode ler o código ARM, mas não rastreá-lo facilmente. A chave é composta por várias operações, portanto, encontrar todas as strings não é suficiente. Isso não é perfeito, mas é bastante doloroso.
Ellis
3
Um exercício de graduação padrão, pelo menos nas universidades dos EUA, é fazer engenharia reversa de senhas construídas conforme você descreve, lendo o código de montagem y86 ( cgi2.cs.rpi.edu/~hollingd/comporg-spring2007/notes/Y86/… ).
12
Essa é uma técnica terrivelmente fraca , que dará aos desenvolvedores uma sensação muito falsa de segurança.
o0 '.
2
Este é um exemplo muito bom de en.wikipedia.org/wiki/Security_through_obscurity
kaoD 15/02/2012
21

Embora você esteja certo de que nem sempre é possível enviar replays inteiros ao servidor para jogos complexos, um sistema semelhante pode ser usado fazendo com que o servidor solicite periodicamente (e semi-aleatoriamente) o cliente para alguma parte de seu estado, enquanto o jogo está rodando.

Por exemplo, em um FPS, a cada minuto você pode perguntar "Quantas mortes você tem?", "Onde estão todos os inimigos?", Etc. Se o cliente não voltar com uma resposta razoável a um desafio em um tempo razoável, eles estão trapaceando.

Obviamente, isso só funciona se o jogo estiver online durante toda a sessão de jogo. Como o objetivo aqui é poder fazer o upload para uma tabela de classificação on-line, acho isso razoável - não expulsar o jogador do jogo se responder errado, apenas não o deixe na lista de pontuação.

No entanto, eu encorajo você a reconsiderar o envio de replays. Tudo o que você realmente precisa é a semente inicial aleatória e a entrada com registro de data e hora. Isso realmente deve ter algumas centenas de KB, no máximo. Muitos jogos de arcade já fazem isso para salvar replays para fins de revisão de jogadores; a validação do servidor pode não ser trivial, mas evita todos os tipos de trapaça, exceto os de bots.


fonte
10

Você pode limitar os abusos mais flagrantes monitorando os resultados mais altos na tabela de pontuação máxima. Dependendo do seu jogo, você pode ter uma "pontuação perfeita", acima da qual qualquer pontuação deve ser fraudulenta. Caso contrário, você pode calcular a menor "pontuação impossível"; o jogador pode disparar 10 tiros por segundo, o jogo dura 1 minuto e cada inimigo morto vale 100 pontos? Qualquer pontuação superior a 60.000 deve ser fraudulenta.

Você também pode ajudar a mitigar o problema enviando alguns metadados; não o histórico completo do jogo, como você descreve, mas apenas os componentes que compõem o placar. Diga: marque 60000, 500 inimigos mortos e um item de bônus agarrado. Você pode executar verificações simples. Isso é "segurança através da obscuridade" e, portanto, não é absolutamente seguro, mas ajuda a eliminar o mais ingênuo dos atacantes.

Gregory Avery-Weir
fonte
Você também pode sinalizar um usuário (possivelmente por IP) se ele enviar uma pontuação que não corresponda aos metadados. Então, se eles tentarem enviar uma pontuação novamente com os metadados corretos, você poderá examiná-la e possivelmente bani-las completamente. Você também pode enviar uma mensagem atrevida de lá a partir de enviar solicitação de pontuação :)
Adam Harte
Eu acho que essa resposta é melhor que a resposta aceita. Basta descobrir qual número é o máximo que seus jogadores podem alcançar. Qualquer coisa mais alta, apenas descarte.
6
Portanto, se um jogador que frequenta uma universidade trapaceia, todo mundo na rede agora é um "trapaceiro"
AttackingHobo
6

Em última análise, você só pode excluir pontuações impossivelmente altas, porque o restante é (por definição) meramente implausível e, portanto, pode ser um jogador legítimo (e impressionante).

Caso contrário, você precisará confiar em técnicas de ofuscação (como criptografia e envio de outras estatísticas além da pontuação).

Você também pode enviar a pontuação periodicamente enquanto o jogo está sendo jogado, o que adicionaria outro nível de complexidade à trapaça - ou seja, o servidor pode decidir se o jogo foi jogado por tempo suficiente para garantir uma pontuação específica e também garantir que relatórios intermediários suficientes foram recebidos durante o tempo de jogo (apenas não o faça 100% ou o trem entrando em um túnel no meu caminho de casa resultará em jogar o telefone pela janela).

No final, alguém encontrará uma maneira de quebrá-lo, portanto, não se mate tentando impedi-lo.

JasonD
fonte
6

Eu adicionei uma tabela de pontuações rápida / suja a um projeto meu há um tempo atrás e, por não ser versado em segurança na Internet / etc, acabou sendo um erro. Surpreendentemente, com quase 1.200.000 pontuações gravadas, só tive 5 ou 6 ocasiões de lotes de pontuações flagrantemente incorretas chegando ao topo do quadro. A maioria das pontuações parecia mais uma falha no jogo do que um verdadeiro "hacking".

Então, acho que um ponto importante é: verifique se o sistema de pontuação do seu jogo é hermético ou, pelo menos, faça uma verificação de viabilidade de pontuação realmente boa; agora, esse jogo que eu estou falando foi uma entrada de Ludum Dare por 48 horas, então não era a coisa mais estável por aí .. mas no geral, acho que é mais provável que o jogador casual descubra / explore uma falha no jogo do que ter alguém "hackeando" diretamente a tabela de classificação.

Dito isto, estou trabalhando para reescrever este projeto agora e vou sair com a ofuscação. Não vou entrar em muitos detalhes, mas basicamente todas as pontuações enviam um valor-chave com base em vários valores aleatórios, hash e uma seqüência de caracteres mágica. Em seguida, qualquer pontuação que passe nessa verificação e seja alta o suficiente para obter o valor real " O cabeçalho Top X "precisa passar por outra rodada de validação (desta vez com um valor de chave expirado gerado no final do servidor e verificações mais completas de viabilidade).

Também aconselho o uso de um rastreador de pacotes de algum tipo para testar que tipo de coisas são visíveis (eu estava originalmente fazendo uma verificação muito mais simples, o que significava que alguém poderia usar um rastreador de pacotes para encontrar e duplicar a solicitação http de uma pontuação carregada, sem saber a seqüência mágica ou qualquer coisa (significava que você precisava primeiro de uma pontuação legítima, mas poderia enviar duplicatas dessa pontuação o quanto quisesse ..)). Eu usei o Wireshark para testar isso.

Huh, isso ficou um pouco longo, mas espero que ajude ...

Riley Adams
fonte
Certamente é. Parece que um hash salgado é um bom caminho a percorrer. Eu não tinha considerado que eles reenviariam a mesma pontuação válida muitas vezes. Um GUID e um carimbo de data / hora incluídos no pacote (e no hash) devem ser pagos - posso verificar se há duplicações no servidor. Obrigado.
teedyay
3

Não sou especialista neste campo, mas se eu fosse você, tentarei criptografar a pontuação com uma chave incorporada no seu código. Essas pessoas precisarão aplicar engenharia reversa sobre o seu código, em vez do texto sem formatação usado para os serviços da web.


fonte
2
Eu iria ainda mais longe. Gere um hash a partir do código hash do arquivo exe (ou parte dele). Ao enviar pontuações, envie o número da versão e o servidor poderá validar usando uma tabela que possui constantes simples número da versão-> código de hash. Então você recebe o bônus adicional de que, se alguém trapaceia modificando o programa, sua pontuação mais alta não conta.
configurator
7
Se alguém estiver modificando o programa, ele já poderá enviar a chave que desejar.
2
@ Joe Wreschnig, eles podem enviar qualquer chave que desejarem, mas o servidor deve estar configurado para aceitar apenas chaves válidas.
AttackingHobo
5
Eu acho que o argumento de Joe era que eles não precisam usar o hash do programa recém-modificado, mas podem enviar o que o hash anterior tiver sido.
Kylotan
1
@ gd1: como isso ajuda?
Kylotan
1

Speedruns são basicamente gravação de cada pressionamento de tecla e estão gravando sobre um jogo INTEIRO. Então, sim, você pode gravar o jogo inteiro, não é inviável. Qualquer outra maneira de fazer isso é quebrável através da engenharia reversa (não posso enfatizar o suficiente: você não está adicionando segurança, está adicionando obscuridade).

Ainda assim, mesmo se você fizer dessa maneira, eles poderão enviar um speedrun. Você não pode fazer nada para impedir isso.

o0 '.
fonte
2
Normalmente, a reprodução, não a gravação, é a parte inviável para o servidor. Se o cliente estiver jogando o jogo por algumas horas, a ressimulação do servidor poderá levar muitos minutos ou mais da CPU. Isso não é realmente aceitável se você tiver muitas pessoas enviando pontuações.
2
O tamanho do pacote de dados se tornaria um problema para jogos para celular - especialmente se o jogador pagar por sua largura de banda pelo byte.
teedyay
Oh, o que vocês dois dizem é verdade. Ainda assim, não há outra solução "real".
o0 '.
11
Você não precisa validar todas as gravações enviadas, basta validar as que chegarem ao top 10. Não há muito sentido em trapacear para se tornar o número 11. E você não precisa fazer isso em tempo real. Processo em lote periódico seria bom.
cinza
@teedyay Digamos que o jogador execute uma média de 5 ações por segundo, e cada ação pode ser completamente descrita em 32 bits. São 20 bytes por segundo ou 72 kB por hora. O preço típico dos dados móveis nos EUA é de US $ 10 por GB ou 1 centavo por 1.000 kB.
Damian Yerrick
1

Enquanto você está nisso, há a questão de saber se uma pontuação alta é simplesmente um jogador que encontrou uma façanha (por exemplo, se algumas coisas no jogo causam uma penalidade de pontuação e um bug faz com que uma pontuação negativa seja "contornada" tornar-se altamente positivo ... ou apenas um jogador que encontra uma determinada condição de jogo como um local seguro no tabuleiro, onde pode ficar sentado e não precisar se preocupar em perder indefinidamente).

Para saber a diferença entre um hack e uma exploração do jogo, seria bom enviar pelo menos alguns dados de jogo. Isso o ajudará a consertar as explorações, pelo menos.

Para alguns jogos (principalmente os baseados em turnos), é possível jogar o jogo através do servidor, onde toda a lógica do jogo existe no lado do servidor e o cliente é apenas uma interface. Isso não apenas dificulta muito o hackeamento de pontuação, mas também permite que você registre todas as ações dos jogadores no servidor trivialmente e, assim, reproduza qualquer jogo a qualquer momento. Sei que, para algo como um atirador de ação, isso pode ser impraticável.

Ian Schreiber
fonte
1

Crie toda a aleatoriedade de origem de uma semente e armazene a entrada para cada quadro. Sempre que você tiver uma pontuação alta reivindicada (por exemplo, as 50 principais), envie a semente e a entrada completa ao servidor. Repita o jogo no servidor e atualize a tabela de classificação, se você conseguir uma pontuação alta.

Se você considera isso inviável para jogos mais sofisticados devido ao tamanho da solicitação, dê uma olhada neste exemplo.

Digamos que o jogo tenha 8 botões de entrada (1 pad e 4 botões) e é executado a 60fps. Uma entrada de jogo de uma hora pode ser transmitida com 3.6KB sem compressão. Sua sessão provavelmente terá menos de uma hora e a compactação deve diminuir bastante, porque a entrada humana tem muita redundância.

O desafio é tornar o jogo determinístico, jogável a partir da entrada gravada e executável no servidor.

Vinicius Canaa
fonte
0

Nunca implementou isso antes, mas ...

Envie pontuações incrementalmente com registros de data e hora. Isso fornece um registro para ver com que frequência a pontuação melhorou, bem como uma maneira de rastrear o "momento" do recorde.

Você definiria marcos / critérios para sua pontuação.

Por exemplo: Uma pontuação maior que 20.000 não pode chegar nos primeiros 20 segundos de um jogo. Uma pontuação maior que 250.000 não pode chegar sem uma entrada maior que 200.000.

Isso não é exatamente o mesmo que enviar um estado de jogo, mas próximo a ele.

Side Benefit: Pense em todas as estatísticas úteis de jogo que você obteria com isso. Alguém provavelmente pagaria um bom dinheiro por isso.

Markus
fonte