CTF M0rsarchive

  1. CHALLENGE DESCRIPTION
  2. Zip file
  3. Get the hex value of a png
  4. Convert to morse
  5. Translate the morse
  6. Assemble
  7. Almost done
    1. Error 1
    2. Error 2
    3. Error 3
  8. Final

CHALLENGE DESCRIPTION

Just unzip the archive … several times …

Zip file

We have an encrypted Zip file: flag_999.zip.
And a picture:

It’s a morse code, it’s mean 9.
The password of flag_999.zip should be 9.

So we have 999 zip files like this, I have to code something.

Get the hex value of a png

convert *.png txt:-

There is 2 colors, #BC32D8 for the background and #FF3200 for the foreground.

convert *.png txt:- > hex.txt
grep "#FF3200" -C 1 hex.txt 

If there is 3 pixels it’s a -, if there is 1 pixel it’s a .and the – is a pace.
The code should be 98.

Convert to morse

grep "#FF3200" -C 1 hex.txt  | awk '{ print $3 }'

Good, now I want it in one line and replace the space by a random char:

grep "#FF3200" -C 1 hex.txt  | awk '{ print $3 }' | awk '!NF{$0=">"}1' | xargs

Now I have to replace #FF3200 #FF3200 #FF3200 by - and #FF3200 by ..
Then remove every thing who is not -, . and >.
Finaly replace > by a space.

grep "#FF3200" -C 1 hex.txt  | awk '{ print $3 }' | awk '!NF{$0=">"}1' | xargs | sed 's/#FF3200 #FF3200 #FF3200 /-/g' | sed 's/#FF3200 /./g' | sed 's/#BC32D8//g' |sed 's/ //g'| sed 's/>/ /g'

Translate the morse

Now I have this string ----- ---.., there is one space between the 2 chars, I would add one space at the end and use sed to replace it by a letter. Like this

sed 's/----- /9/'
sed 's/---.. /8/'

This is what I wanted to do at first but my space is removed in my script, I don’t know why.
So I add this > at the end to have something like this: .- -... >

It’s working well, here is the code:

#!/bin/bash
code=$1
code=$(echo $code | sed 's/\.- /A/g') 
code=$(echo $code | sed 's/-\.\.\. /B/g') 
code=$(echo $code | sed 's/-\.-\. /C/g') 
code=$(echo $code | sed 's/-\.\. /D/g') 
code=$(echo $code | sed 's/\. /E/g') 
code=$(echo $code | sed 's/\.\.-\. /F/g') 
code=$(echo $code | sed 's/--\. /G/g') 
code=$(echo $code | sed 's/\.\.\.\. /H/g') 
code=$(echo $code | sed 's/\.\. /I/g') 
code=$(echo $code | sed 's/\.--- /J/g') 
code=$(echo $code | sed 's/-\.- /K/g') 
code=$(echo $code | sed 's/\.-\.\. /L/g')
code=$(echo $code | sed 's/-- /M/g') 
code=$(echo $code | sed 's/-\. /N/g') 
code=$(echo $code | sed 's/--- /O/g') 
code=$(echo $code | sed 's/\.-- /P/g') 
code=$(echo $code | sed 's/--\.- /Q/g') 
code=$(echo $code | sed 's/\.-\. /R/g') 
code=$(echo $code | sed 's/\.\.\. /S/g') 
code=$(echo $code | sed 's/- /T/g') 
code=$(echo $code | sed 's/\.\.- /U/g') 
code=$(echo $code | sed 's/\.\.\.- /V/g') 
code=$(echo $code | sed 's/\.-- /W/g') 
code=$(echo $code | sed 's/-\.\.- /X/g') 
code=$(echo $code | sed 's/-\.-- /Y/g') 
code=$(echo $code | sed 's/--\.\. /Z/g') 
code=$(echo $code | sed 's/\.---- /1/g') 
code=$(echo $code | sed 's/\.\.--- /2/g') 
code=$(echo $code | sed 's/\.\.\.-- /3/g') 
code=$(echo $code | sed 's/\.\.\.\.- /4/g') 
code=$(echo $code | sed 's/\.\.\.\.\. /5/g') 
code=$(echo $code | sed 's/-\.\.\. /6/g') 
code=$(echo $code | sed 's/--\.\.\. /7/g') 
code=$(echo $code | sed 's/---\.\. /8/g') 
code=$(echo $code | sed 's/----\. /9/g') 
code=$(echo $code | sed 's/----- /0/g') 
code=$(echo $code | sed 's/ >//g') 
echo $code

It’s ugly, there is no loop, no if and all that shiny stuffs, only the basics but it’s working.
I can do it even smaller, with multiple sed in sed in sed etc…
And then the output of this will be the password for the zip file.
I have to assemble everything like a lego.

Assemble

In my script I have to do this:

# Get Morse
# Translate
# Unzip
# repeat

Oh nooooooo !!!
I just found a problem, it’s not the same hex value for every flag.png.
There is 2 hex value every times, there is more background then foreground.
To find the background:

background=$(convert *.png txt:- | awk '{ print $3 }' | grep "#" | head -n 1)
foreground=$(convert *.png txt:- | awk '{ print $3 }' | grep "#" | grep -v $background | head -n 1)

