Fuck Da Binary
In this challenge, we are provided with a ZIP file. The first step is to check it out.
┌──(venv)─(kali㉿kali)-[]
└─$ exiftool idontlikebinaries.zip\?token=eyJ1c2VyX2lkIjoxNTg5LCJ0ZWFtX2lkIjo4NTQsImZpbGVfaWQiOjMwfQ.aQr8SQ.8dNjLlaf725wdc31PXoLuis1QmQ
ExifTool Version Number : 13.25
File Name : idontlikebinaries.zip?token=eyJ1c2VyX2lkIjoxNTg5LCJ0ZWFtX2lkIjo4NTQsImZpbGVfaWQiOjMwfQ.aQr8SQ.8dNjLlaf725wdc31PXoLuis1QmQ
Directory : .
File Size : 519 bytes
File Modification Date/Time : 2025:10:16 12:27:58-04:00
File Access Date/Time : 2025:11:05 02:28:34-05:00
File Inode Change Date/Time : 2025:11:05 02:28:31-05:00
File Permissions : -rw-rw-r--
Comment : i love S*cking H*es A*s more than 255 times
File Type : ZIP
File Type Extension : zip
MIME Type : application/zip
Zip Required Version : 10
Zip Bit Flag : 0
Zip Compression : None
Zip Modify Date : 2025:10:16 09:49:44
Zip CRC : 0x5efab170
Zip Compressed Size : 302
Zip Uncompressed Size : 302
Zip File Name : challenge.7z
The file metadata contains a curious comment: i love S*cking H*es A*s more than 255 times. The capitalized letters S, H, and A stand out, hinting at the SHA hashing algorithm. The number 255 is close to 256, strongly suggesting SHA256.
Extracting the ZIP file reveals another archive: challenge.7z. This inner archive is password-protected.

The challenge description provides the crucial hint for finding the password:
I usually secure important files using password hashes derived from the software I frequently use or tools that hold personal significance to me. Let me introduce you to Unikey — it’s more than just a typing tool, it represents the creativity and ingenuity of Vietnamese developers. As an open-source input method specifically designed for the Vietnamese language, Unikey has empowered millions to communicate, work, and code efficiently in their native tongue. It stands as a symbol of how local innovation can reach global standards, embodying the pride and technical spirit of Vietnam’s software community. Go check the latest version, u gonna love it.
The description clearly points to the following:
- using password hashes derived from the software
- The software is Unikey
- We need the latest version
Connecting this with the ZIP file comment, we deduce that the password is the SHA256 hash of the latest Unikey installer.
Lets download the latest UniKeyNT.exe and compute its hash:
┌──(venv)─(kali㉿kali)-[]
└─$ sha256sum UniKeyNT.exe
b732b1c198e7b0ebfcb0ef2f5d99f1888b5900460c1fa36ea27d47e8386684b1 UniKeyNT.exe
Using this hash as the password, we successfully extract the challenge.7z archive.
┌──(venv)─(kali㉿kali)-[]
└─$ 7z x challenge.7z -pb732b1c198e7b0ebfcb0ef2f5d99f1888b5900460c1fa36ea27d47e8386684b1
7-Zip 24.09 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-11-29
64-bit locale=en_US.UTF-8 Threads:32 OPEN_MAX:1024, ASM
Scanning the drive for archives:
1 file, 302 bytes (1 KiB)
Extracting archive: challenge.7z
--
Path = challenge.7z
Type = 7z
Physical Size = 302
Headers Size = 190
Method = LZMA2:12 7zAES
Solid = -
Blocks = 1
Everything is Ok
Size: 1105
Compressed: 302
After extract it give us a text file sus.txt.
┌──(venv)─(kali㉿kali)-[]
└─$ cat sus.txt
==============================>>==>=====>===========>=======================>================================>>=>>=>>=>>==>>>>=>==>==>==>===>==>==>==>==>==>==>==>==>==>==>==>==>==>>===>>=>>=========================================================>===>==>===========================================================================================>=======================>====>==>==>==>==>==>==>>====>==>==>==>==>==>==>==>==>==>==>==>>=====>================================>====>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>>================================>================================>====>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>>==========================================================================>====>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>>==========================================================================>===>>===========================================================================>===>===>==>==>==>==>>====>==>==>==>==>>==>===>>>====================>====>==>==>==>>===>=============>====================>==============>==
The content of sus.txt resembles a sequence of two characters: = and >. While this looks similar to Brainfuck code, attempting to decode it as such yields no meaningful result.
The next logical step is to interpret this sequence as a binary string. We replace = with 0 and > with 1.
┌──(venv)─(kali㉿kali)-[]
└─$ tr '=>' '01' < sus.txt > sus_bits.txt
┌──(venv)─(kali㉿kali)-[]
└─$ cat sus_bits.txt
000000000000000000000000000000110010000010000000000010000000000000000000000010000000000000000000000000000000011011011011001111010010010010001001001001001001001001001001001001001001100011011000000000000000000000000000000000000000000000000000000000100010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000100001001001001001001001100001001001001001001001001001001001001100000100000000000000000000000000000000100001001001001001001001001001001001001001001001001001001001001100000000000000000000000000000000100000000000000000000000000000000100001001001001001001001001001001001001001001001001001001001001100000000000000000000000000000000000000000000000000000000000000000000000000100001001001001001001001001001001001001001001001001001001001001001001100000000000000000000000000000000000000000000000000000000000000000000000000100011000000000000000000000000000000000000000000000000000000000000000000000000000100010001001001001001100001001001001001100100011100000000000000000000100001001001001100010000000000000100000000000000000000100000000000000100

