forensics

Challenges

diskchal

i accidentally vanished my flag, can u find it for me

  • photorec or binwalk

  • and then gunzip the thing

  • press c — you will have a gzip file

  • gunzip it, the flag is inside

  • scriptCTF{1_l0v3_m461c_7r1ck5}

pdf

so sad cause no flag in pdf :(

  • Just binwalk

  • scriptCTF{pdf_s7r34m5_0v3r_7w17ch_5tr34ms}

Just Some Avocado

just an innocent little avocado!

  • It tooks me a while, but with the strings command, you will have a good idea of what this challenge is all about

strings avocado.jpg > strings 
...
justsomezip.zipUT	
2[hux
*[4n6
V"VI
T@O;++
{2A;
staticnoise.wavUT
...	
  • Now that we know the files we will be working with are justsomezip.zip and staticnoise.wav, next is foremost to carve those files out.

❯ foremost avocado.jpg
Processing: avocado.jpg
|foundat=justsomezip.zipUT*|
❯ tree -L 2
.
├── audit.txt
├── jpg
│   └── 00000000.jpg
└── zip
    └── 00000196.zip

3 directories, 3 files
  • Put the zip into an zip2john and hashcat it with rockyou (when in doubt, rock you).

  • ❯ hashcat -m 17225 hashes.txt rockyou.txt
    
    $pkzip$2*1*1*0*8*24*6cd4*0bd6da0575615b94ae31035ac9d1c8788a24ea0de3a34e116abc6df32146b93ccdd15fd1*2*0*ea*de*f1b363b7*0*49*0*ea*9a00*06bda6dfd28f8144ef8268b6dc5e96a9c5812a5b346e36b1882fe39e1546c9eceb715bb83c6fad10cd3c18ddc156b496e45622564905a8725a5aeba3957b5de2ff4514a8967030c20c0235bd1f2f18cd6042b8f9def121a1157115390213e3bbd3b191c5c3227dbcbfbcc5b8a15ce0797c75ff32b8df0ed5f294785da83afa16e6bbbc8938a093df54404f3b2b2babdc8d045caa091b8a0fa70589e6696105a0b1abb74a6db513086c3d9e71cf7214bbee76d8ab75e50882a3f63794f9983f6d8ba9c8e27a0dc4110294b19008304109ca2691024027cb7b32413b91fb8ee08b7f19674a68ef5b98b438*$/pkzip$:impassive3428
  • Use the password

  • ❯ unzip -l -P impassive3428 00000196.zip
    
    Archive:  00000196.zip
      Length      Date    Time    Name
    ---------  ---------- -----   ----
          222  2025-06-24 16:16   justsomezip.zip
       437908  2025-06-25 10:38   staticnoise.wav
    ---------                     -------
       438130                     2 files
  • Now this is when the challenge got me, I couldn't bother to install Sonic to my machine but I could generate the spectrogram from the terminal, of course through a couple trials and errors to see if I can just read it from here...Finally, I ended up with.

  • sox staticnoise.wav -n spectrogram -o spectrogram.png -x 1024 -y 513 -z 120 -q 249
  • Again....hashcat (if you know it is 8 characters long password for the justsomezip.zip — throw it in zip2john again)

❯ hashcat -m 17225 hash.txt -a 3 "?1?1?1?1?1?1?1?1" --custom-charset1=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 --show

$pkzip$1*2*2*0*28*1c*fa7008be*0*42*0*28*9995*4dfaa9e2e4af466a58883a0709d6ba25d6df0382b5c3eb6524b0baae444268ae7611a9f3a64250aa*$/pkzip$:d41v3ron
  • use the password d41v3ron and you will get the flag (🐧 yay!).

  • scriptCTF{1_l0ve_d41_v3r0n}

Off By One (upsolve)

i hid a qr inside a qr

upsolve — 💤💤💤

  • Stegsolve — 👨‍🍳💋

  • Or use a decoder online, my favorite tool is.

  • StegSolve (StegOnline) have a really really really really really good check list. And I mean really good.

  • I simply follow the check list till we found an anomaly of step 6 , while checking the blue plane color of the image

  • That is progress, now we can simply extract and see what is being hide there

  • At this point, it becomes really challenging to determine what this hex data represents. Despite using various converter tools (cyberchef, online decoder, dcode.fr, etc), I couldn't obtain any meaningful results.

  • "I hid a qr inside a qr" — breh — the hex is a qr image?

  • What I do know about qr code is

    • QR codes must be perfect squares (21x21, 25x25, 29x29, etc.)

    • So if we want to convert hex to image, we have to make sure a couple conditions, like the length of our data — If your data length doesn't form a perfect square when converted to binary, we need to trim the excess bits. (is that why we are "off by one"?)

    • Each bit likely represents a single pixel (1 = black module, 0 = white module)

  • Here is ultimately my solution:

    • Convert hex → bytes → individual bits

    • Calculate the largest possible square dimensions from the available bits

    • Trim the bit array to exactly fit a perfect square matrix

    • Map each bit to a pixel value (1 → black/0, 0 → white/255)

import numpy as np
from PIL import Image

def create_qr_from_hex(hex_string):
    raw_bytes = bytes.fromhex(hex_string)
    byte_array = np.frombuffer(raw_bytes, dtype=np.uint8)
    binary_bits = np.unpackbits(byte_array)

    total_bits = len(binary_bits)
    # print("total_bits len:", total_bits)
    square_root = int(np.sqrt(total_bits))

    # Optional of finding the perfect bits, even if we have extra f at the end of the hex
    while square_root * square_root > total_bits:
        square_root -= 1
        total_bits -= 1

    # Reshape and create image
    perfect_square_bits = square_root * square_root
    trimmed_bits = binary_bits[:perfect_square_bits]
    qr_matrix = trimmed_bits.reshape(square_root, square_root)

    # Convert to image format
    pixel_data = np.where(qr_matrix == 1, 0, 255).astype(np.uint8)
    qr_image = Image.fromarray(pixel_data, mode='L')

    return qr_image.resize((square_root * 10, square_root * 10), Image.NEAREST)

result = create_qr_from_hex("000000000000000fe423f8416cd042e9c0ba175ae5d0ba28ae841519043faaafe00010000fbedd507ce16a80a9763e120e6a20ffd7e6842356b025f148610054e20a38ffa800734683fb6ab610425100bad1fb85d4638c2eb1d5210519710feaa058000000000000007fffffffffff")
result.save("qr.png")
  • This took...a crazy amount of trials and errors, as a couple of my first attempts look like some pixelated horrors.

  • Ultimately...the correct hex is extracted (yay 😭)

  • the flag is the qr code. scriptCTF{qrqrqrc0d3s}

Last updated