¿Cómo puedo evitar informes de puntajes falsos en tablas de puntaje global?

44

Los juegos para navegadores y dispositivos móviles suelen tener tablas de puntaje global. También es común que esas tablas contengan puntajes de 2,147,483,647, donde la gente descubrió la llamada al servicio web que informa los puntajes y la utilizó para registrar un puntaje ficticio.

Para juegos de rompecabezas simples, podemos defendernos de esto al incluir un registro de cada movimiento que hizo el jugador (y cualquier semilla aleatoria utilizada para generar el nivel) con la llamada de informe de puntaje. Todo el juego se puede reproducir y verificar en el servidor.

Sin embargo, esto rápidamente se vuelve inviable para cualquier cosa más grande que Pac-man.

¿De qué otra forma se pueden evitar las trampas de este tipo?

teedyay
fuente
Tenía exactamente la misma pregunta con respecto a los juegos de iPhone que usan la misma técnica para crear una tabla global de puntajes.
deft_code
¿Estás seguro de que no sería factible enviar la repetición?
o0 '.
Sí, estoy seguro. :)
teedyay

Respuestas:

9

El sistema interno que utilizamos para Moblox (luego reemplazado por OpenFeint) funcionó así:

  • Envíe un mensaje JSON a través de HTTP simple (no HTTPS). Incluya un hash MD5 de todos los campos más una cadena mágica.
  • En el servidor, verifique la integridad del mensaje con la misma operación.

Para descifrar el sistema, tendrías que encontrar esta cuerda mágica. Es posible con ingeniería inversa, pero doloroso.

OpenFeint, ScoreLoop y CocosLive usan el mismo truco, pero con HTTPS. Muy fácil de implementar.

Ellis
fuente
29
Tengo muchas dudas de que la ingeniería inversa para encontrar tu cuerda mágica sea tan difícil.
Kylotan
44
Esta es una aplicación de Android en C ++ nativo. No hay símbolo, ni buen depurador disponible. Entonces puede leer el código ARM, pero no rastrearlo fácilmente. La clave está compuesta por múltiples operaciones, por lo que encontrar todas las cadenas no es suficiente. Eso no es perfecto pero sí bastante doloroso.
Ellis
3
Un ejercicio estándar de pregrado, al menos en las universidades de EE. UU., Consiste en aplicar ingeniería inversa a las contraseñas construidas como usted describe, leyendo el código de ensamblaje y86 ( cgi2.cs.rpi.edu/~hollingd/comporg-spring2007/notes/Y86/… ).
12
Esta es una técnica terriblemente débil , que dará a los desarrolladores una falsa sensación de seguridad.
o0 '.
2
Este es un muy buen ejemplo de en.wikipedia.org/wiki/Security_through_obscurity
kaoD
21

Si bien tiene razón en que no siempre es factible enviar repeticiones completas al servidor para juegos complejos, se puede usar un sistema similar haciendo que el servidor le pregunte periódicamente al cliente (y de forma semialeatoria) alguna parte de su estado, mientras que El juego se está ejecutando.

Por ejemplo, en un FPS, cada minuto puedes preguntar "¿Cuántas muertes tienes?", "¿Dónde están todos los enemigos?", Etc. Si el cliente no regresa con una respuesta razonable a un desafío en un cantidad de tiempo razonable, están haciendo trampa.

Por supuesto, esto solo funciona si el juego está en línea durante toda la sesión de juego. Dado que el objetivo aquí es poder subir a una tabla de clasificación en línea, creo que es razonable: no expulse al jugador del juego si responde mal, simplemente no lo deje en la lista de puntajes.

Sin embargo, te animo a que reconsideres el envío de repeticiones. Todo lo que realmente necesita es la semilla inicial aleatoria y la entrada con marca de tiempo. Esto realmente debería ser unos cientos de KB como máximo. Muchos juegos de arcade ya hacen esto para guardar las repeticiones para los propósitos de revisión del jugador; hacer que su servidor los valide puede no ser trivial, pero evita todo tipo de trampas, excepto botting.


fuente
10

Puede limitar los abusos más flagrantes al monitorear los resultados más altos en la tabla de puntaje más alto. Dependiendo de su juego, puede tener un "puntaje perfecto", por encima del cual cualquier puntaje debe ser fraudulento. Si no, puede calcular el "puntaje imposible" más bajo; ¿Puede el jugador disparar 10 disparos por segundo, el juego dura 1 minuto y cada enemigo muerto vale 100 puntos? Entonces cualquier puntaje superior a 60,000 debe ser fraudulento.

También puede ayudar a mitigar el problema enviando algunos metadatos; no se describe el historial completo del juego, como lo describe, sino solo los componentes que conforman la puntuación. Diga: anote 60000, 500 enemigos asesinados, y agarre un objeto extra. Luego puede realizar verificaciones simples. Esto es "seguridad a través de la oscuridad" y, por lo tanto, no es seguro en absoluto, pero ayuda a eliminar a los atacantes más ingenuos.

