4 minutes
Eternal Loop
Note to fellow-HTBers: Only write-ups of retired HTB machines or challenges are allowed.
Challenge info ¶
Eternal Loop [by MinatoTW]
Can you find a way out of this loop?
The challenge ¶
We start of by downloading the Eternal_Loop.zip file and verifying it’s sha256sum with the hash displayed on the challenge page.
$ echo "4246a77b6ca2a2844749437d1a441fc759c6b8ec316187647cd9b1019da6f6fc Eternal_Loop.zip" | sha256sum -c -
Eternal_Loop.zip: OK
We then proceed to unzip this file using the password provided on the challenge page. This will give us a whole directory structure with multiple folders and files.
$ unzip Eternal_Loop.zip
Archive: Eternal_Loop.zip
[Eternal_Loop.zip] 37366.zip password:
extracting: 37366.zip
This zip file contains another zip file, and is again password protected.
$ unzip -l 37366.zip
Archive: 37366.zip
Length Date Time Name
--------- ---------- ----- ----
460340 2018-05-23 10:02 5900.zip
--------- -------
460340 1 file
So we go ahead and crack the password. We follow the same path as we did for the fs0ciety challenge: create a hashfile and crack using john.
$ zip2john 37366.zip > 37366.zip.hash
ver 2.0 37366.zip/5900.zip PKZIP Encr: cmplen=460497, decmplen=460340, crc=4DB4F8A
$ john 37366.zip.hash
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
5900 (37366.zip/5900.zip)
1g 0:00:00:00 DONE 1/3 (2019-09-04 12:18) 20.00g/s 320.0p/s 320.0c/s 320.0C/s z5900..Zip5900
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Note how the password is the same as the filename of the contained zip (5900).
This zip file again contains another zip file. We test using this zip’s filename as password to unzip the parent zip, and it works!
$ unzip -l 5900.zip
Archive: 5900.zip
Length Date Time Name
--------- ---------- ----- ----
460067 2018-05-23 10:02 49805.zip
--------- -------
460067 1 file
$ unzip 5900.zip
Archive: 5900.zip
[5900.zip] 49805.zip password:
inflating: 49805.zip
Note that you can pass the unzip password using the -P
parameter.
$ unzip -l 49805.zip
Archive: 49805.zip
Length Date Time Name
--------- ---------- ----- ----
459794 2018-05-23 10:02 13811.zip
--------- -------
459794 1 file
$ unzip -P 13811 49805.zip
Archive: 49805.zip
inflating: 13811.zip
Automation for the win! ¶
By now, we know we can expect to have to unzip *a lot* of these password protected zip files. So let’s turn to automation.
We know the name of the contained zip will be the password. So we need to extract the filelist of the parent zip, extract the contained zip’s filename, pass this as a password and repeat the process for the contained zip.
My script might not be the prettiest, but with some simple grep’ing I was able to extract the filelist and use it as a password. I keep doing this until I get an unsuccessful unzip (status code != 0), which means I’ve probably reached the end.
#!/bin/bash
ZIPFILE=$1
RESULT=0
while [ $RESULT -eq 0 ]
do
PASSWORD=$( unzip -l $ZIPFILE | grep -E "^\s+[0-9]+" | grep -Eo "[0-9]+\.zip" | grep -Eo "[0-9]+" )
unzip -P "$PASSWORD" "$ZIPFILE"
RESULT=$?
echo "Unzipped $ZIPFILE using password $PASSWORD ($RESULT)"
ZIPFILE="$PASSWORD.zip"
done
Run the script, passing the filename of the last zip we manually unzipped and watch as dozens of lines flash by until we get an incorrect password.
$ ./unziprecursive.sh 13811.zip
Archive: 13811.zip
inflating: 45133.zip
Unzipped 13811.zip using password 45133 (0)
Archive: 45133.zip
[...]
Archive: 27833.zip
inflating: 6969.zip
Unzipped 27833.zip using password 6969 (0)
Archive: 6969.zip
skipping: DoNotTouch incorrect password
Unzipped 6969.zip using password (82)
We now end up with 6969.zip
which contains a file named DoNotTouch
and who’s password is not “DoNotTouch”.
So back to cracking:
$ zip2john 6969.zip > 6969.zip.hash
$ john --wordlist=/usr/share/wordlists/rockyou.txt 6969.zip.hash
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
letmeinplease (6969.zip/DoNotTouch)
1g 0:00:00:00 DONE (2019-09-04 15:03) 10.00g/s 1392Kp/s 1392Kc/s 1392KC/s korn13..katiekatie
Use the "--show" option to display all of the cracked passwords reliably
Session completed
$ unzip -P letmeinplease 6969.zip
Archive: 6969.zip
inflating: DoNotTouch
This unzipped file appears to be a SQLite database file, as can be seen in the file header.
$ head DoNotTouch
SQLite format 3@
Getting the flag ¶
We could go ahead and browse the DB to look for the flag, but the DB contains quite a lot of …
$ sqlitebrowser DoNotTouch
… so let’s try something easier first ;)
$ strings DoNotTouch | grep HTB
1969-01-01 00:00:002069-01-01 00:00:00Chillin with SatanHellHTB{z1p_and_unz1p_ma_bruddahs}
And there we have it :)
HTB{z1p_and_unz1p_ma_bruddahs}