← Back to Writeups
CUSTOMEasyCrypto

XORDECRYPT

XESXOR9/2/20263 min read
#crypto#custom#easy#per_channel_state_recovery#row_wise_processing#xor_feedback_decryption

XORDECRYPT

Platform: CUSTOM | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: per_channel_state_recovery, row_wise_processing, xor_feedback_decryption

Summary

Walkthrough of the CUSTOM Crypto XORDECRYPT. Task: a noisy PNG hides the flag behind a custom XOR-based image transform. Solution: treat 0x67 as the initial state and decrypt each row independently with per-channel XOR feedback to reveal the ove

Description

I feel CHAINED to my desk, looking for some positive FEEDBACK.

We are given a PNG image named 0x67.png that appears heavily corrupted. The goal is to reverse the image transform and recover the hidden flag.

Challenge Summary

The image metadata is unhelpful: it is just a 1050x1050 RGB PNG with no useful embedded information. The real hints are in the challenge name, the clue text, and the filename.

  • XORDECRYPT suggests the image bytes were transformed with XOR.
  • CHAINED and FEEDBACK suggest a stateful mode rather than a fixed repeating key.
  • 0x67.png strongly suggests the initial state or IV is 0x67. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Testing simple XOR variants does not cleanly recover the image, but a row-wise feedback construction does.

Recon / Hint Interpretation

The visible image looks like structured XOR corruption: noisy, but not randomly destroyed. That usually means the original data is still present under a reversible bytewise transform.

The successful interpretation is:

  1. Process the image row by row.
  2. Treat each RGB channel independently.
  3. Initialize the running state for each row and each channel with 0x67.
  4. Decrypt pixels from left to right using XOR feedback. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

This matches the wording of the clue very well: the decryption is both chained and feedback-based.

Analysis

For a ciphertext byte c and current state state, the plaintext byte is:

text
p = c XOR state

Then the state evolves using the recovered plaintext byte:

text
state = state XOR p

Substituting the first equation into the second shows that the next state becomes the previous ciphertext byte, but the formulation above is the clearest way to implement the intended feedback process. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Applying this rule independently to each row and each color channel reconstructs a noisy but recognizable landscape image. The recovered image contains overlaid text with the flag:

text
UDCTF{REDACTED}

Solution

  1. Open the PNG and convert it to RGB.
  2. For each row, reset three channel states to 0x67.
  3. For each pixel from left to right, decrypt R, G, and B with the feedback rule.
  4. Save the resulting image and read the text shown in the recovered picture.
python
#!/usr/bin/env python3
from pathlib import Path
from PIL import Image
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

SRC = Path("tasks/BlueHens CTF 2026/XORDECRYPT/0x67.png")
DST = Path("tasks/BlueHens CTF 2026/XORDECRYPT/xordecrypt_decrypted.png")
IV = 0x67


def decrypt_row(rgb_row):
    state = [IV, IV, IV]
    out = []

    for pixel in rgb_row:
        plain_pixel = []
        for ch in range(3):
            c = pixel[ch]
            p = c ^ state[ch]
            state[ch] ^= p
            plain_pixel.append(p)
        out.append(tuple(plain_pixel))

    return out


img = Image.open(SRC).convert("RGB")
w, h = img.size
src_pixels = img.load()
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

out = Image.new("RGB", (w, h))
out_pixels = out.load()

for y in range(h):
    row = [src_pixels[x, y] for x in range(w)]
    dec = decrypt_row(row)
    for x in range(w):
        out_pixels[x, y] = dec[x]

out.save(DST)
print(f"saved decrypted image to {DST}")
print("flag: UDCTF{REDACTED}")

Running the script reveals the hidden text in the image and prints the same flag. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering per_channel_state_recovery, row_wise_processing, xor_feedback_decryption was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-04-22 • CUSTOM • XORDECRYPT • Difficulty: Easy