For this challenge, we get what looks like a zip archive called dump.zip
with the hint "Every single archive manager unpacks this to a different file...". Unzipping normally gives us a single file called hello.txt
which doesn't contain anything useful.
However, running binwalk dump.zip
shows us another file called hi.txt
, along with many other files named flag00
to flag18
. Each flagNN
is repeated several times. Binwalk also tells us that all of the files have the same compressed/uncompressed size, indicating that they're too small to be compressed, and that each flagNN
is only 1 byte, indicating that each one probably represents a single character of the flag.
Running strings dump.zip
suggests, based on looking at hello.txt
, that each file's contents are stored immediately after the filename followed by a PK
:
V~uK)
hello.txtThere's more to it than meets the eye...
V~uK)
hello.txtPK
hi.txtFind a needle in the haystack...
hi.txtPK
flag00aPK
flag00PK
flag00bPK
flag00PK
flag00cPK
flag00PK
...
Using this pattern, we can see that there are 36 files with each flagNN
filename, and that each flagNN
has the same 36 files. This suggests that those 36 characters are the characters used in the flag, and that some other information will tell us which of the 36 files is the right one for each character. Since zip files also store information about directory structure, it seems likely that that's what we need.
The root directory of a zip archive is called the "central directory", and it's identified by a 4-byte "end of central directory" magic number, 50 4b 05 06
. (It's frequently written in little endian as 0x06054b50
, but that's a little confusing because it's not the order the bytes show up in in the file). Our file dump.zip
actually has around 20 end of central directory signatures. Zip files allow this, since it used to be common at one point to modify a zip file by adding a new central directory instead of changing the old one. Programs that read zip files will find the last end of central directory signature and use that one, as explained here.
Since we have around 20 central directories, and our flag files are numbered 0 to 18, it stands to reason that each character in the flag is represented by one central directory, which points to one of the flag files. Therefore, we just want to unzip each of the central directories. Since the standard unzip
utility will use the last end of central directory signature, we can just delete each one starting from the end and call unzip
in order to unzip all of them. The attached file sol.py
does this, with comments explaining the process in more detail. This gives us a single file for each character, and putting those together gives us the flag.