GrimmCon CTF

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

First Challenge: Zip Zip

My friend sent me this zip file... He is a prankster and compressed the file a LOT of times...

I don't know how to make this go quickly and I don't have the time... At least he told me the password is "pass".

Can you please help?

For this challenge, you're given a zipfile called 50.zip that is encrypted. We're told the password is pass. What's interesting though is, there's a zipfile within a zipfile, and the password is the same for all the other zipfiles lulz. This makes the challenge relatively easy. And since the file is called 50, then the very last zip file should be 00.zip.

Knowing that the password is the same for all the other zipfiles, i made a bash script to hammer that all the way.

#!/usr/bin/bash # @author: mug3njutsu for i in {50..00}; do unzip -P "pass" $i.zip rm $i.zip done

Running this;

➜  zip zip_COMPLETE cat flag.txt                             
flag{cf97382071cb149aac8d6ab8baeaa3ee}

Easy!

Second Challenge: Triple

I was studying something called ASCII armor because I wanted to become better at encoding. I was having fun until I realized I couldn't decode my message...

We're given a txt file that has two base64 encoded text seperated by a space. I'll cut both the first and second section and base64 decode each.

➜  triple_COMPLETE cat encoded.txt | cut -d " " -f 1         
Ulc1amIyUnBibWNnWVNCdFpYTnpZV2RsSUdseklHRWdiRzkwSUc5bUlHWjFiaUIxYm5ScGJDQnBkQ0JwYzI0bmRDNGc=
➜  triple_COMPLETE cat encoded.txt | cut -d " " -f 1 | base64 -d
RW5jb2RpbmcgYSBtZXNzYWdlIGlzIGEgbG90IG9mIGZ1biB1bnRpbCBpdCBpc24ndC4g
➜  triple_COMPLETE cat encoded.txt | cut -d " " -f 1 | base64 -d | base64 -d
Encoding a message is a lot of fun until it isn't.

So, the first section is encoded twice.

➜  triple_COMPLETE cat encoded.txt | cut -d " " -f 2
V20xNGFGb3pjM3BQVkd0M1RsZFJlVTFVVVRSYWFsSnRXa2RKTTFscVFYbE9WMDE1VFRKUk1rOUVVWGROUkU1cVdXNHdQUT09
➜  triple_COMPLETE cat encoded.txt | cut -d " " -f 2 | base64 -d
Wm14aFozc3pPVGt3TldReU1UUTRaalJtWkdJM1lqQXlOV015TTJRMk9EUXdNRE5qWW4wPQ==
➜  triple_COMPLETE cat encoded.txt | cut -d " " -f 2 | base64 -d | base64 -d
ZmxhZ3szOTkwNWQyMTQ4ZjRmZGI3YjAyNWMyM2Q2ODQwMDNjYn0=
➜  triple_COMPLETE cat encoded.txt | cut -d " " -f 2 | base64 -d | base64 -d | base64 -d 
flag{39905d2148f4fdb7b025c23d684003cb}

For the second section three times and we get the flag. I guess that's why the challenge is called triple.
Let's script this in python shall we!

#!/usr/bin/env python3 # @author: mug3njutsu from base64 import b64decode as b handle = [b(b(x)).decode() for x in open('encoded.txt').read().split(" ")] message = handle[0] flag = b(handle[1]).decode() print(f'{message}\n{flag}')

When we run this

➜  triple_COMPLETE python3 ape.py     
Encoding a message is a lot of fun until it isn't. 
flag{39905d2148f4fdb7b025c23d684003cb}

Third Challenge: wannabeel33t

We are chasing down a hacker, wannabeel33t and we watch to catch him red-handed. He keeps a low profile online, but he has to have some bad habits...

Literally just googling the name and the very first result is from Reddit. When you check that, you see his bio with some urlencoded text. Decoding that, you get the flag.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

➜  wannabeel33t_COMPLETE urlencode -d "%66%6c%61%67%7b%36%36%62%31%35%33%34%37%63%35%38%63%39%31%64%31%39%33%37%66%30%62%34%30%65%39%37%33%64%33%66%36%7d"
flag{66b15347c58c91d1937f0b40e973d3f6}

Fourth Challenge: Chef's salad

Want to try the chef's salad? Some days it is waldorf, some days fruit, some days caesar... it is different every day!

We're given a txt file with some rotated text and was seems to be the flag.

➜  chef salad_COMPLETE cat chefs_salad.txt | grep -oE taqx{.*?}    
taqx{u6953087bc5hi8l207q2pts86uxz34a8}

Then i used caesar to loop through the 26 rotations and see if i can notice anything interesting.