Gregory Avery-Weir
fuente
También puede marcar un usuario (posiblemente por IP) si envía una puntuación que no coincide con los metadatos. Luego, si intentan enviar una puntuación nuevamente que TIENE los metadatos correctos, puede analizarla y, posiblemente, simplemente prohibirlos por completo. También puede enviar un mensaje descarado desde allí enviar solicitud de puntuación :)
Adam Harte
Creo que esta respuesta es mejor que la respuesta aceptada. Solo averigua qué número es el máximo que tus jugadores pueden alcanzar. Algo más alto, solo descartar.
66
Entonces, si un jugador que va a una universidad hace trampa, todos en la red ahora son un "tramposo"
AttackingHobo
6

En última instancia, solo puede descartar puntajes imposiblemente altos, porque el resto son (por definición) meramente inverosímiles y, por lo tanto, podrían ser un jugador legítimo (e increíble).

De lo contrario, debe confiar en las técnicas de ofuscación (como el cifrado y el envío de otras estadísticas más allá de la puntuación).

También puede enviar el puntaje periódicamente a medida que se juega el juego, lo que agregaría otro nivel de complejidad a las trampas, es decir, el servidor puede decidir si el juego se ha jugado lo suficiente como para garantizar un puntaje particular, y también garantizar que haya suficientes informes intermedios. fueron recibidos durante el tiempo de juego (simplemente no lo hagas al 100% o el tren que vaya a un túnel en mi camino a casa provocará que tire el teléfono por la ventana).

Sin embargo, en última instancia, alguien encontrará una manera de romperlo, así que no te mates tratando de detenerlo.

JasonD
fuente
6

Agregué una tabla de puntaje rápido / sucio a un proyecto mío hace un tiempo y, al no estar versado en absoluto en seguridad de Internet, etc., resultó ser algo defectuoso. Sorprendentemente, con casi 1,200,000 puntajes registrados, solo he tenido quizás 5 o 6 ocasiones de lotes de puntajes descaradamente incorrectos que alcanzan la parte superior del tablero. La mayoría de los puntajes incluso parecían más una falla en el juego que un verdadero "pirateo".

Así que supongo que un punto importante es: asegúrese de que el sistema de puntaje de su juego sea hermético , o al menos haga una buena verificación de factibilidad de puntaje; ahora, este juego del que estoy hablando era una entrada de Ludum Dare de 48 horas, por lo que no era lo más estable ... pero en general creo que a menudo es más probable que el jugador casual descubra / explote una falla en el juego que hacer que alguien "piratee" directamente la tabla de clasificación

Dicho esto, estoy trabajando en una reescritura de este proyecto en este momento, y voy a salir con la ofuscación. No voy a entrar en demasiados detalles, pero básicamente hago que todas las puntuaciones envíen un valor clave basado en un grupo de valores aleatorios y hashing y una cadena mágica, luego cualquier puntuación que pase esa verificación y sea lo suficientemente alta como para hacer el verdadero " La tabla de clasificación Top X "tiene que pasar otra ronda de validación (esta vez con un valor de clave que caduca generado en el servidor y verificaciones de viabilidad más exhaustivas).

También recomendaría usar un rastreador de paquetes de algún tipo para probar qué tipo de cosas son visibles (originalmente estaba haciendo una verificación mucho más simple que significaba que alguien podría usar un rastreador de paquetes para encontrar y duplicar la solicitud http de una puntuación cargada, sin saberlo la cadena mágica o cualquier cosa (significaba que primero necesitabas un puntaje legítimo, pero podías enviar duplicados de ese puntaje tanto como quisieras ...)). Solía Wireshark para probar esto.

Eh, esto resultó un poco largo, pero espero que ayude ...

Riley Adams
fuente
Ciertamente lo es. Parece que un hash salado es un buen camino a seguir. No había considerado que volverían a enviar el mismo puntaje válido muchas veces. Un GUID y una marca de tiempo incluida en el paquete (y en el hash) deberían pagarse. Puedo verificar si hay engaños en el servidor. Gracias.
teedyay
3

No soy un experto en este campo, pero si fuera usted, trataré de cifrar el puntaje con una clave incrustada en su código. Esas personas necesitarán aplicar ingeniería inversa sobre su código en lugar del texto sin formato utilizado para los servicios web.


fuente
2
Yo iría incluso uno más. Genere un hash a partir del código troceando el archivo exe (o parte de él). Al enviar puntuaciones, envíe el número de versión y el servidor puede validar utilizando una tabla que tenga constantes simples número de versión-> código hash. Luego obtienes el bono adicional de que si alguien hace trampa modificando el programa, su puntaje más alto no contaría.
configurador
77
Si alguien está modificando el programa, ya puede enviar la clave que desee.
2
@ Joe Wreschnig, pueden enviar cualquier clave que deseen, pero el servidor debe configurarse para aceptar solo claves válidas.
AttackingHobo
55
Creo que el punto de Joe fue que no tienen que usar el hash del programa recién modificado, sino que pueden enviar lo que sea que haya sido el hash anterior.
Kylotan
1
@ gd1: ¿cómo ayuda eso?
Kylotan
1