This binary string is the key. The challenge name, “Fuck Da Binary” and the transformed data suggest this is a BinaryFuck program—a variant of Brainfuck that uses binary input.
We decode the binary string using a BinaryFuck interpreter.

Success! The decoding process reveals the final flag.
Flag: V1t{this_is_way_too_easy}
Thirsty Sick
First, when receiving the challenge ZIP file 360degree.zip and extracting it, we get a comment as follows:
┌──(kali㉿kali)-[]
└─$ unzip 360degree.zip
Archive: 360degree.zip
i am very Thirsty and feeling Sick
inflating: capture.pcap
The comment “i am very Thirsty and feeling Sick” reminded me of the challenge title. And “Thirsty Sick” sounds similar to “Thirty Six” (36). I thought this was a hint for this challenge.
After receiving the capture.pcap file, opening and examining it, I saw many packets with the same length.




Upon checking the content of these packets, I found a string of 360 characters, and other packets were the same.

Looking at the string in the first packet, I immediately guessed it was the header of a ZIP file. So, I tried to extract all these strings into a text file.
from scapy.all import *
import re
PCAP_FILE = "capture.pcap"
OUTPUT_FILE = "hex_strings.txt"
HEX_PATTERN = re.compile(r'Content-Length:\s*360\s*([0-9a-fA-F]{360})', re.DOTALL)
hex_strings = []
packets = rdpcap(PCAP_FILE)
for pkt in packets:
if pkt.haslayer(TCP) and pkt.haslayer(Raw):
payload = pkt[Raw].load
if len(payload) == 476:
try:
data = payload.decode('utf-8', errors='ignore')
except:
continue
match = HEX_PATTERN.search(data)
if match:
hex_str = match.group(1)
hex_strings.append(hex_str)
print(f"found: {hex_str[:64]}...")
with open(OUTPUT_FILE, 'w') as f:
for h in hex_strings:
f.write(h)
print(f"\nDone {len(hex_strings)} ")
print(f"Saved: {OUTPUT_FILE}")
┌──(kali㉿kali)-[]
└─$ python3 extract.py
found: 504b03041400000008008d54505bfa42b32b633a00007a49000005001c006d69...
found: 24130018b84f1ca7bd6c1ca47048fbf55feffccf93c153ffbe2a50dcc3bb447b...
found: ca54859d6d2602eb4f221d986560b935e939890e00f0f947ca543300948e33d3...
found: a10b9f087a0e7df8d073e8c2a7859e431f3ef41cbaf099a1e7d0870f3d872e7c...
found: 37ace8e1330f25fe9bfc6cb1a75f81cb0894e1712efde981f6cc7a2f43cf71cc...
found: 5071ddfe168a9e93da7cb0069d3236d63647e3ee50c9dd65487a0e78621f1f42...
(...)
After extracting to a text file, I converted the hex string into a ZIP file and extracted it, resulting in the mixed file.
┌──(kali㉿kali)-[]
└─$ unzip file.zip
Archive: file.zip
inflating: mixed
After checking the mixed file, I could see the header of a PNG file. Furthermore, upon checking the PNG tail, it was not located at the end of the file. This indicated that this file was a PNG that had been mixed with another file according to some rule.
Let’s check the total number of hex characters in the entire mixed file: we have 37620 characters. I noticed it was divisible by 36, so possibly the entire file was mixed in blocks, with each block containing 36 characters.
I tried to extract them into two files using the rule above and stopped at the PNG tail ‘AE426082’.
┌──(kali㉿kali)-[]
└─$ xxd -p mixed | tr -d '\n' > hex_mixed.txt
Export all hex of the mixed file to a text file.
INPUT_FILE = "hex_mixed.txt"
PNG_OUTPUT = "png_hex.txt"
OTHER_OUTPUT = "other_hex.txt"
BLOCK_SIZE = 36
PNG_TAIL = "AE426082"
with open(INPUT_FILE, 'r') as f:
data = f.read().strip().upper()
png_parts = []
other_parts = []
png_ended = False
for i in range(0, len(data), BLOCK_SIZE):
block = data[i:i + BLOCK_SIZE]
if len(block) < BLOCK_SIZE:
other_parts.append(block)
break
if i % (BLOCK_SIZE * 2) == 0: # Block 0, 2, 4,... → PNG
if not png_ended:
png_parts.append(block)
png_so_far = ''.join(png_parts)
if PNG_TAIL in png_so_far:
tail_pos = png_so_far.find(PNG_TAIL) + len(PNG_TAIL)
final_png = png_so_far[:tail_pos]
png_parts = [final_png]
png_ended = True
print(f"PNG end at {i//BLOCK_SIZE + 1}, {tail_pos} byte")
else:
other_parts.append(block)
else: # Block 1, 3, 5,...
other_parts.append(block)
with open(PNG_OUTPUT, 'w') as f:
f.write(''.join(png_parts))
with open(OTHER_OUTPUT, 'w') as f:
f.write(''.join(other_parts))
print(f"→ {PNG_OUTPUT}: {len(''.join(png_parts))} chars (PNG)")
print(f"→ {OTHER_OUTPUT}: {len(''.join(other_parts))} chars")
┌──(kali㉿kali)-[]
└─$ python3 extract_mixed.py
PNG end at 677, 12192 byte
→ png_hex.txt: 12192 chars (PNG)
→ other_hex.txt: 25416 chars
After exporting into two files, I obtained the desired PNG hex file.
┌──(kali㉿kali)-[]
└─$ cat png_hex.txt
89504E470D0A1A0A0000000D494844520000029F0000011A0806000000577D3CFE000000017352474200AECE1CE90000000467414D410000B18F0BFC6105000000097048597300000EC300000EC301C76FA8640000176549444154785EEDDD0B94ADF5F807F0B7C82289509242371162115D961C24B9954BB9
...
8CF009004019E113008032C227000065844F0000CA089F000094113E010028237C02005046F80400A08CF009004019E113008032C227000065844F0000CA089F000094113E010028237C02005046F80400A08CF009004019E1130000459AE6FF006A4B2B21A783C0800000000049454E44AE426082
I converted that string to a PNG file and saw the first half of the flag.

