Solfeggio - Writeup by lemeda

Challenge :

iLearn music, or crypto… Or both ?


Given the picture above, we can notice that :

  • Even though the picture looks like a musical partition, it cannot actually be one, and that for several reasons. The most obvious is that the minimal musical syntax (the musical key in which to read the partition, musical bars, etc.) does not appear anywhere.
  • We can find elements of punctuation under the stave.

By looking closer at this pseudo-partition, we can see that it consists of groups of musical notes of various sizes.
Those groups are separated by spaces or by punctuation.
There are few repetitions among the existing groups of notes. This tends to indicate that one group of notes cannot represent a single letter. We can thus suppose that one musical symbol represents one letter.

If we look even closer at these symbols, we can notice that :

  • as for the rythmic values, the notes can be eighth, quarter, half or whole notes.
  • the height of the notes is always between C3 and B4 (reading in the key of G).
  • there are also eighth and quarter rests.

By adding up the possible heights for each possible rythmic value, we get 4 ∗ 14 = 56 possible symbols. By adding the 2 rest symbols, we end up with 58 possible symbols. Assuming that there may be a few more symbols, which are not on the pseudo-partition, we can suppose that we are in the case of a 62-characters mono-alphabetical substitution alphabet. \_ By substituting [C3 eighth-note - B4 eighth-note ; C3 quarter note - B4 quarter note ; C3 half note - B4 half note ; C3 whole note - B4 whole note ; extra symbols] to [A-Za-z0-9], and by letting the punctuation where it is, we get the following message :

"Hey, so you liked my song ? oh, maybe you want the flag… Well you’ll have to make a few more manipulations…
Here is the flag :
easy combinations ;) You know them all !"

By decoding the sequence "PVTGIX3TNZPWE5DRNNPWI2LUOFVHEX3GNFPXS2SRPNWGM4LZ" from Base32, we get the following :


Since the format of the flags for this CTF is flag{<flag>}, we reverse the order of the characters in the previous string, and thus get :


By applying a shifting algorithm with a 21-shift (except on the first character, to which a 6-shift has to be applied), we get :