Bonjour à tous, je suis Nikita Kurtin, conservatrice du
lycée israélien
HackerU informatique et sécurité.
Et je continue de parler des cyber-tests de la société israélienne leader dans le domaine de la sécurité de l'information Checkpoint. Dans un
post précédent, j'ai décrit comment j'ai passé quatre tests, et dans ce document, je veux parler des trois suivants que j'ai réussi à passer.
Pour ceux qui ont raté le premier post, je vous dirai cet été que
Checkpoint a publié une série de cyber-tests.
Le défi a officiellement pris fin fin septembre 2018.
Les tâches étaient divisées en six catégories:
• Logique
• Web
• Programmation
• Réseautage
• Inverser
• Surprise
Deux tâches pour chaque direction. Comme je l'ai déjà
écrit , Checkpoint avait déjà réussi à gagner le respect et l'intérêt de ma part, j'ai donc décidé d'accepter ces défis. Cependant, en raison de mon emploi, je n'ai pu me permettre que 8 des 12 tâches (de quatre catégories différentes). Et j'ai réussi à en résoudre 7.
Et donc:
Défi: Puzzle
Description:
Enfin, nous vous avons trouvé!
Nous devons assembler ce puzzle, et comme le dit la prophétie - vous seul en êtes capable.
Le puzzle est très bizarre. Il se compose d'un tableau avec 10 colonnes et 10 lignes. Au total - 100 pièces. Et chacun d'eux porte un mystère! Les parties se composent de quatre parties: supérieure, inférieure, droite et gauche. Chaque battement est un nombre. Par exemple:
Haut - 12, droite - 3, bas - 4 et gauche - 5.
Pour que le puzzle se développe, tous les détails doivent être placés sur le plateau de sorte que chaque pièce soit à la même valeur.
De plus, une fraction qui ne se joint à rien mais fait partie de la limite de la carte doit être définie sur 0. Les fractions restantes ne peuvent pas avoir une valeur nulle. Voici un exemple valide de 4 parties:

En haut de la planche, tous les lobes formant la bordure sont nuls.
Considérez la partie supérieure gauche. Son lobe droit est 9, et le lobe adjacent (lobe gauche de la partie supérieure droite) est également 9.
Malheureusement, tous nos détails sont mélangés. Ils sont donnés dans le format suivant:
Id du cube [fraction]; id de cube, [partages]; ... id de cube, [partages]
Où l'id du cube est des nombres de 0 à 99, et les fractions sont constituées de nombres disposés dans l'ordre: supérieur, droit, inférieur, gauche.
Par exemple, regardez le tableau mélangé suivant:

Voici la ligne qui décrit ce forum:

Nous avons besoin de vous pour assembler le puzzle!
Écrivez-nous une ligne qui ressemblerait exactement à ceci:
Id du cube, combien de fois il doit être tourné dans le sens horaire; id du cube, combien de fois il doit être tourné dans le sens des aiguilles d'une montre; ... id du cube, combien de fois il doit être tourné dans le sens des aiguilles d'une montre
La ligne avec la solution pour cette carte ressemblera à ceci:

La ligne ci-dessus correspond au puzzle (résolu) suivant:

Considérez la partie supérieure gauche. Dans la ligne, il correspond à la désignation "2.2". Comment prendre le cube numéro 2 en entrée:

Mais nous le tournons deux fois dans le sens horaire et obtenons [0,19,5,0].
Considérons maintenant la partie centrale supérieure. Dans la ligne, il correspond à la désignation "1.0". Par conséquent, nous prenons le cube numéro 1 de l'entrée:

Et ne le tournez pas du tout (oui, tournez-le 0 fois) - cela signifie qu'il est déjà dans la bonne position.
Vous avez compris?
Aidez-nous à assembler le puzzle!
Cela ressemble à ceci:

Bonne chance
Théoriquement, ce problème peut être résolu de différentes manières. Trouvez le vôtre et partagez-le. J'ai réfléchi à plusieurs options et suis finalement parvenu aux conclusions suivantes:
Le premier. À tout moment, il me suffit de définir un cube. Pour chaque cube, je connais toujours avec certitude deux côtés: le haut et la gauche. Au début, c'est 0 et 0. Le cube suivant en haut aura également 0, et à gauche il y aura un chiffre correspondant au numéro du lobe droit du cube précédent.
Le deuxième. En raison du grand nombre de variations différentes entre les cubes, je devrais essayer de faire le moins d'étapes possible et de me débarrasser d'un contrôle sans signification au premier résultat négatif.
Le troisième. Pour travailler avec différents cubes, je dois toujours me souvenir de leur position initiale (id), du nombre de tours depuis le point de départ et, apparemment, du nombre de côtés (en haut, à droite, en bas, à gauche).
Quatrièmement. L'entrée initiale est une chaîne. Et la sortie est également une chaîne (et non la position actuelle).
Sur la base de tout cela, j'ai développé la stratégie suivante pour moi:
Déplacez-vous linéairement - de gauche à droite jusqu'à ce que vous atteigniez le coin droit. Ensuite, descendez une ligne et commencez à gauche avec le numéro inférieur du cube, qui se trouve au-dessus.
La conformité doit être vérifiée après chaque rotation. Donc, si vous avez déjà terminé 4 tours et qu'il n'y a toujours pas une seule correspondance pour ce cube, je prends le suivant. Chaque cube vérifié peut potentiellement être vérifié avec tous les autres détails, pour cela, je peux répéter récursivement l'initialisation de chacun d'eux avec un ensemble complet de tous les autres cubes.
Pour suivre toutes les manipulations avec les données sources, j'ai choisi une méthode de programmation orientée objet dans laquelle un cube est un objet qui a un identifiant, le nombre de rotations et quatre côtés: haut, droit, bas et gauche.
Au lieu de copier l'état initial et d'éviter les faux comptes après plusieurs tours, j'ai toujours augmenté le nombre d'un. Mais quand j'ai vérifié le nombre final de rotations, j'ai utilisé le modulo (reste de division) par 4.
Par exemple, si une rotation est nécessaire (de [1,2,3,4] à [4,1,2,3]), mais au début, trois rotations ont été effectuées par erreur (actuellement [2,3,4,1] ), la prochaine fois il en faudra 2 (du [2,3,4,1] actuel au [4,1,2,3] nécessaire). 3 plus 2 est 5. Et 5% 4 = 1, et c'est ce dont vous avez besoin.
J'ai toujours besoin de garder une trace des cubes utilisés et d'éviter les revérifications. Pour cela, j'utilise une table de cubes id. Et si le cube comparé correspond, je le supprime de la liste.
J'ai sélectionné les structures de données suivantes:
HashMap - pour lier id (position initiale) et un cube construit à partir de la chaîne d'entrée.
Pile - pour vérifier les cubes id associés.
Array - pour tester temporairement le résultat.
Cube de code objet:

Fonctions de manipulation des chaînes:

La logique de la solution pour trouver des cubes correspondants:

Résultat:
Défi: Ping Pong
Description:
Je parie que tu n'es pas assez rapide pour me battre.
C'est là que je suis:
nc 35.157.111.68 10158En exécutant cette commande, vous obtenez:

À première vue, il semble que ce soit une tâche pour travailler avec des flux.
Cependant, après avoir reçu les premières données, il semble qu'elles tombent dans Timeout, puis complètement - seront couvertes.
Une fois les données terminées, un nouveau séparateur de ligne apparaît.
J'ai recréé le flux en utilisant du code Python.
Cela semble fonctionner, j'ai donc ajouté un code itératif qui répète l'algorithme de ping-pong, et j'attendrai que l'indicateur apparaisse.

Après un grand nombre de tels remaniements de ping-pong (peut-être plus d'un millier) entre le client et le serveur, je fais enfin avancer les choses.
Défi: «Protocole»
Description:
Salut, là!
Nous devons extraire les données secrètes d'un serveur spécial. Nous ne savons pas grand-chose de lui, mais nous avons réussi à intercepter le trafic qui prend en charge la communication avec ce serveur.
Nous savons également que le chemin d'accès à ce fichier secret est: /usr/PRivAtE.txt
Vous pouvez trouver le fichier sniff ici (lien vers le fichier).
Dites-nous quel est le secret!
Bonne chanceJ'ai téléchargé le fichier et l'ai ouvert à l'aide de Wireshark

Et vérifié les négociations enregistrées

Cela m'a permis de comprendre ce qui se passait.

J'ai remarqué qu'il y avait des négociations entre IP 35.157.111.68 via le port 20120 et le port SSH 22. Je devrais vérifier ce port 20120, j'ai décidé, puis passer à SSH (plus tard, j'ai réalisé que ce n'était pas nécessaire).
J'ai utilisé la commande nc pour vérifier cette IP et ce port et j'ai reçu une réponse: "0 8 Bienvenue"

Je ne savais pas à quoi il s'attendait, alors je suis retourné à Wireshark pour voir s'il restait des indices.
J'ai filtré tous les paquets de données pour 35.157.111.68 sur le port 20120 et j'ai trouvé une conversation facile à lire:





J'ai recréé tout cela en utilisant la ligne de commande nc:

J'ai remarqué que la réponse à ma demande «2 3 XOR» était différente de celle du dossier.
J'ai répété toute la procédure encore et encore pour voir si la réponse changeait à chaque fois.


Comme je le pensais, les 4 valeurs obtenues étaient différentes à chaque fois, tout comme les données finales.
Les quatre valeurs obtenues semblent être la clé pour déchiffrer les données finales.
J'ai également remarqué que les chiffres avant chaque paquet de données ne sont pas aléatoires.
Il ressemble à ceci.
Le premier chiffre signifie l'ordre: 0 -> premier, 1 -> deuxième, 2 -> troisième, etc ...
Le deuxième chiffre signifie la durée de la phrase 8 -> "Bienvenue", 5 -> "Bonjour" ->, etc.
J'ai pensé que ce n'était pas la clé du décryptage. Étant donné que les données finales sont une ligne continue de blocs de 4 valeurs HEX et la clé XOR est également 4 valeurs HEX. Je peux peut-être parcourir chaque élément et le diviser en octets séparés, puis les mordre avec des octets de la clé.
Et j'ai essayé de décrypter:

Tout s'est avéré, mais il n'y avait aucun indicateur dans les données reçues.

J'ai relu les règles et je me suis souvenu que le chemin vers ce fichier secret était le suivant: /usr/PRivAtE.txt
J'ai répété la procédure à nouveau, mais cette fois j'ai demandé le chemin "/usr/PRivAtE.txt"

J'ai essayé à nouveau de décrypter les données finales:

Et le drapeau était entre mes mains:

Avez-vous réussi? Écrivez vos idées et options, je serai heureux de commenter.