Back to Qu1ck5h0t's Writeups

This chall is a pretty special one because it had not one, but TWO fake flags used to catch out AI agents per a “no slop” policy. Also the first chall I solved where I had to combine my rev and forensics (and I guess steg) skills!

Downloading the handout gave a disk image file called Gelatino.img. I first began with opening it in Disk Drill (one of the best software for disk forensics) and recovered the disk files. Poking around, I noticed that vault.b64 opened in notepad like a regular text file and read in what seemed to be English (so plaintext), but with weird characters in between (yes it was even green somehow)

Opening it in a hex editor, I found a bunch of occurrences of hex values E2808B and E2808C. Turns out they’re unicode for what’s called zero width characters, and they don’t render on a lot of programmes.

When the non delimiter/plaintext characters were removed, they resembled binary a lot. I wrote a script that takes all occurrences of zero width chars in order, encodes them by 1s and 0s then back to ASCII.

import re

import sys

from pathlib import Path

text = (

    Path(sys.argv[1]).read_text(encoding="utf-8")

    if len(sys.argv) > 1

    else sys.stdin.read()

)

markers = re.findall(r"E2808[B C]".replace(" ", ""), text.upper())

bits = "".join("1" if marker == "E2808B" else "0"

               for marker in markers)

complete_length = len(bits) - len(bits) % 8

binary = bits[:complete_length]

decoded = bytes(

    int(binary[i:i + 8], 2)

    for i in range(0, len(binary), 8)

)

print(decoded.decode("ascii"))

Which got me the flag!

Securinets{z3r0_w1dth_mmm_h0w_d1d_th4t_h4pp3n}

…

Except it wasn’t actually the flag.

Apparently it was bait for AI agents, and people get banned for submitting it.

The author was chill though, and pointed me towards memdisk.pack. It didn’t follow any of the regular .pack conventions, so it had to be decrypted by something else on the disk. I opened BOOTX64.efi in an online decompiler and looked for where it referenced memdisk.pack, which I found in efi_main.

Scrolling down, I found the part with the logic for decrypting memdisk.

Combining inference from the rest of the function and some guesswork, I could roughly figure out what the variables do. rax_54 is intended to be the output (unpacked byte) y. While intimidating, the whole expression within the pointer evaluates to the unpacked input byte, for which MUSASHIX kindly informed me that var_60 is the base, and rax_31 is the span. Hence, var_18_1 could be interpreted as some form of counter variable i by deduction. That leaves the logic to be somewhat like

y = (i * 61 - 89) ⊕ ror8(*((i * 13 mod span) + 16 + base), i ∧ 7)

For ror8(x,n) indicates an 8 bit rightwards shift of x by n. Also interesting to note here that COMBINE() just extends var_18_1 * 0xd to a 64 bit expression by prepending a 32 bit register of 0, or in other words nothing of use to me.

Following that, I wrote a script that runs the unpacking algorithm against a hexadecimal representation of memdisk.pack I extracted.

import struct

data = bytes.fromhex(open("memdisk.txt").read())

span = struct.unpack("<I", data[12:16])[0]

payload = data[16 : 16 + span]

ror8 = lambda v, s: v if (s & 7) == 0 else (((v >> (s & 7)) | (v << (8 - (s & 7)))) & 0xff)

out = bytes(((i * 61 - 89) & 0xff) ^ ror8(payload[(i * 13) % span], i) for i in range(span))

print(out.hex())

MUSASHIX mentioned something about CPIO archives, and when I looked up the header it also matched the output from my script. So I wrote another one to unpack the CPIO archive, and ended up with two files, order_history.txt and blends.lst

Since there was a specific note about tickets being “flavor-ticket number”, I figured that should be some sort of password.

It was pretty obvious pistachio is the flavour since it said “pistachio was always the owner’s favourite” with a pistachio order made by “Filip the owner”, but the ticket number was unclear. 18 for the number could’ve made sense since pistachio was the 18th order made, but what ended up being the correct number was 37 since pistachio was the 37th item on the list, which makes the password “pistachio-37”. Apparently the latter line of reasoning was an “AI answer” (quoting the author) and I got hella pressed when I made the guess, but I don’t know how else I’d get the number.

Before I continue, I’m going to show you the SECOND fake flag. I didn’t actually get this before I got the real flag because it didn’t occur to me that I’d use strings for the chall.

Securinets{1_h0p3_u_d0n’t_uS3_th1s_sl0p}

Moving forward, I knew I had a password that I needed to decrypt something with. Nothing in the decrypted EFI was present, so I looked for another partition because Disk Drill said there were three even though I only found one partition. Indeed, 7zip was able to identify another partition that Disk Drill could not identify.

However, 7zip complained it was corrupted and FTK Imager tried to extort me into buying their “pro edition” to decrypt it. Luckily Autopsy had my back and identified the partition as LUKS encrypted.

After some Googling, I figured out how to decrypt LUKS and used the password from before

I then opened the decrypted partition in 7zip, and found two files. I was told by the author that recipe.enc is indeed where the flag lies and not another trap for LLM agents, so I went on with decrypting that.

Looking through the hex, recipe.enc has “Salted__” as its header.

Another quick Google search told me that Salted__ is the header for openssl, which typically uses aes-256-cbc. Following the convention, I decrypted the .enc file with the same password as the partition (MUSASHIX: “think about it for a little bit and you'll know”) and got the flag!

Flag: Securinets{n3xt_time_buy_s0m3th1ng_h34lthy}