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 variablesolved
retourne désormaistrue
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!}