M0rsarchive
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 representing the number 9. Thus, the password for flag_999.zip should be 9.
Since we have 999 zip files like this, we need to write a script to automate the process.
Get the Hex Value of a PNG
First, let's get the hex value of the PNG:
convert *.png txt:-
There are 2 colors: #BC32D8 for the background and #FF3200 for the foreground.
convert *.png txt:- > hex.txt
grep "#FF3200" -C 1 hex.txt
If there are 3 pixels, it's a -, if there is 1 pixel, it's a . and the - is a space. The code should be 98.
Convert to morse
grep "#FF3200" -C 1 hex.txt | awk '{ print $3 }'
Now, let's format it in one line and replace the space with a random character:
grep "#FF3200" -C 1 hex.txt | awk '{ print $3 }' | awk '!NF{$0=">"}1' | xargs
Now replace #FF3200 #FF3200 #FF3200 with - and #FF3200 with .. Then remove everything that is not -, . or >. Finally, replace > with 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
We now have this string ----- ---... To translate it, replace Morse code with corresponding letters. Use sed for this:
sed 's/----- /9/'
sed 's/---.. /8/'
Add a > at the end to facilitate the translation:
Here's the script:
#!/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 simple but effective. We can make it more concise, but this works. The output will be the password for the zip file. Now, let's put everything together.
Assemble
In our script, we need to:
- Get Morse code
- Translate it
- Unzip the file
- Repeat
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 the morse code, I have to change the position of few sed command.
There is few dots remaining in the password. 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 … I had to change the password to lower case. I will use this:
echo "${a,,}"
Error 3
I’m trying manually.
The password looks good, the problem is somewhere else.
fillin_CFileInfo - internal error - MAX_PATHNAME_LEN
The path is too 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
This script automates the process of extracting the Morse code, translating it, and unzipping the files iteratively.