← Back to Writeups
CUSTOMEasyMisc

Kotik (Cat)

XESXOR9/2/20264 min read
#misc#custom#easy#file_appending#header_repair#winzip_aes_cracking#zip_extraction#linux

Kotik (Cat)

Platform: duckerz | Category: Misc | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-01-08 | Status: Solved Techniques: file_appending, header_repair, winzip_aes_cracking, zip_extraction

Summary

Task: extract a flag hidden inside a JPEG image file. Solution: repair the corrupted JPEG header, find an appended ZIP archive via PK signature, extract the WinZip AES-256 encrypted ZIP, crack the password with hashcat using rockyou.txt, and read the flag.

Kotik (Cat) - duckerz CTF

Description

Original (Russian):

"Зачем мой друг постоянно кидает мне этих котиков, может он хочет мне что то сказать?"

Translation:

"Why does my friend keep sending me these cats, maybe he wants to tell me something?"

Files provided: kotik.jpg (124KB)

Analysis

Step 1: Initial File Inspection

bash
$ file kotik.jpg
kotik.jpg: data

The file command returns "data" instead of "JPEG image" - this indicates a corrupted or modified file header.

Step 2: Header Analysis

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

bash
$ xxd kotik.jpg | head -1
00000000: ddf8 dde0 0010 4a46 4946 0001 0100 0001  ......JFIF......

Problem identified: First bytes are ddf8dde0 instead of standard JPEG magic ffd8ffe0.

The bytes appear to be XORed or modified. Standard JPEG header:

  • FF D8 - JPEG SOI (Start of Image)
  • FF E0 - APP0 marker

Step 3: Fix JPEG Header

bash
# Fix the header bytes
printf '\xff\xd8\xff\xe0' | dd of=kotik.jpg bs=1 count=4 conv=notrunc

After fixing, the image displays a "demotivator" meme with a cat:

  • Text: "Демотиватор" (Demotivator)
  • Subtext: "нет блин мотиватор" (no, it's a motivator) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 4: Search for Hidden Data

bash
$ strings kotik.jpg | grep -i flag
flag.txt

$ xxd kotik.jpg | tail -20
# Found PK signature (0x504B) - ZIP archive marker

Step 5: Locate and Extract ZIP Archive

bash
# Find ZIP signature offset
$ xxd kotik.jpg | grep "504b"
0001e2f1: ... 504b 0304 ...

# Calculate offset (0x1e2f1 = 123761)
$ dd if=kotik.jpg of=hidden.zip bs=1 skip=123761

Step 6: Analyze ZIP Structure

bash
$ 7z l hidden.zip
# flag.txt - 47 bytes uncompressed
# Method: AES-256 (WinZip AES encryption)
# Compression method 99 indicates WinZip AES

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 7: Extract Hash for Cracking

The ZIP uses WinZip AES-256 encryption. Manual parsing of ZIP structure reveals:

Salt (16 bytes):      f70c6b895f0b778392844ad1e609103b
Verification (2 bytes): 3889
Encrypted data:       49 bytes
Auth code (10 bytes): 937e00d85e6d320c68ef

Hashcat format (mode 13600):

$zip2$*0*3*0*f70c6b895f0b778392844ad1e609103b*3889*31*[encrypted_data_hex]*937e00d85e6d320c68ef*$/zip2$

Step 8: Crack Password

bash
$ hashcat -m 13600 hash.txt rockyou.txt
# Password found: lifehouse

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 9: Extract Flag

bash
$ 7z x hidden.zip -plifehouse
$ cat flag.txt
DUCKERZ{REDACTED}

Solution Script

python
#!/usr/bin/env python3
"""
Kotik (duckerz CTF) - Steganography + ZIP AES cracking
"""

import subprocess
import struct

def fix_jpeg_header(filename):
    """Fix corrupted JPEG header"""
    with open(filename, 'r+b') as f:
        # Standard JPEG header: FF D8 FF E0
        f.write(b'\xff\xd8\xff\xe0')
    print(f"[+] Fixed JPEG header in {filename}")

def find_zip_offset(filename):
    """Find PK signature (ZIP) in file"""
    with open(filename, 'rb') as f:
        data = f.read()
    
    # Search for PK\x03\x04 (local file header)
    offset = data.find(b'PK\x03\x04')
    if offset != -1:
        print(f"[+] Found ZIP at offset: {offset} (0x{offset:x})")
        return offset
    return None
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

def extract_zip(filename, offset, output):
    """Extract embedded ZIP from file"""
    with open(filename, 'rb') as f:
        f.seek(offset)
        data = f.read()
    
    with open(output, 'wb') as f:
        f.write(data)
    print(f"[+] Extracted ZIP to {output}")

def create_hashcat_hash(zipfile):
    """
    Parse WinZip AES ZIP and create hashcat hash
    Mode 13600 format for WinZip AES
    """
    with open(zipfile, 'rb') as f:
        data = f.read()
    
    # Find AES extra field (0x9901)
    # This is simplified - real implementation needs full ZIP parsing
    # Key components needed:
    # - Salt (8 or 16 bytes depending on key size)
    # - Password verification value (2 bytes)
    # - Encrypted data
    # - Authentication code (10 bytes)
    
    print("[*] Parse ZIP structure manually or use zip2john")
    print("[*] Then crack with: hashcat -m 13600 hash.txt rockyou.txt")
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

if __name__ == "__main__":
    # Step 1: Fix header
    fix_jpeg_header("kotik.jpg")
    
    # Step 2: Find and extract ZIP
    offset = find_zip_offset("kotik.jpg")
    if offset:
        extract_zip("kotik.jpg", offset, "hidden.zip")
    
    # Step 3: Crack password (use hashcat externally)
    # hashcat -m 13600 hash.txt rockyou.txt
    # Password: lifehouse
    
    # Step 4: Extract with password
    # 7z x hidden.zip -plifehouse

Techniques Summary

StepTechniqueTool
1Header analysisfile, xxd
2Header repairdd, printf
3Hidden data searchstrings, xxd
4Archive extractiondd
5Password crackinghashcat (mode 13600)
6Final extraction7z
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Lessons Learned

  1. Always verify file headers - Even if extension is correct, headers can be corrupted/modified
  2. Check file endings - Archives are often appended to images (file concatenation steganography)
  3. WinZip AES cracking - Requires proper hash extraction; auth code position is critical
  4. rockyou.txt - Still effective for many CTF password challenges

Related Techniques

  • File header manipulation (XOR, byte swap)
  • Steganography by file concatenation
  • ZIP structure analysis
  • Password hash extraction and cracking ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