764 words
4 minutes
CodeVinci CTF 2026 - Final Boss - Miscellaneous Writeup

Category: Miscellaneous Flag: CodeVinci{17_w45_V3rY_d1ff1cUL7_t0_b34t_7H3_F1N4l_8055_MY_H4ND5_4R3_571LL_5H4K1NG}

Challenge Description#

A few days ago I started playing a video game: everything was going great, until I came across the Final Boss, which in my opinion was practically unbeatable. I wonder if anyone managed to beat it? 🤔

Analysis#

The file was a USB packet capture, which immediately suggested input-device telemetry rather than classic network traffic, so the first useful move was to confirm the container details and capture scope.

capinfos ~/Downloads/capture.pcapng
File encapsulation:  USB packets with USBPcap header
Number of packets:   1,826
Capture duration:    271.838474 seconds
Interface #0 info:
  Name = \\.\USBPcap2

At first glance there was no direct plaintext flag in payload strings, so I pivoted to structured decoding of recurring packet families. One host-to-device family (0900...) had two bytes that only toggled between 0x00 and 0x64, which looked like symbolic pulses rather than numeric telemetry.

python ~/Downloads/finalboss_symbol_analysis.py | rg "^rows=|^payload_rows=|^counts|^morse dot=A,dash=B:"
rows=282
payload_rows=277
counts Counter({'0': 140, 'A': 70, 'B': 42, 'C': 25})
morse dot=A,dash=B: 'MY_H4ND5_4R3_571LL_5H4K1NG'

That decode was real and clean, but using it alone as a full flag was a trap, because it was only one half of the message.

tableflip

The actual breakthrough came from the main device-to-host 2000.. stream. I decoded transitions in a button-like byte (off4) into press events and treated them as a 4-symbol alphabet. A base-4 mapping produced a valid flag prefix and sentence fragment ending with an underscore, proving there was still a second part to append.

python ~/Downloads/finalboss_2000_events.py | rg "^rows=|^press_events=|^press value counts|CodeVinci\\{"
rows=454
press_events=220
press value counts Counter({64: 82, 32: 59, 16: 51, 128: 28})
('CodeVinci', 0, 'CodeVinci{17_w45_V3rY_d1ff1cUL7_t0_b34t_7H3_F1N4l_8055_')

I then combined both independently decoded channels in one extractor script to avoid manual mistakes and to verify that the final candidate matched format and was not the previously rejected value.

