Hola a todos, soy Nikita Kurtin, curadora del
departamento de informática y seguridad de la escuela secundaria israelí
HackerU .
Y sigo hablando sobre las pruebas cibernéticas de la compañía israelí líder en el campo de Checkpoint de seguridad de la información. En una
publicación anterior describí cómo pasé por cuatro pruebas, y en esto quiero hablar sobre las siguientes tres que logré aprobar.
Para aquellos que se perdieron la primera publicación, les contaré este verano
Checkpoint ha publicado una serie de pruebas cibernéticas.
El desafío finalizó oficialmente a fines de septiembre de 2018.
Las tareas se dividieron en seis categorías:
• lógica
• Web
• Programación
• Redes
• marcha atrás
• sorpresa
Dos tareas para cada dirección. Como ya
escribí , Checkpoint ya había logrado ganar respeto e interés por mi parte, así que decidí aceptar estos desafíos. Sin embargo, debido al empleo, pude permitirme asumir solo 8 de 12 tareas (de cuatro categorías diferentes). Y logré resolver 7 de ellos.
Y entonces:
Desafío: rompecabezas
Descripción:
Finalmente te encontramos!
Necesitamos armar este rompecabezas, y como dice la profecía, solo tú eres capaz de hacerlo.
El rompecabezas es muy extraño. Consiste en un tablero con 10 columnas y 10 filas. En total - 100 partes. ¡Y cada uno de ellos lleva un misterio! Las partes constan de cuatro partes: superior, inferior, derecha e izquierda. Cada latido es un número. Por ejemplo:
Arriba - 12, derecha - 3, abajo - 4 e izquierda - 5.
Para que el rompecabezas se desarrolle, todos los detalles deben colocarse en el tablero para que cada pieza se una al mismo valor.
Además, una fracción que no está contigua a nada pero que es parte del límite del tablero debe establecerse en 0. Las fracciones restantes no pueden tener un valor cero. Aquí hay un ejemplo válido de 4 partes:

En la parte superior del tablero, todos los lóbulos que forman el borde son cero.
Considere la parte superior izquierda. Su lóbulo derecho es 9, y el lóbulo adyacente (lóbulo izquierdo de la parte superior derecha) también es 9.
Desafortunadamente, todos nuestros detalles se barajan. Se dan en el siguiente formato:
Id del cubo [fracción]; identificación del cubo, [acciones]; ... identificación del cubo, [acciones]
Donde la identificación del cubo son números del 0 al 99, y las fracciones consisten en números ordenados en orden: superior, derecha, inferior, izquierda.
Por ejemplo, mira el siguiente tablero barajado:

Aquí está la línea que describe este tablero:

¡Te necesitamos para armar el rompecabezas!
Escríbanos una línea que se vea exactamente así:
Id del cubo, cuántas veces se debe girar en sentido horario; ID del cubo, cuántas veces se necesita girar en sentido horario; ... ID del cubo, cuántas veces se debe girar en sentido horario
La línea con la solución para esta placa se verá así:

La línea anterior corresponde al siguiente rompecabezas (resuelto):

Considere la parte superior izquierda. En la línea, corresponde a la designación "2.2". ¿Cómo tomamos el cubo número 2 de la entrada?

Pero lo giramos dos veces en el sentido de las agujas del reloj y obtenemos [0,19,5,0].
Ahora considere la parte media superior. En la línea, corresponde a la designación "1.0". Por lo tanto, tomamos el cubo número 1 de la entrada:

Y no lo gire en absoluto (sí, gírelo 0 veces), significa que ya está en la posición correcta.
Lo tengo?
¡Ahora ayúdanos a armar el rompecabezas!
Se ve así:

