Post

Le Musicien du Midi (2/2)

𝄞 Introduction

Intro


𝄞𝄞 Solution

Dans ce challenge, un fichier .midi est fourni. GrĂące au premier dĂ©fi, les joueurs ont normalement pu se familiariser avec le format MIDI, ce qui leur permet d’aborder ce deuxiĂšme niveau dans de bonnes conditions.

En examinant ce fichier MIDI de la mĂȘme maniĂšre que dans le premier challenge :

midi

On observe un spectre ne contenant aucune information exploitable, accompagnĂ© d’un son particuliĂšrement dĂ©sagrĂ©able.

Il est donc nĂ©cessaire de comprendre le fonctionnement interne d’un fichier .midi afin de pouvoir le manipuler et rĂ©vĂ©ler le message cachĂ©.


Note-on | Note-off

Les termes note-on et note-off dĂ©signent des Ă©vĂ©nements spĂ©cifiques dans un fichier MIDI. Ils dĂ©crivent respectivement le dĂ©but et la fin de la lecture d’une note.

  • Note-on : indique le moment oĂč une note commence Ă  ĂȘtre jouĂ©e. Cet Ă©vĂ©nement prĂ©cise quelle note jouer, sa vĂ©locitĂ© (intensitĂ©) et le canal MIDI utilisĂ©.

Par exemple :

  • Note-on pour la note “C4” (do central) avec une vĂ©locitĂ© de 80 (sur une Ă©chelle de 0 Ă  127).
  • Note-off : marque la fin de la note, c’est-Ă -dire quand elle cesse de sonner.

Ces deux Ă©vĂ©nements sont fondamentaux pour la construction d’une sĂ©quence musicale en MIDI. Un fichier MIDI est donc essentiellement une suite de note-on et de note-off, dĂ©finissant la durĂ©e et l’intensitĂ© de chaque note jouĂ©e.

Nous allons examiner les événements note-on dans notre fichier .midi.

Pour cela, plusieurs méthodes existent. Ici, nous allons utiliser le module mido en Python, qui permet de lire et manipuler des fichiers MIDI.

Voici un petit script :

1
2
3
4
5
6
7
8
from mido import MidiFile

mid = MidiFile('remy.mid')

for i, track in enumerate(mid.tracks):
    print('Track {}: {}'.format(i, track.name))
    for msg in track:
        print(msg)

Ce script, rĂ©alisable en quelques secondes avec l’aide de la documentation officielle Mido, permet d’afficher les diffĂ©rents champs prĂ©sents dans notre fichier .mid.

midi2

On retrouve ici les Ă©vĂ©nements note_on et note_off. Il est normal d’observer plusieurs Ă©vĂ©nements liĂ©s aux mĂȘmes notes (si vous avez bien compris leur fonctionnement).

On peut remarquer que les numéros de notes ressemblent à des valeurs ASCII. Nous allons donc extraire ces valeurs issues des événements note_on pour les interpréter en caractÚres ASCII.

Voici un script pour cela :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from mido import MidiFile

mid = MidiFile('remy.mid')

FLAG = []

for i, track in enumerate(mid.tracks):
    print('Track {}: {}'.format(i, track.name))
    for msg in track:
        for i in str(msg).splitlines():
            if i.startswith('note_on'):
                chunk  = i.split()
                for m in chunk:
                    if m.startswith('note='):
                        valeur_note = int(m.split('=')[1])
                        FLAG.append(valeur_note)

for i in FLAG:
    print(chr(i), end="")

En récupérant la valeur des champs note_on et en les convertissant en caractÚres ASCII, nous pouvons ainsi reconstituer le FLAG !

flag

𝄞 FLAG : MB{note_hidden_message}𝄞

This post is licensed under CC BY 4.0 by the author.