Now, let’s recall the challenge description:
I could see that the parts in the description described the steps I had just solved:
I chopped it into many pieces, put it back together, extracted it, tore it down again, twisted it, and rebuilt it once more.
- I chopped it into many pieces: This refers to the pcap file.
- put it back together: We combined them and got the ZIP file in this step.
- extracted it: Describes the step where we extracted the ZIP file to get the mixed file.
- tore it down again: This is the step we just did, which is splitting the mixed file into two different files.
- twisted it: This step definitely applies to the remaining hex file, meaning we had to twist (reverse) the entire hex string.
Let’s try it.
┌──(kali㉿kali)-[]
└─$ cat other_hex.txt
0000000000009DFF00A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82A8200A82
...
414141414141414141414141414141414141414141414141D0B0D04190505090504050404030103400BDFF415141218141618171F0C0515151413111016101B0B0E011E0D00121E0D0B0B0A0B0C0C0A0C080607070A0504040505080504030304030303030202030202030003400BDFF00000600060010101000649464A401000EFF8DFF
┌──(kali㉿kali)-[]
└─$ rev other_hex.txt > upsidedown.txt
FFD8FFE000104A46494600010101006000600000FFDB0043000302020302020303030304030304050805050404050A070706080C0A0C0C0B0A0B0B0D0E12100D0E110E0B0B1016101113141515150C0F171816141812141514FFDB00430103040405040509050509140D0B0D141414141414141414141
...
28A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A00FFD9
After revers, the header of a JPG file appeared. I tried to convert it to a JPG image file. And we got the other half of the flag.