➜  chef salad_COMPLETE for i in {1..26}; do echo "taqx{u6953087bc5hi8l207q2pts86uxz34a8}" | caesar $i; done              
ubry{v6953087cd5ij8m207r2qut86vya34b8}
vcsz{w6953087de5jk8n207s2rvu86wzb34c8}
wdta{x6953087ef5kl8o207t2swv86xac34d8}
xeub{y6953087fg5lm8p207u2txw86ybd34e8}
yfvc{z6953087gh5mn8q207v2uyx86zce34f8}
zgwd{a6953087hi5no8r207w2vzy86adf34g8}
ahxe{b6953087ij5op8s207x2waz86beg34h8}
biyf{c6953087jk5pq8t207y2xba86cfh34i8}
cjzg{d6953087kl5qr8u207z2ycb86dgi34j8}
dkah{e6953087lm5rs8v207a2zdc86ehj34k8}
elbi{f6953087mn5st8w207b2aed86fik34l8}
fmcj{g6953087no5tu8x207c2bfe86gjl34m8}
gndk{h6953087op5uv8y207d2cgf86hkm34n8}
hoel{i6953087pq5vw8z207e2dhg86iln34o8}
ipfm{j6953087qr5wx8a207f2eih86jmo34p8}
jqgn{k6953087rs5xy8b207g2fji86knp34q8}
krho{l6953087st5yz8c207h2gkj86loq34r8}
lsip{m6953087tu5za8d207i2hlk86mpr34s8}
mtjq{n6953087uv5ab8e207j2iml86nqs34t8}
nukr{o6953087vw5bc8f207k2jnm86ort34u8}
ovls{p6953087wx5cd8g207l2kon86psu34v8}
pwmt{q6953087xy5de8h207m2lpo86qtv34w8}
qxnu{r6953087yz5ef8i207n2mqp86ruw34x8}
ryov{s6953087za5fg8j207o2nrq86svx34y8}
szpw{t6953087ab5gh8k207p2osr86twy34z8}
taqx{u6953087bc5hi8l207q2pts86uxz34a8}

What you notice here is, the flag is somehow arranged going backwards. The first character of the 12th rotation is f, then the second character of the 11th rotation is l, third character of the 10th rotation is a, fourth character of the 9th rotation is g and so on.
From here i made a list with the rotations sorted according to the flag format. And i did this, by instead using a range of 1 to 38 then using tac to reverse the output. Apparently a range in bash plays a little different from what's in python coz, the list is made of 38 lines instead of 37 in python. I then used tac to reverse the output so that it has the line with f at the beginning.

➜  chef salad_COMPLETE for i in {1..38}; do echo "taqx{u6953087bc5hi8l207q2pts86uxz34a8}" | caesar $i; done >> dump
➜  chef salad_COMPLETE cat dump | head -n 1                    
ubry{v6953087cd5ij8m207r2qut86vya34b8}
➜  chef salad_COMPLETE cat dump | tac >> rot
➜  chef salad_COMPLETE cat rot | head -n 1  
fmcj{g6953087no5tu8x207c2bfe86gjl34m8}

Like so. So now with the list, i made a simple python script to hammer that and get the flag. It will basically grab the nth character of the nth line. That means if the line is marked as [0], it will grab the 1st character[0] of the line. If the line is marked as [1], it will grab the second character[1] of the line and then when it's done, it appends each character to form the flag.

#!/usr/bin/env python3 # @author: mug3njutsu x = [i for i in range(0, 38)] wordlist = [x.strip() for x in open('rot').read().split('\n') if x] print("".join([wordlist[x][x] for x in x]), end='', flush=True)
➜  chef salad_COMPLETE python3 ape.py
flag{b6953087aa5dd8e207f2cfd86cef34d8}

Easy!

I feel like touching on one last one that didn't work out as i expected. And the same challenge was once in a ctf, was rated easy, and i still couldn't solve it lulz.

Bonus: Lottery

We're given a webpage.

We are supposed to kinda guess an 8-digit number, and it's 8 coz of the placeholder that we can see on the text box.
And if you check the page source, do some directory listing, there's nothing interesting there.
So, decided to build a script that loops through 10000000 to 99999999 and when it finds the string "Oh no!" in the response, then it knows that's not the right number because that's what we get when we guess wrong.

#!/usr/bin/env python3 # @author: mug3njutsu import requests import re for lottery in range(10000000, 99999999): r = requests.get("http://challenge.ctf.games:32351/?action=submit&lottery_number={lottery}") matched = re.search(r'Oh no!', r.text) if matched: print(f'{lottery} : {matched.group()}') else: print(f'{lottery} : Found!')

That was it. After that stopped looping, i went to do something else lol!