[Sthack][WriteUp – Reverse] Matrix

Introduction

On fait face à un exécutable linux ainsi que deux fichiers d’extension matrix, respectivement « hello_world.matrix » et « white_rabbit.matrix« .
Lorsque l’on lance l’exécutable, il nous indique la syntaxe: « Usage: ./matrix bytecode.matrix« .
hello_world.matrix affiche alors « Hello world! » tandis que white_rabbit.matrix demande un mot de passe.

Premiers tests

« Wake up Neo »

Premiers pas

On remarque quelques chaines de caractères interressantes dans le bytecode de white_rabbit.matrix.

"Tout ce que je vois, c'est..."

« Tout ce que je vois, c’est… »


"...Des blondes, des brunes, des rousses" Cypher - Matrix

« …Des blondes, des brunes, des rousses » Cypher – Matrix

Le programme va surement essayer de déchiffrer ces chaines pour en extraire le mot de passe de validation.

On peut commencer à décompiler le binaire:

Et ça décompile

« T’as vu la femme en robe rouge ? »

Comme on peut s’y attendre, l’exécutable lit le fichier en entrée, …

… crée ses structures, …

Elle est où la pilule rouge ?

… et rentre dans sa boucle pour décoder le bytecode.

Bienvenue dans la réalité, Neo

« Bienvenue dans la réalité, Neo »

 

La technique

Plutôt que d’essayer de comprendre quel bytecode exécutait quelle opération, j’ai tenté une technique de CTF qui fonctionne de temps en temps: compter les instructions pour savoir quelle entrée permet d’aller le plus loin possible.
Et là, le miracle s’est produit :

"Des armes, beaucoup d'armes"

« Des armes, beaucoup d’armes »

Pour la lettre « j », on remarque qu’il y a plus d’instructions qui sont exécutées.
Cela signifie que le programme vérifie l’entrée utilisateur caractère par caractère, et dès qu’il y en a un de faux, le programme s’arrete.

Plus qu’à coder un petit script en python pour bruteforce :

from os import popen
from string import printable
import re
passwd = ""
alphabet = printable

while 1:
    max_ = (-1,-1)
    for i in alphabet:
        try:
            n = re.findall("refs: (.*?)\n", popen('echo "%s%c" | valgrind --tool=callgrind ./matrix samples/white_rabbit.matrix 2>&1; rm call*'%(passwd,i)).read())[0]
        except:
            continue
        n = int(n.replace(',',''))
        if max_ == (-1,-1):
            max_ = (i, n)
        if max_[1] < n:
            passwd += i
            print("found: %c (%d)"%(i, n))
            print(passwd)
            break
"Au revoir M. Anderson"

« Au revoir M. Anderson »

Au bout d’un certain temps, le programme de bruteforce n’avance plus, MAIS :

"Mon nom est Neo"

« Mon nom est Neo »

Flag

Et voilà, le flag pour valider est  : jhgV6KdJbG

BdenneuINGÉNIEUR SÉCURITÉ
Yolo

Add a comment

*Please complete all fields correctly