The title of the challenge is qr-mania which points us in a certain direction.
Firstly, I started analyzing the file without opening it in wireshark, which is, in my opinion, the best way to start in this kind of challenges.
Commands used for basic anaylsis:
fileexiftoolbinwalk
However, binwalk sucesfully retrieved some .PNG headers so I extract them all using
foremost-Tchallenge.png
We've got a lot of .pngs file. Using exiftool on anyone of them, we see:
Comment: x/69
69 is clearly the size of the flag and x must be the position of the letter decoded in that QR. So I made a Bash script to sort them in the right order.
Afterwards, I realized that I can't just decode each QR code because some of them were invalid. Consequently, I made a script to convert all that colored QRs in black and white QRs that can easily be decoded.
We've got only one thing to do. Decode all of them and get the flag:
import cv2
import numpy as np
import os
INPUT_DIR = "."
OUTPUT_DIR = "output"
os.makedirs(OUTPUT_DIR, exist_ok=True)
for filename in os.listdir(INPUT_DIR):
if not filename.lower().endswith(".png"):
continue
input_path = os.path.join(INPUT_DIR, filename)
output_path = os.path.join(OUTPUT_DIR, filename)
img = cv2.imread(input_path)
if img is None:
print(f"[!] Could not read {filename}")
continue
# convert to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
# threshold on saturation
_, bw = cv2.threshold(
s, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU
)
# ensure black on white
if np.mean(bw) < 127:
bw = cv2.bitwise_not(bw)
# add quiet zone
bw = cv2.copyMakeBorder(
bw, 20, 20, 20, 20,
cv2.BORDER_CONSTANT, value=255
)
cv2.imwrite(output_path, bw)
print(f"[+] Processed {filename}")
print("[✓] Done")
import cv2
import os
import re
INPUT_DIR = "output"
detector = cv2.QRCodeDetector()
def extract_number(filename):
match = re.search(r'\d+', filename)
return int(match.group()) if match else 0
files = [
f for f in os.listdir(INPUT_DIR)
if f.lower().endswith(".png")
]
files.sort(key=extract_number)
results = []
for filename in files:
path = os.path.join(INPUT_DIR, filename)
img = cv2.imread(path)
if img is None:
results.append("")
continue
data, _, _ = detector.detectAndDecode(img)
if data:
results.append(data)
else:
results.append("")
# afișare finală
for line in results:
if line:
print(line, end="")