Skip to main content

BreizhCTF 2025 | Welcome Game

·396 words·2 mins
WiZee
Author
WiZee
Infosec student @ ESNA
Table of Contents

TL;DR
#

  • Le contrat contient une grille de sudoku incomplète et une fonction submitSolution
  • On utilise la suite d’outils de Foundry pour interagir avec le contrat, ainsi qu’un modèle d’intelligence artificielle pour résoudre la grille
  • En soumettant la grille complète via la fonction submitSolution, la variable solved retourne désormais true et permet d’obtenir le flag

Informations du challenge
#

Auteur K.L.M
Catégorie Blockchain
Description Bienvenue au BreizhCTF 2025 ! Pour commencer, nous allons jouer à un jeu, trouvez un moyen de réussir à gagner la partie pour obtenir le flag.
Difficulté Très facile
Fichier(s) Challenge.sol
Points 227
Résolutions 79/118
Sources https://github.com/BreizhCTF/breizhctf-2025/tree/main/blockchain/welcome-game/
URL https://welcome-game.ctf.bzh/

Résolution du challenge
#

Pour réaliser ce challenge, nous allons utiliser la suite d’outils de Foundry.

En parcourant le contrat, on comprend qu’on a affaire à un jeu de sudoku et qu’on va devoir envoyer une grille valide à la fonction submitSolution.

...
constructor() {
        solved = false;
        initialGrid = [
            [5, 3, 0, 0, 7, 0, 0, 0, 0],
            [6, 0, 0, 1, 9, 5, 0, 0, 0],
            [0, 9, 8, 0, 0, 0, 0, 6, 0],
            [8, 0, 0, 0, 6, 0, 0, 0, 3],
            [4, 0, 0, 8, 0, 3, 0, 0, 1],
            [7, 0, 0, 0, 2, 0, 0, 0, 6],
            [0, 6, 0, 0, 0, 0, 2, 8, 0],
            [0, 0, 0, 4, 1, 9, 0, 0, 5],
            [0, 0, 0, 0, 8, 0, 0, 7, 9]
        ];
    }

    function submitSolution(uint8[9][9] memory solution) public {

        if (isValidSolution(solution)) {
            solved = true;
        }
    }
...

On commence par définir quelques variables d’environnement afin de simplifier leur usage dans nos futures commandes.

export PK="0x6715d324d14e0565ab02a575fa5f74540719ba065a610cba6497cdbf22cd5cdb"
export RPC="http://localhost:8002/rpc"
export TARGET="0xBF66E4584229A619F0F2d6F55636383b4F1b7e7A"

On ne va évidemment pas chercher une grille valide manuellement, car le CTF ne dure que 8 heures, un temps très limité pour résoudre les nombreux challenges proposés.

Pour cela, deux solutions s’offrent à nous :

  • Utiliser un résolveur de sudoku en ligne
  • Utiliser un modèle d’intelligence artificielle

J’ai privilégié la seconde solution pour gagner un maximum de temps.

On passe donc cette grille à la fonction submitSolution avec la commande suivante.

cast send $TARGET --private-key $PK -r $RPC "submitSolution(uint8[9][9])" \
    "[[5,3,4,6,7,8,9,1,2],[6,7,2,1,9,5,3,4,8],[1,9,8,3,4,2,5,6,7],[8,5,9,7,6,1,4,2,3],[4,2,6,8,5,3,7,9,1],[7,1,3,9,2,4,8,5,6],[9,6,1,5,3,7,2,8,4],[2,8,7,4,1,9,6,3,5],[3,4,5,2,8,6,1,7,9]]"
...            
status               1 (success)
...

On vérifie si notre grille est valide.

cast call $TARGET -r $RPC "solved()(bool)"
true

La variable solved étant passée à true, on peut maintenant retourner sur la page du challenge pour récupérer le flag.

BZHCTF{W3lcome_t0_th3_BZHCTF25!}

Reply by Email