Buena suerte
Teóricamente, este problema se puede resolver de muchas maneras diferentes. Encuentra el tuyo y compártelo. Medité varias opciones y finalmente llegué a las siguientes conclusiones:
El primero En cualquier momento, solo necesito definir un cubo. Para cada cubo, siempre sabré con certeza dos lados: el superior y el izquierdo. Al principio es 0 y 0. El siguiente cubo en la parte superior también tendrá 0, y a la izquierda habrá un dígito correspondiente al número del lóbulo derecho del cubo anterior.
El segundo Debido a la gran cantidad de variaciones diferentes entre los cubos, debería intentar hacer el menor número de pasos posible y deshacerme de una comprobación sin sentido en el primer resultado negativo.
El tercero Para trabajar con diferentes cubos, siempre necesito recordar su posición inicial (id), el número de vueltas desde el punto de partida y, aparentemente, el número de lados (arriba, derecha, abajo, izquierda).
Cuarto. La entrada inicial es una cadena. Y la salida también es una cadena (y no la posición actual).
Basado en todo esto, desarrollé la siguiente estrategia para mí:
Muévase linealmente, de izquierda a derecha hasta que llegue a la esquina derecha. Luego, baja una línea y comienza a la izquierda con el número más bajo del cubo, que se encuentra arriba.
El cumplimiento debe verificarse después de cada rotación. Entonces, si ya has completado 4 turnos y aún no hay una sola coincidencia para este cubo, tomo la siguiente. Cada cubo marcado se puede verificar potencialmente con todos los demás detalles, para esto puedo repetir de forma recursiva la inicialización de cada uno de ellos con un conjunto completo de todos los demás cubos.
Para realizar un seguimiento de todas las manipulaciones con los datos de origen, elegí un método de programación orientado a objetos en el que un cubo es un objeto que tiene una identificación, el número de rotaciones y cuatro lados: superior, derecho, inferior e izquierdo.
En lugar de copiar el estado inicial y evitar falsos recuentos después de varios giros, siempre aumentó el recuento en uno. Pero cuando verifiqué el número final de rotaciones, usé el módulo (resto de división) por 4.
Por ejemplo, si se necesita una rotación (de [1,2,3,4] a [4,1,2,3]), pero al principio se realizaron tres rotaciones erróneamente (actualmente [2,3,4,1] ), la próxima vez tomará 2 (del actual [2,3,4,1] al necesario [4,1,2,3]). 3 más 2 es 5. Y 5% 4 = 1, y esto es lo que necesita.
Siempre necesito hacer un seguimiento de los cubos utilizados y evitar nuevas comprobaciones. Para esto, uso una tabla de cubos de identificación. Y si el cubo que se compara coincide, lo elimino de la lista.
Seleccioné las siguientes estructuras de datos:
HashMap: para enlazar id (posición inicial) y un cubo construido a partir de la cadena de entrada.
Pila: para verificar los cubos de identificación relacionados.
Matriz: para probar temporalmente el resultado.
Cubo de código de objeto:

Funciones de manipulación de cadenas:

La lógica de la solución para encontrar cubos coincidentes:

Resultado:
Desafío: ping pong
Descripción:
Apuesto a que no eres lo suficientemente rápido como para vencerme.
Aquí es donde estoy:
nc 35.157.111.68 10158Al ejecutar este comando, obtienes:

A primera vista, parece que esta es una tarea para trabajar con flujos.
Sin embargo, después de recibir los primeros datos, parece que cae en el tiempo de espera, y luego por completo, se cubrirá.
Cuando finalizan los datos, aparece un nuevo separador de línea.
Recreé la secuencia usando el código Python.
Parece funcionar, así que agregué un código iterativo que repite el algoritmo de ping-pong y esperaré hasta que aparezca la bandera.

Después de una gran cantidad de tales reorganizaciones de ping-pong (quizás más de mil) entre el cliente y el servidor, finalmente hago las cosas.
Desafío: "Protocolo"
Descripción:
Hola
Necesitamos extraer los datos secretos de un servidor especial. No sabemos mucho sobre él, pero logramos interceptar el tráfico que admite la comunicación con este servidor.
También sabemos que la ruta a este archivo secreto es: /usr/PRivAtE.txt
Puede encontrar el archivo sniff aquí (enlace al archivo).
¡Cuéntanos cuál es el secreto!
Buena suerteDescargué el archivo y lo abrí usando Wireshark

Y revisé las negociaciones registradas

Me permitió descubrir qué estaba pasando.

Noté que había negociaciones entre IP 35.157.111.68 a través del puerto 20120 y el puerto SSH 22. Decidí verificar este puerto 20120 y luego cambiar a SSH (más tarde me di cuenta de que esto no era necesario).
Utilicé el comando nc para verificar esta IP y puerto, y recibí una respuesta: "0 8 Bienvenido"

No estaba seguro de qué información esperaba, así que volví a Wireshark para ver si quedaban pistas.
Filtré todos los paquetes de datos para 35.157.111.68 en el puerto 20120 y encontré una conversación fácil de leer:





Recreé todo esto usando la línea de comando nc:

Noté que la respuesta a mi solicitud "2 3 XOR" era diferente de la que estaba en el archivo.
Repetí todo el procedimiento una y otra vez para ver si la respuesta cambiaba cada vez.


Como pensé, los 4 valores obtenidos fueron diferentes cada vez, al igual que los datos finales.
Los cuatro valores obtenidos parecen ser la clave para descifrar los datos finales.
También noté que los números antes de cada paquete de datos no son aleatorios.
Se ve de la siguiente manera.
El primer número significa orden: 0 -> primero, 1 -> segundo, 2 -> tercero, etc.
El segundo número significa la duración de la frase 8 -> "Bienvenido", 5 -> "Hola" ->, etc.
Pensé si esta no es la clave para el descifrado. Dado que los datos finales son una fila continua de bloques de 4 valores HEX y la tecla XOR también tiene 4 valores HEX. Tal vez pueda iterar sobre cada uno y dividirlo en bytes separados, y luego morderlos con bytes de la clave.
Y traté de descifrar:

Todo resultó, pero no había bandera en los datos recibidos.

Releí las reglas y recordé que la ruta a este archivo secreto es la siguiente: /usr/PRivAtE.txt
Repetí el procedimiento nuevamente, pero esta vez solicité la ruta "/usr/PRivAtE.txt"

Intenté nuevamente descifrar los datos finales:

Y la bandera estaba en mis manos:

¿Tuviste éxito? Escriba sus ideas y opciones, estaré encantado de comentar.