Las carreras rápidas básicamente están grabando cada golpe de teclado, y están grabando sobre un juego ENTERO. Entonces, sí, puedes grabar todo el juego, no es inviable. Cualquier otra forma de hacerlo es descifrable a través de la ingeniería inversa (no puedo enfatizarlo lo suficiente: no está agregando seguridad, está agregando oscuridad).

Aún así, incluso si lo haces de esta manera, podrían enviar un speedrun. No puedes hacer nada para evitar eso.

o0 '.
fuente
2
Por lo general, la reproducción, no la grabación, es la parte que no es factible para el servidor. Si el cliente ha estado jugando el juego durante un par de horas, la resimulación del lado del servidor podría tomar muchos minutos de CPU o peor. Eso no es realmente aceptable si hay muchas personas que envían puntajes.
2
El tamaño del paquete de datos se convertiría en un problema para los juegos móviles, especialmente si el jugador paga su ancho de banda por byte.
teedyay
Oh, lo que ambos dicen es verdad. Aún así, no hay otra solución "real".
o0 '.
11
No tiene que validar cada grabación enviada, solo tiene que validar las que llegan al top 10. No tiene mucho sentido hacer trampa para convertirse en el # 11. Y no tienes que hacerlo en tiempo real. El proceso por lotes periódico estaría bien.
gris
@teedyay Digamos que el jugador realiza un promedio de 5 acciones por segundo, y cada acción se puede describir completamente en 32 bits. Eso es 20 bytes por segundo o 72 kB por hora. El precio típico de datos móviles en EE. UU. Es de $ 10 por GB, o 1 centavo por 1000 kB.
Damian Yerrick
1

Mientras lo hace, está la cuestión de si un puntaje alto es simplemente un jugador que encontró un exploit (por ejemplo, si algunas cosas en el juego dan una penalización de puntaje, y un error hace que un puntaje negativo se "encierre" para volverse altamente positivo ... o simplemente un jugador que encuentra una determinada condición de juego como un lugar seguro en el tablero donde simplemente pueden sentarse allí y no tener que preocuparse por perder, indefinidamente).

Para distinguir la diferencia entre un hack y un exploit de juego, cargar al menos algunos datos de juego sería bueno. Te ayudará a arreglar las hazañas, al menos.

Para algunos juegos (particularmente los basados ​​en turnos), puedes hacer que el juego se juegue a través del servidor, donde toda la lógica del juego existe en el lado del servidor y el cliente es solo una interfaz. Esto no solo hace que el pirateo de puntajes sea mucho más difícil, sino que también te permite registrar todas las acciones de los jugadores en el servidor de manera trivial y, por lo tanto, reproducir cualquier juego en cualquier momento. Me doy cuenta de que algo así como un tirador de acción de contracción, esto podría ser poco práctico.

Ian Schreiber
fuente
1

Haga todo el origen de aleatoriedad de una semilla y almacene la entrada para cada cuadro. Siempre que tenga un puntaje alto reclamado (digamos los 50 mejores), envíe la semilla y la entrada completa al servidor. Vuelve a jugar el juego en el servidor y actualiza la tabla de clasificación si obtienes una puntuación alta.

Si considera que esto no es factible para juegos más sofisticados debido al tamaño de la solicitud, eche un vistazo a este ejemplo.

Digamos que el juego tiene 8 botones de entrada (1 pad y 4 botones) y funciona a 60 fps. Una entrada de juego de una hora se puede transmitir con 3.6 KB sin compresión. Su sesión probablemente tendrá menos de una hora y la compresión debería reducirla mucho, porque la entrada humana tiene mucha redundancia.

El desafío es hacer que el juego sea determinista, jugable desde la entrada grabada y ejecutable en el servidor.

Vinicius Canaa
fuente
0

Nunca implementé esto antes pero ...

Envíe puntajes incrementalmente con marcas de tiempo. Esto le proporciona un registro para ver con qué frecuencia mejoró la puntuación, así como una forma de rastrear el "impulso" de la puntuación más alta.

Luego establecería hitos / criterios para sus puntajes.

Por ejemplo: un puntaje mayor a 20,000 no puede llegar en los primeros 20 segundos de un juego. Un puntaje mayor a 250,000 no puede llegar sin una entrada mayor a 200,000.

Esto no es exactamente lo mismo que enviar un estado de juego, pero cercano.

Beneficio secundario: piense en todas las estadísticas útiles de juego que obtendrá de esto. Alguien probablemente pagaría un buen dinero por eso.

Markus
fuente