jellyCTF
Cult_classic_2 [864 pts]
Writeup author: lolmenow
Difficulty: easy
Provided files: N/A (same as cult_classic_1, continue from last stage)
Description: See cult_classic_1 for challenge files. Enter the second flag into this challenge. Clarifications for Stage 5: Make sure you’re using the original source without modification (otherwise you may notice larger numbers than expected) If using online decoders but it’s not working, try a quick manual check to see if the decoders doing what you expect
Lets continue off from the last stage! We left off with the key of ALIEN
which is most likely the next key for the protected zip file.
Using the password, we now have 04.txt:
Welcome to stage four.
Cheating is not tolerated. We hope you play fair and square.
LBPTTULD
The text file obviously hints to the playfair
cipher. However, we need a key. Lets use the key ALIEN
as that is the last key we have.
Thats the next key! Lets use it to unlock the next zip file.
We are presented with 05.txt:
🌠Don't Look Away... 🌠
36.1 34.11 35.10 3.29 25.18 1.14 25.13 38.10 19.4 40.15
9.10 17.31 27.13 20.11 3.6 14.27 25.26 25.24 6.15 10.40 13.3 28.16 19.23 27.34 18.26 36.8
9.37 25.23 14.17
33.12 23.30 19.31
39.25 13.29 18.25 35.28
1.12 39.7 39.5 29.21 34.4 10.28 20.14 15.26
This reminds me of a book cipher. But, what text should we use? It took me a while, but the book/”song” we need to use is made by Jelly herself! The song is called Luminary
and we can verify this is the correct song from the description:
Lets use the lyrics from the Youtube description to decrypt this cipher. With book ciphers, you need to know how its decrypted. number.other_number.sometimes_another_number
Usually, its common to be line.character OR line.word.character
Since there are only 2 numbers in the cipher (eg: 36.1
) it most likely is line.character. What this means is that, for example 36.1
, in the 36th line at the 1st character is the first letter of the decrypted message.
With the assistance of chatgpt, I made a python script to do this.
song.txt
When I sleep at night
I have dreams that I
One day will wake up as a princess
With a shining gown
Smiling for a crowd
Oh how, I wish I could reset
But I can't keep thinking of "What if"
I'll turn my make-believe world into the truth I live
And towards the sky I shout my name
Hoping to be heard by you one day
Cause I know there's a world out there
Waiting for me to come and play
Oh I want to sing for you and me
And everyone in our galaxy
Cause you know that's always been
My lifelong dream
And I'm never giving up
I'll finish what I started, oh
If it all becomes too rough
Then I'll only get stronger
If I want the universe to look only at me
I'll put on a show I'm ready to go
"Hello world, this is me"
("Don't look away")
So towards the sky I shout my name
Knowing that you'll hear me sing one day
And I'll pour my heart out to you
Cause I'm here to stay
I'm standing here, a luminary in the night sky
The stars aligned to bring me to you
So come with me let's start
A new beginning
code.txt
36.1 34.11 35.10 3.29 25.18 1.14 25.13 38.10 19.4 40.15
9.10 17.31 27.13 20.11 3.6 14.27 25.26 25.24 6.15 10.40 13.3 28.16 19.23 27.34 18.26 36.8
9.37 25.23 14.17
33.12 23.30 19.31
39.25 13.29 18.25 35.28
1.12 39.7 39.5 29.21 34.4 10.28 20.14 15.26
sol.py
def read_file(file_name):
with open(file_name, 'r') as file:
return file.readlines()
def decode_song(song_lines, code_lines):
result = ''
for line in code_lines:
codes = line.strip().split()
for code in codes:
line_num, char_num = map(int, code.split('.'))
result += song_lines[line_num - 1][char_num - 1]
return result
def main():
song_lines = read_file('song.txt')
code_lines = read_file('code.txt')
decoded_song = decode_song(song_lines, code_lines)
print(decoded_song)
if __name__ == "__main__":
main()
# make sure code.txt and song.txt are in the same directory
Using the script, we get:
Capitalise'megalencephaly'forthenextpassword
There is the password! Which would be MEGALENCEPHALY
Using this, we unlock the final zip file. The last text file 06.txt has:
WAAWW AAWWW AAWAA AAWAW AWAAA AWWAW AAAAA AWAWW AWWWW AAAAA WAAWA WAAWA WAWWA AWWWA WAAAW AAAWW AWAAA WAAWA WAAWA AAAAA AAAWW AAWWA AWAAA WAAAW AWAWW
I instantly thought binary code/bacon cipher, as there is only W’s and A’s.
So, I replaced every W
with a 0
and every A
with a 1
(binary usually starts with 0, hence why I replaced W
with 0)
This gives us: 01100 11000 11011 11010 10111 10010 11111 10100 10000 11111 01101 01101 01001 10001 01110 11100 10111 01101 01101 11111 11100 11001 10111 01110 10100
Decoding this with bacon cipher, we get: THEFINALPASSWORDISSADGIRL
That is the final password! SADGIRL
which unlocks the flag.txt file!
Final flag: jellyctf{jelly_was_probably_older_than_these_ciphers}