peaCTF 2019 (Round1) - [Forensic] Song of My People (800pts)

Written by Maltemo, member of team SinHack.

Statement of the challenge

Description

A specific soundcloud rapper needs help getting into his password protected zipped file directory. The initial password is in the title. You just have to know your memes, and pick the right instrument! We were on the fence on giving you an image to go along with this puzzle, but the loincloth was too scandalous. Alternatively, you could bruteforce.

File

song_of_my_people.zip
├── a lengthy issue.png
├── Ice Cube - Check Yo Self Remix (Clean).mp3
└── README.txt

Step 1 : Extracting the data from a password ZIP file

The first part of the challenge was explained in the statement : extract the content of the zip.

Fine, we’ll do !
I chose the peaceful method and let my CPU rest this time.

So the hint says in the description :

The initial password is in the title. You just have to know your memes, and pick the right instrument! We were on the fence on giving you an image to go along with this puzzle, but the loincloth was too scandalous.

So I searched on internet for “Song of My People” and found write away this website :

I didn’t know this meme, so happy to learn an old one :smile: ! (memes are love, memes are life :heart:).

We understand now why they were talking about instruments and we have to find the right one.

They were talking about a loincloth, and there it is on the first picture of the website.

Perfect, we can come to the conclusion that the password is this instrument, a violin.

unzip -P violin song_of_my_people.zip Archive: song_of_my_people.zip skipping: Ice Cube - Check Yo Self Remix (Clean).mp3 unsupported compression method 99 skipping: README.txt unsupported compression method 99 skipping: a lengthy issue.png unsupported compression method 99

Ouch, so unzip won’t do the trick.
Trying 7zip :

7z x -pviolin song_of_my_people.zip 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 Scanning the drive for archives: 1 file, 5594494 bytes (5464 KiB) Extracting archive: song_of_my_people.zip -- Path = song_of_my_people.zip Type = zip Physical Size = 5594494 Everything is Ok Files: 3 Size: 5645856 Compressed: 5594494

Yup, we extracted the files successfuly.

Analysis of the files

Let’s check the README.md first. After all, it’s not called README for nothing :wink:
Here is the content :

one of the three files is a red herring, but a helpful one at that.

does any of this ADD up? This is a LONG problem.

Ok, there is not much information.

Then, I try to open the png file called a lengthy issue.png but I got a message error saying that the PLTE data chunk is too long. We get more information with pngcheck tool, but nothing incredible.

At this moment, I don’t know what it is, so I skip and check the music file.

I ran a lot of stego tool to see if there were any data hidden, but nothing at all. The music is a legit one and no weird noise are present in it.

I think this is a dead end (in addition of the README telling me that one of the file is a red herring).

I also check if the .txt didn’t hide any information in the spaces characters, you never know :smile:, but nothing too.

At this moment, Maltemo knew. He had to learn how PNG works.
Narrator

Step 2 : Correcting the PLTE length of the PNG file

I spent a LOT of time learning and testing on this image, so here is summary of what you need to know for this challenge.


A PNG file is composed of different chunks of data, some must exist and other are optional.

The critical chunks are (in order):

A chunk of data is always composed of :

Length of the data chunk Chunk type Chunk data CRC
4 bytes 4 bytes Length bytes 4 bytes

Now lets focus on the PLTE chunk (will see later why).

PLTE chunk contains from 1 to 256 palette entries, each a three-byte series of the form:
Red : 1 byte
Green : 1 byte
Blue : 1 byte

Consequently, the length of the PLTE chunk must be divisible by 3 (because one palette = 3 bytes).

Also, the PLTE chunk must appear for colour type 3 (that can be read in the IHDR chunk). For other types, it’s optionnal.

In our case, the image uses the colour type 3, so we will be forced to fix our PLTE Length properly.

The CRC (Cyclic Redundancy Code or Checksum) aims to check the integrity of the data.
For now, I don’t have the knowledge to explain to you how it works.
Sicarius explains it well there, but in french.


Those are the main documentations/sources I used to learn all this stuff :

Thanks to this knowledge, i’ll try to explain how I did in order to fix the PNG.

So first, to display the image as hexa and show the ascii version, we can use command line xxd. I’ll pipe this command with head command to show the beginning of the file.

Quick reminder, in hexadecimal one byte is represented by two character.
Example : (ff)16 = (1111 1111)2
(ff in hexa = 1111 1111 in binary. Remember the notation above, I will use it later)

xxd a\ lengthy\ issue.png | head 00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR 00000010: 0000 0500 0000 02d0 0803 0000 018f a41d ................ 00000020: f200 0000 0173 5247 4200 aece 1ce9 0000 .....sRGB....... 00000030: 0004 6741 4d41 0000 b18f 0bfc 6105 4845 ..gAMA......a.HE 00000040: 4c50 504c 5445 ffff fff7 f7f7 4040 4000 LPPLTE......@@@. 00000050: 0000 3232 32f5 f5f5 7272 722d 2d2d c9c9 ..222...rrr---.. 00000060: c9a2 a2a2 b8b8 b87f 7f7f dede de11 1111 ................ 00000070: 5050 50e6 e6e6 3f3f 3f8c 8c8c bdbd bd61 PPP...???......a 00000080: 6161 fbfb fb47 4747 2828 285d 5d5d d0d0 aa...GGG(((]]].. 00000090: d01e 1e1e d4d4 d4a7 a7a7 9d9d 9d4d 4d4d .............MMM

