RADARCTF2019 — Misc(+Programming) Writeup
For this post, I will write about our team’s solutions for the Misc challenges @ RADARCTF2019, which included a healthy mix of Forensics, Steganography and pure fun. +a solution to a programming challenge!
Hello everyone! Today I will write about our team’s solutions for the Misc challenges @ RADARCTF2019, which included a healthy mix of Forensics, Steganography and pure fun.
I will also write about our solution for a programming challenge at the end!
For this run, we luckily placed 22nd out of 610 teams ❤️
So let’s start!
Can you find what is hidden inside the photo ?
We are given
Logo.zip, which when unpacked gives us
logo.png. However, we can’t view
logo.png due to this error:
A CRC error! Let’s fix it!
Upon opening the file using my favorite Hex Editor (010Editor), we will see this prompt:
Let’s fix it:
After which, we can now open the file:
Here comes the frustrating part. I ran most of my steganography tools to try and see if there’s anything hidden, to no avail.
I then inspected the chunks and set my focus on the dimensions:
In my opinion, this is where the intuition part comes in, I was kind of put off by the dimensions of the file (
400x180) so I decided to tweak it using
After tweaking it, we will get this file:
We took it from the ocean and we don’t know what is file include !
Mon’s Notes: I had so much fun with this challenge, due to its creativity 😂
Upon downloading the
Ocean.zip file, we will get
unknown.zip which contains
file command on
unknown shows that it’s an XML document:
Let’s inspect the file:
I’d like you to focus on lines 2, 8, and 56–58. What do they have in common? Right. They all point to a Google service, and with the coordinates in mind, probably Maps or Earth. Knowing that KML files are associated with Google Earth, I decided to try and import it into their web service (which only works with Google Chrome..).
And voila, we have the flag!
Stephen love to hide some secrets ;)
hawking.zip we will get
Now, based on the description of the challenge:
Stephen love to hide some secrets ;)
I concluded that they must’ve used
steghide for this, however, running steghide and extracting files using a key (password) without any clue/s is incredibly time-consuming. So I decided to use all the available strings we have, namely:
Luckily, we got a hit by using
hawking as the password, which gives us radar.txt:
Mon’s Notes: May you rest in peace, Dr. Hawking. I felt compelled to solve this challenge just because it had your name and face on it, as you will always be one of my greatest role models.
This challenge was pretty easy, since you just have to crack the file. However, it’s not that easy since it uses compression method 99 (AE-x) that is unsupported by
unzip, which renders tools such as
fcrackzip (which relies on unzip) unusable.
However, cracking the file using hashcat did the trick.
First, get the password hash of the file using:
zip2john EasyZip.zip | cut -d ':' -f 2 > easyzip_hash
Then proceed to process it using hashcat:
And we get the password:
Finally unzipping the file will give us flag.txt:
This can be easily solved using stegsolve:
Unzip me and get your flag
Alright, first off, we are give
Unzip.zip which gives us
flag.zip when unzipped.
unzip flag.zip will give us this:
So we’ll try to use
7z for this:
Huh, it doesn’t work. Let’s open a copy of
flag.zip on our (my) favorite Hex Editor (010Editor):
We are working on a copy of flag.zip so that we can keep its integrity.
Alright, at face value, we can easily see the shenanigans that the authors did on the zip file. No? Alright, to see it clearly, let’s open up a working zip copy. Do we have one? Yes we do.
Alright. Initially, let’s focus on the first four offsets (00h–03h). Knowing zip files, they must start with the signature
50 4B 03 04 . We see nothing like it on flag.zip (in fact, the bytes are flipped). So let’s fix it:
Next, the next 2 bytes starting at offset 4 are collectively called the
Version. This describes the minimum version needed to extract the contents. Oh, since we fixed the zip file signature, we unlock this feature on 010Editor:
Now, Version number of 5120 isn’t normal, let’s flip the bytes to fix it:
Now we have a Version with the value
20 which stands for 2.0.
For the next 2 bytes, this is called the
General Purpose Flag it serves a lot of purposes for the zip file format, but I will explain it further later. Initially we have this working copy:
General Purpose Flag value of 2304, which is a really huge value for a flag. Let’s change it to something better by flipping the bytes:
General Purpose Value flag of value
9 gives us
0000 0000 0000 1001 in binary. For now, all we need to know is that if bit 0 is set, then the file is encrypted.
Moving on, the next two bytes is called the
Compression Method . For reference, we can look at this snippet from pkware’s documentation:
And for flag.zip’s compression method:
Let’s fix it by flipping the bytes again:
Which gives us compression method 99 (AE-x), which is unsupported by unzip.
At this point we can confidently assume that we fixed the header, as the succeeding values look pretty promising:
To check, let’s run
7z x :
Fixed! Now, time to crack the password for this file:
And the password is:
Mon’s Notes: Now I kinda feel bad for our crackstation for using it without even trying some passwords haha
Finally, unzipping the file will give us
Mon’s Notes: This programming problem is definitely one of the most fun challenges I’ve ever encountered.
A lot of scattered pictures , do you think they give you a secret ?
Downloading the zip file will give us
Scattered1.zip that contains 576 images of pure madness:
Now, if we look closely:
SGVsbG8g stands for
Hello when decoded using base64. Ladies and gentlemen, we now have a lead!
Our plan is to read the characters in all 576 images, display its output, and then decode the resulting base64 string.
For this challenge, I used the libraries
To resize the images, I used opencv:
#Script Name: resizer.py
#Description: Resizes images to 150x150
#made with <3 by mon from the hackstreetboysimport cv2
for i in range(1, 577):
im_path = './' + str(i) + '.jpg'
img = cv2.imread(im_path)
cropped = img[0:150, 0:150]
cv2.imwrite('./cropped/' + str(i) + '.jpg', cropped)
This stores the cropped images in a
cropped folder. Before and after of the images:
I cropped the images so that it will be easier for
pytesseract to read the characters.
Next, the reading part:
#Script Name: ocra.py
#Description: Performs OCR on multiple images and prints the result
#made with <3 by mon from the hackstreetboys from PIL import Image
for i in range(1, 577):
img = str(i) + '.jpg'
text = pytesseract.image_to_string(Image.open(img), config='--psm 10')
config=--psm 10 so that we can tell tesseract to follow page segmentation mode 10 (Treat the image as a single character). Please refer to the list below:
After running the script above, we will get:
Now I encountered a lot of problems with parsing the characters. First, pytesseract had a hard time distinguishing
I,i,l,L and so on. So the above base64 string is the (almost)best effort I got. When decoded, this results to:
All in all, we enjoyed this CTF as a team! We luckily placed 22 out of 610 participants, so I’ll say its a pretty good run! I’ll always be proud of my teammates, so be sure to clap on their writeups when they release it!
I hope you learned a thing or two, dear reader!
As always, thank you for reading!
Hi I’m Mon, and I’m one of the founders of hackstreetboys, a CTF team from the Philippines!
While you’re at it, please like our Facebook page (hackstreetboys)
Follow our Twitter account (https://twitter.com/_hackstreetboys)
Read our writeups on Medium (https://medium.com/hackstreetboys)
Look at our new GitHub page (https://github.com/hackstreetboysph)
Also, visit our website (https://hackstreetboys.ph)