Creo que esta prueba nos llevó más del 50% del tiempo del HackIt de este año :-O , pero es el tipo de prueba que nos encanta: sabes lo que hay que hacer, pero es un camino tortuoso, doloroso y complejo. A por ello 🙂
Analizamos el dump y vemos que se trata de un pcap. Lo abrimos con Wireshark y curioseamos un rato.
Ese puerto tcp/25565 se nos hace conocido…
Yep, Minecraft. En el servidor 51.15.21.7. Aquí otra vez fuimos troleados por @imobilis… o tal vez se trataba de un easter-egg en la prueba 🙂 El caso es que ese servidor existe (!) y tiene un mundo en el que apareces encima de una torre de la que no es posible salir. Incluso tiene mensajes en algunos carteles (por supuesto los probamos todos, sin éxito), como el de la imagen (Mundo Survival Kots)
El dump tiene mensajes enviados del cliente (10.11.12.52) al servidor (51.15.21.7) y viceversa. El payload de los mensajes es (parecía!) claro y se puede extraer con tshark.
$ tshark -r dump -T fields -e data
1b0010408d2e07aeae7d91401400000000000040855ae9b632828401
12004a0000000059c86aa10000000000001ac9
0a0021000000028daf8dbd
0a000e000000028daf8dbd
Aquí nos las prometíamos muy felices, porque vimos que había analizadores del protocolo Minecraft para Wireshark, como este o este. Todo muy de color rosa… hasta que nos fijamos en la fecha del último commit: 2010. Qué bien… no nos valen para nada. Así que, nos remangamos, fuimos a por café, y nos pusimos a estudiar la especificación del protocolo Minecraft, que está escrito por alguien que parece que tomaba apuntes de una charla, más que una especificación bien redactada. Hay exactamente 0 ejemplos de las partes más engorrosas (VarInt, packets with compression, …) En fin, nuestro compañero Joserra, un Excel wizard, decidió que nuestros scripts eran una **** mierda y que lo iba a hacer en Excel ¯_(ツ)_/¯
Si tomamos el primer payload, 001b es el tamaño del paquete (27 bytes), 0x10 el packetID y 408d2e07aeae7d91401400000000000040855ae9b632828401 el payload del paquete. El 0x10 es el ID de un paquete de tipo «Player Position» (Bound to server indica que es el cliente el que le envía al servidor). El payload se divide en 4 campos: x (double), feet y (double), z (double), «on ground» (boolean). Todos los paquetes de posición (0x10, server bound) son impares, por lo que terminan en 1 (true, on ground). Nos interesa conocer x, y, z.
x= 408d 2e07 aeae 7d91
y = 4014 0000 0000 0000
z = 4085 5ae9 b632 8284
Para pasar de hex a double, invocamos una macro, hex2dbl
y obtenemos las posiciones x,y,z.
Finalmente, generamos un gráfico de dispersión y obtenemos la clave 🙂
Atentos a las mayúsculas, minúsculas, 0 vs. O, 1 vs. I, etc… Fue la troleada final a una buena prueba 🙂
BLoCkD3f1nEdPrOt0coL
UPDATE: @navarparty (los primeros en lograr superar este reto) ha publicado su solución (en Go!). Thanks @tatai!
También recomiendo leer el write-up de w0pr y su elegante solución en Python + pygame.