I’ll not detail the IDHR chunk, but we can find the color type value of 3 :

Now, let’s check the PLTE's broken length. We take the four bytes before PLTE and we got :
48 45 4c 50 which in ASCII is HELP.

Now we can understand why there was a length problem :dizzy_face: !

Our mission will be to replace those four bytes by the right length.

Lets calculate the total length of data from the PLT chunk :

We take everything afterPLTE, but we let 4 bytes for the CRC, 4 bytes before the next type chunk (here tRNS).

I found 906 letters of hexadecimal. Converting it to bytes, we divide it by 2.


906/2=(453)10 bytes

If you don’t understand this step, go back to the blue text called Quick Reminder.


We check if 453 is divisible by 3 => 453/3=151

Remember from the summary ?
A palette is composed of 3 bytes. So the data chunk must be divisible by 3 because it verifies if all the palettes of colour are complete.


Ok so now that we have the length, we convert it from base 10 to base 16 (to hexadecimal).

(453)10=(1c5)16

The chunk length is 4 bytes long, so we will replace in the image HELP by the length :

48 45 4c 50 will be replaced by 00 00 01 c5.

To do so, I used bless command line to edit the image hexadecimal, but you can use hexeditor or many more.

BEFORE

AFTER

We save the image with this modification.

We check the integrity of the PNG with pngcheck and we see that it has been correctly fixed ! :confetti_ball: YEEEAAAAAAHH :beers: !

I spent litteraly 3 nights on this problem and learned a lot. I’m so happy that I did finish this step !

Step 3 : Get the flag from the given information on the PNG

So I thougth that the challenge was finished right here.

He was so wrong :stuck_out_tongue_closed_eyes:
Narrator

The image was this :

Let’s get back to it !

We have a ton of information on this image.
I first checked it with aperisolve online tool to verify if the are some hidden things, but everything seemed okay.

Then I saw that we had to find 2 informations :

Page Number

I went to the soundcloud page) and found this :

From the description, we can see the famous page number, but there is a “should” so we don’t know if this is a valid information.

The music sounded like morse. I decoded it with this awesome online tool morse code scphillips and got this output (it isn’t exactly the text because of the method I use to decode, but the website is incredible):

E5UP YALL ITS YA BOI LIL ICE CUBE MELTING OUT HERE IN THE HAWAII HEAT FOR ALL OF YOU. YOU GUESSED IT THIS IS LIVE AUDIO FROM MY WORLD TOUR. I REPEAT LIL ICE CUBES WORLD TOUR MAYBE A LIBRARY WILL HELP

This gives us the archive name thanks to the help we got from the soundcloud description : LIL ICE CUBES WORLD TOUR

But what is this mysterious hexagonal library ?

We will try to answer this question by decoding the hexadecimal text on the PNG.

54 68 65 20 4c 69 62 72 61 72 79 20 6f 66 20 42 61 62 65 6c 3a 0a 28 77 69 74 68 20 6e
65 77 20 61 64 64 69 74 69 74 69 6f 6e 20 6f 66 20 61 6c 6c 20 74 68 65 20 70 6f 73 73 69 62 6c
65 20 64 69 73 73 20 74 72 61 63 6b 73 20 74 6f 20 65 76 65 72 20 62 65 20 6d 61 64 65
20 61 6e 64 20 65 76 65 72 20 63 6f 75 6c 64 20 62 65 20 6d 61 64 65 29

We can decode this hexa to ascii and we get this text :

The Library of Babel:
(with new additition of all the possible diss tracks to ever be made and ever could be made)

So I search library of babel on the web and find this website which seems to correspond. I search for LIL ICE CUBES WORLD TOUR and boom :

We just confirmed that the page number was 371.

If you are interested in understanding what is the Babel Library, I advise you to check youtube video explaining it, it’s quite fascinating.

Number of places left

For the number of places, I searched every where but got nothing from the 3 files of the beginning.
I tried to search online to find number of places left on the most recent concert passed of Ice Cube (a real person, author of the music we got from the zip).
I got nothing either.

So I guessed and tried 3 for the 3 ice cubes on the profile picture of the music, on the souncloud page.

It worked. And I didn’t get why. But the number of places left was 3

If you have any explanation for this last part, I would be more than happy to understand how you did find it, if there were a logical way.

Feel free to contact me on twitter at @Maltemo.

TL;DR

First step was unzipping a password protected zip. It could be achieved with bruteforce or understanding a little enigma.

The next step consisted in correcting a corrupted PNG where the length of the PLTE lenght chunk had been replaced by letters.

The last step was different puzzles (morse sound to text, hex values to text, Library of Babel) to find informations enabling to get the flag.

Flag

The flag is peaCTF{3_thousand_spaces_371}


Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.