Hello,

Aujourd'hui on s'attaque on challenge Bring weakness du AlexCTF (2017). La particularité ici est que l'on va devoir recréer le code source du serveur du challenge avant de pouvoir le résoudre. En effet le challenge originel était proposé au travers d'un serveur et par conséquent, aujourd'hui le serveur n'est plus disponible. Ce n'est pas grave, on va juste travailler un peu plus.

Agenda

Cet article est divisé en 2 parties. Une première concernant la récréation du code serveur et la seconde concernant la résolution proprement dite du challenge.

Dans ce post, on va s'occuper des étapes 1 et 2.

Reconstruire le challenge ? Mais d'habitude on se contente de le résoudre...

Oui je sais bien, mais il y a un moment où faut tenter de forger pour être forgeron. Alors aujourd'hui j'ai trouvé un petit challenge pas bien compliqué qui demande justement d'avoir accès à des ressources qui ne sont plus disponibles aujourd'hui.

Le principe de ce challenge est assez simple:

  1. On se connecte à un serveur qui nous donne un nombre et demande de trouver le suivant.
  2. On fait une proposition
  3. Le serveur nous informe de la justesse de notre prédiction

Le serveur ne donne le flag que si l'on arrive à faire 10 prédictions successives et correctes.

Si l'on veut recréer le serveur qui nous fait défaut il faut:

  1. Un générateur aléatoire défaillant (si, si !)
  2. Un serveur

Génération aléa-quoi ??

Un PRNG (Pseudo Random Generator Number) est une fonction mathématique qui renvoie un résultat non prédictible (en théorie). Le problème c'est qu'entre la théorie et la pratique il y a un gouffre.

Dans un monde parfait, un générateur aléatoire ne reproduit jamais 2 fois la même séquence, mais le monde étant ce qu'il est...

C'est tout le principe de ce challenge, il faut arriver à générer suffisamment de résultat pour que le générateur boucle et que l'on puisse prédire correctement les futurs résultats.

Pour arriver à ce résultat on va utiliser le module random de python, et plus particulièrement la fonction seed().

On donc utiliser un paramètre seed fixe afin de générer toujours la même séquence.

max_size=10000
rand_gen=[]
random.seed(2)
for i in range(max_size):
	rand_gen.append(random.randint(0, 65535))

Ensuite on va sélectionner aléatoirement 10 valeurs successives parmi les valeurs que l'on vient de générer.

max_size=10000

# Generate entry
rand_gen=[]
random.seed(2)
for i in range(max_size):
	rand_gen.append(random.randint(0, 65535))

random.seed()
seq=[]
debut = random.randint(0, max_size-11)
for i in range(debut, debut+11):
	seq.append(rand_gen[i])

Ensuite il ne reste plus qu'a en proposer la première et voir si le joueur arrive à faire 10 prédictions exactes.

Le code complet de cet algorithme est disponible sur mon framagit.

Dans le prochain article, je montrerais comment résoudre ce challenge.

NB: Comme le serveur est accessible en local, je n'ai pas intégré de gestion d'erreur, notamment lorsque le client ferme la connexion (via ctrl-c par exemple).

Social et Media

Comme toujours je suis disponible sur Twitter et cie, si vous avez des questions, des remarques, des suggestions etc. N’hésitez pas !

Twitter: @GhostAgs

Discord: hackraw