Finally, combine the two halves, and we have obtained a complete flag:
Flag: V1t{ju57_4_fun_1_l1k3_p3nnyw0r7_b7w}
Tryna crack
Step 1 — Inspect the ZIP and choose an attack method
- List archive content:
┌──(kali㉿kali)-[]
└─$ zipinfo challenge.zip
Archive: challenge.zip
Zip file size: 19934 bytes, number of entries: 1
-rw-rw-rw- 3.0 unx 19718 BX stor 25-Oct-16 09:16 quackquackquack.png
1 file, 19718 bytes uncompressed, 19718 bytes compressed: 0.0%
Explanation:
BX stor→ the entry is stored (no compression). That implies two important things:- If the archive uses ZipCrypto, the ciphertext corresponds byte-for-byte to the plaintext (since there is no compression). This makes known-plaintext attacks practical.
- We can use fixed PNG structures (header + chunk names) as partial known plaintext to recover the key/keystream.
Step 2 — Known-plaintext attack (concept & example)
Concept
PNG files have a fixed header (89 50 4E 47 0D 0A 1A 0A) and well-known chunk names (IHDR, IDAT, IEND). Because the ZIP entry is stored, an attacker can feed a few bytes of known PNG plaintext to a ZipCrypto attack tool (e.g., bkcrack or pkcrack) to recover the keys and decrypt the entry.
- Prepare a small plaintext file containing the PNG header + the beginning of IHDR:
┌──(kali㉿kali)-[]
└─$ /bkcrack -C challenge.zip -c quackquackquack.png -p png.bin -d decrypted.png
bkcrack 1.7.1 - 2024-12-21
[05:25:47] Z reduction using 9 bytes of known plaintext
100.0 % (9 / 9)
[05:25:47] Attack on 783459 Z values at index 6
Keys: 4672d551 bcb3adcb c76d52c5
44.5 % (348404 / 783459)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 348404
[05:46:38] Keys
4672d551 bcb3adcb c76d52c5
[05:46:38] Writing deciphered data decrypted.zip
Wrote deciphered data (not compressed).
┌──(kali㉿kali)-[]
└─$ ls
challenge.zip decrypted.png png.bin
After success you will have decrypted.png in your directory.
Step 3 — Inspect the decrypted image