python ~/Downloads/finalboss_extract_final.py
part1: CodeVinci{17_w45_V3rY_d1ff1cUL7_t0_b34t_7H3_F1N4l_8055_
part2: MY_H4ND5_4R3_571LL_5H4K1NG
candidate: CodeVinci{17_w45_V3rY_d1ff1cUL7_t0_b34t_7H3_F1N4l_8055_MY_H4ND5_4R3_571LL_5H4K1NG}
valid_format: True
is_rejected: False

When the two channels were merged, the final flag was complete and consistent with the challenge hint about adding the closing brace.

smile

Solution#

# ~/Downloads/finalboss_extract_final.py
import subprocess
import re

PCAP = "/home/rei/Downloads/capture.pcapng"


def decode_part1_from_2000():
    # Derived from successful event decoding: use press sequence of off4 values and base4 mapping perm=4
    # Values sorted [16,32,64,128], mapping for perm=4 corresponds to tuple (0,3,1,2)
    # i.e. 16->0, 32->3, 64->1, 128->2
    cmd = [
        "tshark", "-r", PCAP,
        "-Y", "usb.endpoint_address==0x82 && usb.capdata && usb.capdata[0:2]==20:00",
        "-T", "fields", "-e", "usb.capdata"
    ]
    out = subprocess.check_output(cmd, text=True, errors="replace")
    rows = []
    for line in out.splitlines():
        cap = line.strip().lower()
        if len(cap) == 88:
            b = bytes.fromhex(cap)
            rows.append(b)

    off4 = [b[4] for b in rows]
    presses = []
    prev = off4[0]
    for v in off4[1:]:
        if v != prev:
            if prev == 0 and v in (16, 32, 64, 128):
                presses.append(v)
            prev = v

    mapping = {16: 0, 32: 3, 64: 1, 128: 2}
    q = [mapping[x] for x in presses]
    data = bytearray()
    for i in range(0, len(q) - 3, 4):
        data.append((q[i] << 6) | (q[i + 1] << 4) | (q[i + 2] << 2) | q[i + 3])
    part1 = data.decode("latin1", errors="ignore")
    return part1


def decode_part2_from_0900():
    # Decode symbolic Morse from 0900 packets: A=(64,0), B=(0,64), C=(64,64), 0=(0,0)
    MORSE = {
        ".-":"A","-...":"B","-.-.":"C","-..":"D",".":"E","..-.":"F","--.":"G","....":"H","..":"I",".---":"J","-.-":"K",".-..":"L","--":"M","-.":"N","---":"O",".--.":"P","--.-":"Q",".-.":"R","...":"S","-":"T","..-":"U","...-":"V",".--":"W","-..-":"X","-.--":"Y","--..":"Z",
        "-----":"0",".----":"1","..---":"2","...--":"3","....-":"4",".....":"5","-....":"6","--...":"7","---..":"8","----.":"9","..--.-":"_"
    }
    cmd = [
        "tshark", "-r", PCAP,
        "-Y", "usb.endpoint_address==0x02 && usb.capdata && usb.data_len==13",
        "-T", "fields", "-e", "usb.capdata"
    ]
    out = subprocess.check_output(cmd, text=True, errors="replace")
    syms = []
    for line in out.splitlines():
        cap = line.strip().lower()
        if len(cap) != 26:
            continue
        b = bytes.fromhex(cap)
        if not (b[0] == 0x09 and b[1] == 0x00 and b[3] == 0x09 and b[4] == 0x00 and b[5] == 0x0F and b[10] == 0xFF and b[11] == 0x00 and b[12] == 0xEB):
            continue
        x, y = b[8], b[9]
        if x == 0 and y == 0:
            syms.append('0')
        elif x == 0x64 and y == 0:
            syms.append('A')
        elif x == 0 and y == 0x64:
            syms.append('B')
        elif x == 0x64 and y == 0x64:
            syms.append('C')

    # drop init 5 entries (empirically validated)
    syms = syms[5:]
    nz = [s for s in syms if s != '0']

    cur = ""
    outtxt = ""
    for s in nz:
        if s == 'A':
            cur += '.'
        elif s == 'B':
            cur += '-'
        elif s == 'C':
            if cur:
                outtxt += MORSE.get(cur, '?')
                cur = ""
    if cur:
        outtxt += MORSE.get(cur, '?')
    return outtxt


def main():
    rejected = {"CodeVinci{MY_H4ND5_4R3_571LL_5H4K1NG}"}
    p1 = decode_part1_from_2000()
    p2 = decode_part2_from_0900()
    print("part1:", p1)
    print("part2:", p2)

    # If p1 already full, keep it. If p1 ends with '_' combine with p2.
    if re.fullmatch(r"CodeVinci\{[^}]+\}", p1):
        flag = p1
    elif p1.startswith("CodeVinci{"):
        body = p1[len("CodeVinci{"):]
        if body.endswith("_") and p2:
            flag = f"CodeVinci{{{body}{p2}}}"
        else:
            flag = f"{p1}}}"
    else:
        flag = f"CodeVinci{{{p2}}}"

    print("candidate:", flag)
    print("valid_format:", bool(re.fullmatch(r"CodeVinci\{[^}]+\}", flag)))
    print("is_rejected:", flag in rejected)


if __name__ == "__main__":
    main()
python ~/Downloads/finalboss_extract_final.py
part1: CodeVinci{17_w45_V3rY_d1ff1cUL7_t0_b34t_7H3_F1N4l_8055_
part2: MY_H4ND5_4R3_571LL_5H4K1NG
candidate: CodeVinci{17_w45_V3rY_d1ff1cUL7_t0_b34t_7H3_F1N4l_8055_MY_H4ND5_4R3_571LL_5H4K1NG}
valid_format: True
is_rejected: False
CodeVinci CTF 2026 - Final Boss - Miscellaneous Writeup
https://blog.rei.my.id/posts/83/codevinci-ctf-2026-final-boss-miscellaneous-writeup/
Author
Reidho Satria
Published at
2026-03-10
License
CC BY-NC-SA 4.0