Estou falando de um jogo de ação sem limite de pontuação superior e sem maneira de verificar a pontuação no servidor repetindo movimentos etc.
O que eu realmente preciso é da criptografia mais forte possível no Flash / PHP e uma maneira de impedir que as pessoas chamem a página PHP além do meu arquivo Flash. No passado, tentei alguns métodos simples para fazer várias chamadas para uma única pontuação e concluir uma sequência de soma de verificação / fibonacci etc., além de ofuscar o SWF com o Amayeta SWF Encrypt, mas todos foram hackeados eventualmente.
Graças às respostas do StackOverflow, agora encontrei mais informações da Adobe - http://www.adobe.com/devnet/flashplayer/articles/secure_swf_apps_12.html e https://github.com/mikechambers/as3corelib - que acho que eu pode usar para a criptografia. Não tenho certeza se isso vai me levar ao redor do CheatEngine.
Preciso conhecer as melhores soluções para o AS2 e o AS3, se forem diferentes.
Os principais problemas parecem ser os cabeçalhos TamperData e LiveHTTP, mas entendo que também existem ferramentas de hackers mais avançadas - como o CheatEngine (obrigado Mark Webster)
Respostas:
Este é um problema clássico com jogos e concursos na Internet. Seu código Flash trabalha com os usuários para decidir uma pontuação para um jogo. Mas os usuários não são confiáveis e o código Flash é executado no computador do usuário. Você é SOL. Não há nada que você possa fazer para impedir que um invasor forje pontuações mais altas:
O Flash é ainda mais fácil de fazer engenharia reversa do que você imagina, pois os bytecodes estão bem documentados e descrevem uma linguagem de alto nível (Actionscript) --- quando você publica um jogo em Flash, publica seu código-fonte, independentemente de conheça ou não.
Os invasores controlam a memória de tempo de execução do interpretador Flash, para que qualquer pessoa que saiba usar um depurador programável possa alterar qualquer variável (incluindo a pontuação atual) a qualquer momento ou o próprio programa.
O ataque mais simples possível contra o seu sistema é executar o tráfego HTTP do jogo por meio de um proxy, capturar a pontuação mais alta e reproduzi-la com uma pontuação mais alta.
Você pode tentar bloquear esse ataque vinculando cada save de alta pontuação a uma única instância do jogo, por exemplo, enviando um token criptografado para o cliente na inicialização do jogo, que pode parecer:
(Você também pode usar um cookie de sessão para o mesmo efeito).
O código do jogo faz com que esse token retorne ao servidor com o salvamento de maior pontuação. Mas um invasor ainda pode simplesmente iniciar o jogo novamente, obter um token e colá-lo imediatamente em um save repetido de pontuação alta.
Então, em seguida, você alimenta não apenas um token ou cookie de sessão, mas também uma chave de sessão com criptografia de alta pontuação. Essa será uma chave AES de 128 bits, ela própria criptografada com uma chave codificada no jogo Flash:
Agora, antes que o jogo publique a pontuação mais alta, ele descriptografa a chave da sessão de criptografia de alta pontuação, o que pode ser feita porque você codificou a chave de decriptografia da chave de sessão de criptografia de alta pontuação no binário do Flash. Você criptografa a pontuação mais alta com essa chave descriptografada, juntamente com o hash SHA1 da pontuação mais alta:
O código PHP no servidor verifica o token para garantir que a solicitação veio de uma instância de jogo válida e descriptografa a pontuação máxima criptografada, verificando se a pontuação máxima corresponde ao SHA1 da pontuação máxima (se você pular esta etapa , a descriptografia simplesmente produzirá pontuações aleatórias, provavelmente muito altas e altas).
Portanto, agora o invasor descompila seu código Flash e encontra rapidamente o código AES, que se destaca como um polegar dolorido, embora, mesmo se não fosse, seria rastreado em 15 minutos com uma pesquisa de memória e um rastreador ("Eu sei minha pontuação neste jogo é 666, então vamos encontrar 666 na memória e capturar qualquer operação que toque nesse valor --- olha, o código de criptografia de alta pontuação! "). Com a chave da sessão, o invasor nem precisa executar o código Flash; ela pega um token de lançamento do jogo e uma chave de sessão e pode enviar de volta uma pontuação alta arbitrária.
Agora você está no ponto em que a maioria dos desenvolvedores simplesmente desiste - ou aproveite alguns meses para mexer com os invasores:
Embaralhar as teclas AES com operações XOR
Substituindo matrizes de bytes de chave por funções que calculam a chave
Espalhando criptografias de chaves falsas e postagens de alta pontuação em todo o binário.
Isso tudo é principalmente uma perda de tempo. Escusado será dizer que o SSL também não irá ajudá-lo; O SSL não pode protegê-lo quando um dos dois pontos de extremidade SSL é ruim.
Aqui estão algumas coisas que podem realmente reduzir a fraude de pontuação alta:
Exija um login para jogar, faça com que ele produza um cookie de sessão e não permita vários lançamentos pendentes de jogos na mesma sessão, nem várias sessões simultâneas para o mesmo usuário.
Rejeite pontuações altas de sessões de jogos que duram menos que os jogos reais mais curtos já realizados (para uma abordagem mais sofisticada, tente "colocar em quarentena" altas pontuações para sessões de jogos que durem menos de 2 desvios padrão abaixo da duração média do jogo). Verifique se você está acompanhando as durações dos jogos no servidor.
Rejeite ou coloque em quarentena as pontuações mais altas dos logins que apenas jogaram o jogo uma ou duas vezes, para que os atacantes tenham que produzir uma "trilha de papel" com uma jogabilidade de aparência razoável para cada login que criarem.
Pontuações "Heartbeat" durante o jogo, para que seu servidor veja o crescimento da pontuação ao longo da vida de um jogo. Rejeite pontuações altas que não seguem curvas de pontuação razoáveis (por exemplo, saltando de 0 a 999999).
Estado do jogo "Instantâneo" durante o jogo (por exemplo, quantidade de munição, posição no nível etc.), que você pode reconciliar posteriormente com as pontuações intermediárias registradas. Você nem precisa ter uma maneira de detectar anomalias nesses dados; você apenas precisa coletá-lo e, em seguida, pode voltar e analisá-lo se as coisas parecerem duvidosas.
Desabilite a conta de qualquer usuário que falhe em uma das suas verificações de segurança (por exemplo, sempre enviando uma pontuação alta criptografada que falha na validação).
Lembre-se, porém, de que você está apenas impedindo a fraude de pontuação alta aqui. Não há nada que você possa fazer para evitar isso. Se houver dinheiro em jogo no jogo, alguém derrotará qualquer sistema que você criar. O objetivo não é parar este ataque; é tornar o ataque mais caro do que ficar muito bom no jogo e derrotá-lo.
fonte
Você pode estar fazendo a pergunta errada. Você parece focado nos métodos que as pessoas estão usando para subir na lista de recordes, mas o bloqueio de métodos específicos só vai tão longe. Não tenho experiência com o TamperData, então não posso falar sobre isso.
A pergunta que você deve fazer é: "Como posso verificar se as pontuações enviadas são válidas e autênticas?" A maneira específica de fazer isso depende do jogo. Para jogos de quebra-cabeça muito simples, você pode enviar a pontuação juntamente com o estado inicial específico e a sequência de movimentos que resultaram no estado final e, em seguida, executar novamente o jogo no lado do servidor usando os mesmos movimentos. Confirme se a pontuação declarada é igual à pontuação calculada e aceite a pontuação apenas se corresponderem.
fonte
Uma maneira fácil de fazer isso seria fornecer um hash criptográfico do seu valor de pontuação máxima junto com a pontuação que ela própria. Por exemplo, ao postar os resultados via HTTP GET: http://example.com/highscores.php?score=500&checksum=0a16df3dc0301a36a34f9065c3ff8095
Ao calcular essa soma de verificação, um segredo compartilhado deve ser usado; esse segredo nunca deve ser transmitido pela rede, mas deve ser codificado no back-end do PHP e no front-end do flash. A soma de verificação acima foi criada anexando a sequência " secret " à pontuação " 500 " e executando-a no md5sum.
Embora esse sistema impeça um usuário de publicar pontuações arbitrárias, ele não impede um "ataque de repetição", em que um usuário repõe uma combinação de pontuação e hash calculada anteriormente. No exemplo acima, uma pontuação de 500 sempre produziria a mesma cadeia de hash. Parte desse risco pode ser atenuada pela incorporação de mais informações (como nome de usuário, carimbo de data e hora ou endereço IP) na cadeia de caracteres a ser hash. Embora isso não impeça a reprodução de dados, ele garantirá que um conjunto de dados seja válido apenas para um único usuário ao mesmo tempo.
Para evitar quaisquer ataques de repetição ocorra, algum tipo de sistema de desafio-resposta terá de ser criado, como o seguinte:
Lembre-se de que a segurança de qualquer uma das técnicas acima é comprometida se o segredo compartilhado estiver acessível ao usuário
Como alternativa, algumas dessas opções podem ser evitadas forçando o cliente a se comunicar com o servidor por HTTPS e assegurando que o cliente esteja pré-configurado para confiar apenas nos certificados assinados por uma autoridade de certificação específica, à qual você só tem acesso. .
fonte
Eu gosto do que o tpqf disse, mas, em vez de desativar uma conta quando a fraude é descoberta, implemente um honeypot para que, sempre que eles façam login, vejam suas pontuações hackeadas e nunca suspeitem que foram marcados como trolls. Pesquise no Google por "phpBB MOD Troll" e você verá uma abordagem engenhosa.
fonte
Na resposta aceita, o tqbf menciona que você pode fazer uma pesquisa na memória para a variável score ("Minha pontuação é 666, por isso procuro o número 666 na memória").
Existe uma maneira de contornar isso. Eu tenho uma aula aqui: http://divillysausages.com/blog/safenumber_and_safeint
Basicamente, você tem um objeto para armazenar sua pontuação. No setter, ele multiplica o valor que você passa com um número aleatório (+ e -), e no getter, você divide o valor salvo pelo multiplicador aleatório para recuperar o original. É simples, mas ajuda a interromper a pesquisa de memória.
Além disso, confira o vídeo de alguns dos responsáveis pelo mecanismo PushButton que falam sobre algumas das diferentes maneiras de combater os hackers: http://zaa.tv/2010/12/the-art-of-hacking-flash- jogos / . Eles foram a inspiração por trás da classe.
fonte
Eu fiz uma espécie de solução alternativa ... Eu dei um ponto onde as pontuações aumentavam (você sempre obtém +1). Primeiro, comecei a contar a partir de um número aleatório (digamos 14) e quando mostro as pontuações, apenas as pontuações var menos 14. Isso foi assim se os crackers estão procurando, por exemplo, 20, eles não a encontrarão ( será 34 na memória). Segundo, desde que eu sei qual deve ser o próximo ponto ... usei a biblioteca de criptografia da Adobe, para criar o hash do que o próximo ponto deveria ser. Quando preciso incrementar as pontuações, verifico se o hash das pontuações incrementadas é igual ao hash que deve ser. Se o cracker alterou os pontos na memória, os hashes não são iguais. Realizo algumas verificações do lado do servidor e, quando obtive pontos diferentes do jogo e do PHP, sei que havia trapaça. Aqui está um trecho do meu código (estou usando a classe MD5 do Adobe Crypto libraty e o sal de criptografia aleatória. CallPhp () é a validação do meu servidor)
Usando essa técnica + obfusão do SWF, consegui parar os crackers. Além disso, quando estou enviando as pontuações para o lado do servidor, uso minha própria função pequena de criptografia / descriptografia. Algo assim (código do lado do servidor não incluído, mas você pode ver o algoritmo e escrevê-lo em PHP):
Então eu envio a variável entre outros falsos vars e ela se perde no meio do caminho ... É muito trabalho apenas para pequenos jogos em flash, mas onde há prêmios envolvidos, algumas pessoas ficam gananciosas. Se precisar de ajuda, escreva-me um PM.
Saúde, Ico
fonte
Criptografar usando uma chave reversível (privada) conhecida seria o método mais simples. Eu não gosto muito do AS, então não tenho certeza de que tipos de provedores de criptografia existem.
Mas você pode incluir variáveis como a duração do jogo (criptografada novamente) e a contagem de cliques.
Todas essas coisas podem ter engenharia reversa, então considere lançar um monte de dados indesejados para tirar as pessoas do cheiro.
Edit: Pode valer a pena jogar em algumas sessões PHP também. Inicie a sessão quando eles clicarem em iniciar jogo e (como diz o comentário nesta postagem) registre a hora. Quando eles enviam a pontuação, você pode verificar se eles realmente têm um jogo aberto e não estão enviando uma pontuação muito cedo ou muito grande.
Pode valer a pena elaborar um escalar para ver qual é a pontuação máxima por segundo / minuto de jogo.
Nenhuma dessas coisas é incircunventável, mas ajudará a ter alguma lógica que não esteja no Flash, onde as pessoas possam vê-la.
fonte
Na minha experiência, isso é melhor abordado como um problema de engenharia social do que como um problema de programação. Em vez de se concentrar em tornar impossível trapacear, concentre-se em torná-lo chato, removendo os incentivos para trapacear. Por exemplo, se o principal incentivo for pontuações altas publicamente visíveis, simplesmente atrasar a exibição de pontuações altas pode reduzir significativamente as trapaças, removendo o ciclo de feedback positivo dos trapaceiros.
fonte
Você não pode confiar em nenhum dado retornado pelo cliente. A validação precisa ser realizada no lado do servidor. Não sou desenvolvedor de jogos, mas faço software comercial. Em ambos os casos, o dinheiro pode estar envolvido e as pessoas quebram as técnicas de ofuscação do lado do cliente.
Talvez envie dados de volta ao servidor periodicamente e faça alguma validação. Não se concentre no código do cliente, mesmo que seja aí que o seu aplicativo mora.
fonte
Sempre que o seu sistema de recordes se basear no fato de o aplicativo Flash enviar dados de recordes não criptografados / não assinados pela rede, eles podem ser interceptados e manipulados / reproduzidos. A resposta segue a partir disso: criptografar (decentemente!) Ou assinar criptograficamente dados de recordes. Isso, pelo menos, torna mais difícil para as pessoas violarem o seu sistema de recordes porque elas precisam extrair a chave secreta do seu arquivo SWF. Muitas pessoas provavelmente desistirão ali. Por outro lado, basta uma pessoa individual extrair a chave e publicá-la em algum lugar.
As soluções reais envolvem mais comunicação entre o aplicativo Flash e o banco de dados de recordes, para que este possa verificar se uma determinada pontuação é um pouco realista. Isso provavelmente é complicado, dependendo do tipo de jogo que você tem.
fonte
Não há como torná-lo completamente inalterável, pois é fácil descompilar SWFs, e um hacker de desenvolvedor qualificado pode rastrear seu código e descobrir como ignorar qualquer sistema criptografado que você possa empregar.
Porém, se você simplesmente deseja impedir que crianças trapaceiem usando ferramentas simples como o TamperData, pode gerar uma chave de criptografia que passa para o SWF na inicialização. Em seguida, use algo como http://code.google.com/p/as3crypto/ para criptografar a pontuação mais alta antes de transmiti-la ao código PHP. Em seguida, decifre-o no final do servidor antes de armazená-lo no banco de dados.
fonte
Você está falando sobre o que é chamado de problema "confiança do cliente". Como o cliente (nesse caixa, um SWF em execução no navegador) está fazendo algo para o qual foi projetado. Salve uma pontuação alta.
O problema é que você deseja garantir que as solicitações de "salvar pontuação" sejam provenientes do seu filme em flash, e não alguma solicitação HTTP arbitrária. Uma solução possível para isso é codificar um token gerado pelo servidor no SWF no momento da solicitação (usando flasm ) que deve acompanhar a solicitação para salvar uma pontuação alta. Depois que o servidor salvar essa pontuação, o token expirará e não poderá mais ser usado para solicitações.
A desvantagem disso é que um usuário poderá enviar apenas uma pontuação alta por carga do filme em flash - você precisará forçá-lo a atualizar / recarregar o SWF antes que ele possa reproduzir novamente para uma nova pontuação.
fonte
Normalmente, incluo "dados fantasmas" da sessão do jogo com a entrada de recordes. Então, se estou fazendo um jogo de corrida, incluo os dados de repetição. Você já tem os dados de repetição para funcionalidade de repetição ou de corrida fantasma (jogando contra sua última corrida ou contra o fantasma do cara n ° 14 na tabela de classificação).
Verificar isso é muito trabalhoso, mas se o objetivo é verificar se as 10 principais entradas de um concurso são legítimas, isso pode ser uma adição útil ao arsenal de medidas de segurança que outros já apontaram.
Se o objetivo é manter a lista de recordes on-line até o final dos tempos, sem que ninguém precise olhar para eles, isso não lhe trará muito.
fonte
A maneira que um novo mod de arcade popular faz é enviar dados do flash para o php, de volta para o flash (ou recarregá-lo) e depois para o php. Isso permite que você faça o que quiser para comparar os dados, além de ignorar os hacks pós-descriptografia / dados e afins. Uma maneira de fazer isso é atribuindo 2 valores aleatórios de php no flash (que você não pode capturar ou ver, mesmo executando um captador de dados em flash em tempo real), usando uma fórmula matemática para adicionar a pontuação aos valores aleatórios e verificando-a usando a mesma fórmula para invertê-lo para ver se a pontuação corresponde quando finalmente chega ao php no final. Esses valores aleatórios nunca são visíveis e também cronometram a transação e, se
Parece uma solução muito boa, se você me perguntar, alguém vê algum problema ao usar esse método? Ou possíveis maneiras de contornar isso?
fonte
Eu acho que a maneira mais simples seria fazer chamadas para uma função como RegisterScore (score) cada vez que o jogo registra uma pontuação a ser adicionada e depois a codifica, empacota e envia para um script php como uma string. O script php saberia decodificá-lo corretamente. Isso interromperia todas as chamadas diretamente para o script php, pois qualquer tentativa de forçar uma pontuação resultaria em um erro de descompressão.
fonte
Só é possível mantendo toda a lógica do jogo no servidor, que também armazena a pontuação internamente sem o conhecimento do usuário. Por razões econômicas e científicas, a humanidade não pode aplicar essa teoria a todos os tipos de jogos, exceto baseados em turnos. Por exemplo, manter a física no lado do servidor é computacionalmente caro e difícil de obter resposta como velocidade da mão. Mesmo possível, enquanto estiver jogando xadrez, qualquer um pode combinar a jogabilidade de IA com o oponente. Portanto, melhores jogos multiplayer também devem conter criatividade sob demanda.
fonte
Não é realmente possível alcançar o que você deseja. As partes internas do aplicativo Flash são sempre parcialmente acessíveis, especialmente quando você sabe usar coisas como o CheatEngine , o que significa que, por mais seguro que seja o seu site e o navegador <-> as comunicações do servidor, ainda será relativamente fácil de superar.
fonte
Pode ser uma boa ideia se comunicar com o back-end via AMFPHP . Isso deve desencorajar pelo menos os preguiçosos de tentar enviar os resultados pelo console do navegador.
fonte