┌──(kali㉿kali)-[]
└─$ exiftool decrypted.zip
ExifTool Version Number : 13.25
File Name : decrypted.zip
Directory : .
File Size : 20 kB
File Modification Date/Time : 2025:11:03 05:46:38-05:00
File Access Date/Time : 2025:11:03 05:56:41-05:00
File Inode Change Date/Time : 2025:11:03 05:46:38-05:00
File Permissions : -rw-rw-r--
File Type : PNG
File Type Extension : png
MIME Type : image/png
Image Width : 806
Image Height : 184
Bit Depth : 8
Color Type : RGB with Alpha
Compression : Deflate/Inflate
Filter : Adaptive
Interlace : Noninterlaced
Exif Byte Order : Little-endian (Intel, II)
User Comment : password for zip file =)))) D4mn_br0_H0n3y_p07_7yp3_5h1d
SRGB Rendering : Perceptual
Gamma : 2.2
Pixels Per Unit X : 3779
Pixels Per Unit Y : 3779
Pixel Units : meters
Image Size : 806x184
Megapixels : 0.148
User Comment : password for zip file =)))) D4mn_br0_H0n3y_p07_7yp3_5h1d
That string is a bait — not the real flag. It’s intended to mislead you into thinking the password is the final flag.
Step 4 — Analyze the PNG file (hex) to “extend” the image
Goal: modify the chunk parameters in the PNG (or IEND) to make the image viewer read additional existing data in the file (or allow hidden bytes to be decoded/displayed). General procedure:
- View the hex / locate important chunks:
xxd quackquackquack.png | head
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
00000010: 0000 0326 0000 00b8 0806 0000 00bc a986 ...&............
00000020: ec00 0000 a465 5849 6649 492a 0008 0000 .....eXIfII*....
00000030: 0001 0069 8704 0001 0000 001a 0000 0000 ...i............
00000040: 0000 0001 0086 9207 0078 0000 002c 0000 .........x...,..
00000050: 0000 0000 0055 4e49 434f 4445 0070 0061 .....UNICODE.p.a
00000060: 0073 0073 0077 006f 0072 0064 0020 0066 .s.s.w.o.r.d. .f
00000070: 006f 0072 0020 007a 0069 0070 0020 0066 .o.r. .z.i.p. .f
00000080: 0069 006c 0065 0020 003d 0029 0029 0029 .i.l.e. .=.).).)
00000090: 0029 0020 0044 0034 006d 006e 005f 0062 .). .D.4.m.n._.b
Read the documentation about the PNG header signature: https://asecuritysite.com/forensics/png?file=%2Flog%2Fbasn0g01.png
From there, we can identify the position of the bytes containing the image height. For a PNG file: after the PNG signature, skip 4 bytes of IHDR and 2 bytes of width to locate 2 bytes of height.
Change the height value to increase the visible area of the image:
before: 00000010: 0000 0326 0000 00b8
after: 00000010: 0000 0326 0000 032b
Step 5 — Result: revealing the real flag (SHA512)

After extending the image, we get a complete sentence visible in the picture, but there’s also a Morse code sequence at the bottom:
... .... .- ..... .---- ..---

Decode it and we have the full message: “just kidding the real flag is the password in SHA512”
This means we need to take the ZIP password obtained earlier and convert it to SHA512:
┌──(kali㉿kali)-[]
└─$ echo -n "D4mn_br0_H0n3y_p07_7yp3_5h1d" | sha512sum
7083748baa3a42dc0a93811e4f5150e7ae1a050a0929f8c304f707c8c44fc95d86c476d11c9e56709edc30eba5f2d82396f426d93870b56b1a9573eaac8d0373
Flag: V1t{7083748baa3a42dc0a93811e4f5150e7ae1a050a0929f8c304f707c8c44fc95d86c476d11c9e56709edc30eba5f2d82396f426d93870b56b1a9573eaac8d0373}