Almost done

Error 1

I have a problem with tho morse code, I have to change the position of few sed command.

There is few dots remaining in the password, it’s inaceptable.

The error:

.-. . .--.

.-. = R
. = E

. –. = P
but
–. = G
I should translate the P before the G.

Error 2

The translation it good.

There is only 2 colors:

Ok got it … Ihad to change the password to lower case.
I will use this:

echo "${a,,}"

Now I have to wait.

Error 3

So I’m trying manualy.

The password looks good, the problem is somewhere else.

fillin_CFileInfo - internal error - MAX_PATHNAME_LEN

Yup, the path is very long
I’ve unziped more than 150 zip files, I should move the zip file every 150 files to be closer to the root directory.
I’m not gonna create an another loop, I will just use the current one.

if [ $c == 850 ] || [ $c == 700 ] || [ $c == 550 ] || [ $c == 400 ] || [ $c == 250 ] || [ $c == 100 ];

Final

#!/bin/bash

# Get Morse
## Get colors
for (( c=999; c>=0; c-- ))
do 
	if [ $c == 850 ] || [ $c == 700 ] || [ $c == 550 ] || [ $c == 400 ] || [ $c == 250 ] || [ $c == 100 ]; # To tired to play with regex
	then
		mv flag /home/peanutstick/Documents/CTF/Challenges/HTB/M0rsarchive/flag$c
		cd /home/peanutstick/Documents/CTF/Challenges/HTB/M0rsarchive/flag$c
	else
		cd flag
	fi
	b=$(convert *.png txt:- | awk '{ print $3 }' | grep "#" | head -n 1)
	f=$(convert *.png txt:- | awk '{ print $3 }' | grep "#" | grep -v $b | head -n 1)
	#echo "Background: $b"
	#echo "Foreground: $f"
	## Replace the str
	
	code=$(convert *.png txt:- | grep $f -C 1 | awk '{ print $3 }'| awk '!NF{$0=">"}1' | xargs | sed 's/'$f' '$f' '$f' /-/g' | sed 's/'$f' /./g' | sed 's/'$b'//g' |sed 's/ //g'| sed 's/>/ /g')
	code="${code} >"
	echo $code
	# Translate
	## Group of 4
	code=$(echo $code | sed 's/\.---- /1/g') 
	code=$(echo $code | sed 's/\.\.--- /2/g') 
	code=$(echo $code | sed 's/\.\.\.-- /3/g') 
	code=$(echo $code | sed 's/\.\.\.\.- /4/g') 
	code=$(echo $code | sed 's/\.\.\.\.\. /5/g') 
	code=$(echo $code | sed 's/-\.\.\.\. /6/g') 
	code=$(echo $code | sed 's/--\.\.\. /7/g') 
	code=$(echo $code | sed 's/---\.\. /8/g') 
	code=$(echo $code | sed 's/----\. /9/g') 
	code=$(echo $code | sed 's/----- /0/g') 
	code=$(echo $code | sed 's/-\.\.\. /B/g') 
	code=$(echo $code | sed 's/-\.-\. /C/g') 
	code=$(echo $code | sed 's/-\.\.- /X/g') 
	code=$(echo $code | sed 's/-\.-- /Y/g') 
	code=$(echo $code | sed 's/--\.\. /Z/g') 
	code=$(echo $code | sed 's/\.--\. /P/g') 
	code=$(echo $code | sed 's/--\.- /Q/g') 
	code=$(echo $code | sed 's/\.\.\.- /V/g') 
	code=$(echo $code | sed 's/\.\.\.\. /H/g') 
	code=$(echo $code | sed 's/\.-\.\. /L/g')
	code=$(echo $code | sed 's/\.--- /J/g') 
	code=$(echo $code | sed 's/\.\.-\. /F/g') 
	code=$(echo $code | sed 's/-\.\. /D/g') 
	code=$(echo $code | sed 's/--\. /G/g') 
	code=$(echo $code | sed 's/--- /O/g') 
	code=$(echo $code | sed 's/\.\.- /U/g') 
	code=$(echo $code | sed 's/\.-- /W/g') 
	code=$(echo $code | sed 's/\.\.\. /S/g') 
	code=$(echo $code | sed 's/\.-\. /R/g') 
	code=$(echo $code | sed 's/-\.- /K/g') 
	code=$(echo $code | sed 's/\.- /A/g') 
	code=$(echo $code | sed 's/\.\. /I/g') 
	code=$(echo $code | sed 's/-- /M/g') 
	code=$(echo $code | sed 's/-\. /N/g') 
	code=$(echo $code | sed 's/\. /E/g') 
	code=$(echo $code | sed 's/- /T/g') 
	password=$(echo $code | sed 's/>//g') 
	echo "Unzip flag_$c.zip with $password"
	
	# Unzip
	7z X flag_$c.zip -P$password -y > /dev/null 2>&1
	if [ $? -ne 0 ]; then
		password=$(echo ${password,,})
		7z X flag_$c.zip -P$password -y > /dev/null 2>&1
	fi
	echo "7z X flag_$c.zip -P$password -y"
done

71 lines of code and 39 for the morse part.
It was fun.