Reverse - Tetris
by Karzemrok
Description
Trouver comment Nitnick du 33 a pu faire un score aussi élevé ! http://54.217.60.203:3000
Fichier
Résolution
Avant de résoudre ce challenge, jouons un peu pour voir les mécaniques de gameplay.
Le jeu est un Tetris classique, à chaque pièce posée, 4 points sont ajoutés.
Au fur et à mesure du jeu, on se rend compte que chaque ligne rapporte 40 pts.
Avec un timer de 3 min, il est évident qu’il va falloir que le score augmente plus rapidement si on veut faire plus de 150666 pts en moins de 3 min.
Nous allons transformer le WASM en JS (avec wasm2js) et en WAT (avec wasm2wat) pour avoir deux vues différentes pour nous simplifier l’analyse du binaire.
wasm2wat challenge/Build/TetrisChallenge.wasm -o challenge/Build/TetrisChallenge.wat
wasm2js challenge/Build/TetrisChallenge.wasm -o challenge/Build/TetrisChallenge.wasm.js
En regardant la version JS, on trouve quelques fonctions intéressantes :
- _GameController_computeScore
- _GameController_increaseScore
- _GameController_computeFlag
Dans la fonction “_GameController_computeScore”, on remarque qu’il y a un switch sur plusieurs valeurs dont “40”. On peut en déduire que ce switch gère les points en fonction du niveau actuel.
On voit aussi que la fonction “_GameController_increaseScore” est appelée avec la valeur “4” en paramètre.
function _GameController_computeScore_m159BAAA24208AF84DD5ED8B95AD29BD9E6EEDB1F($0, $1, $2) {
$0 = $0 | 0;
$1 = $1 | 0;
$2 = $2 | 0;
var $6 = 0, $3 = 0;
$3 = $0;
label$1 : {
label$2 : {
switch (__Z23il2cpp_codegen_subtractIiiEN11pick_biggerIT_T0_E4typeES1_S2_($1 | 0, 1 | 0) | 0 | 0) {
case 0:
$6 = 40;
break label$1;
case 1:
$6 = 100;
break label$1;
case 2:
$6 = 300;
break label$1;
case 3:
$6 = 1200;
break label$1;
default:
break label$2;
};
}
$6 = 0;
}
_GameController_increaseScore_m5289853DCC0AB993DA5503761DEB20790872E41C($3 | 0, __Z23il2cpp_codegen_multiplyIiiEN11pick_biggerIT_T0_E4typeES1_S2_($6 | 0, __Z18il2cpp_codegen_addIiiEN11pick_biggerIT_T0_E4typeES1_S2_(0 | 0, 1 | 0) | 0 | 0) | 0 | 0, 0 | 0);
if ($1) {
_GameController_increaseScore_m5289853DCC0AB993DA5503761DEB20790872E41C($0 | 0, 4 | 0, 0 | 0);
if (($1 | 0) != (999 | 0)) {
_GameController_increaseLinesDeleted_mBD1BAEC32F785607B6B3B35C33B4965690E572AA($0 | 0, $1 | 0, 0 | 0)
}
}
}
On peut modifier ces deux valeurs et voir ce qu’il se passe.
wat2wasm challenge/Build/TetrisChallenge.wat -o challenge/Build/TetrisChallenge.wasm
Dès que le premier bloc est posé, le flag s’affiche
Résolution alternative
Changer la mécanique de score est une première façon de faire, mais il y en a d’autres.
Par exemple, nous pouvons regarder la fonction “_GameController_computeFlag” d’un peu plus près. Cette fonction étant appelée à chaque fois, la vérification du score doit être faite pour vérifier si le flag doit être affiché ou non.
function _GameController_computeFlag_m8E22B11FD96D95CC679276481FE7DAC672CFCB38($0, $1) {
$0 = $0 | 0;
$1 = $1 | 0;
var $3 = 0;
if (!(HEAP8[2286203 >> 0] | 0)) {
__Z42il2cpp_codegen_initialize_runtime_metadataPm(1045652 | 0);
__Z42il2cpp_codegen_initialize_runtime_metadataPm(1045752 | 0);
__Z42il2cpp_codegen_initialize_runtime_metadataPm(1072180 | 0);
__Z42il2cpp_codegen_initialize_runtime_metadataPm(1071092 | 0);
__Z42il2cpp_codegen_initialize_runtime_metadataPm(1067764 | 0);
HEAP8[2286203 >> 0] = 1;
}
if (__ZNK54ObjectReader_t5F7C1222253B9F7FBFC6D74D444FF7AF9A6A415227get_bFullDeserialization_17Ev($0 | 0) | 0) {
if ((__ZNK17SharedTextureData9GetFormatEv($0 | 0) | 0 | 0) >= (__ZThn52_NK13MonoBehaviour9GetScriptEv($0 | 0) | 0 | 0)) {
__ZN47Timer_t31BE4EDDA5C1CB5CFDF698231850B47B7F9DE9CB14set_disposed_7Eb($0 | 0, 1 | 0);
[...]
}
}
}
On voit en début de fonction une comparaison >= qui pourrait correspondre à la vérification du score.
Pour le vérifier, on peut inverser la condition et voir ce qu’il se passe.
La comparaison >= correspond à l’instruction “i32.ge_s”. En regardant ici, on trouve que l’opérateur <= correspond à “le_s”
On peut donc le modifier dans le fichier WAT et recompiler.
wat2wasm challenge/Build/TetrisChallenge.wat -o challenge/Build/TetrisChallenge.wasm
Dès que le jeu se lance, le flag s’affiche
tags: sthack2021 - reverse - wasm - ctf