← Back to Writeups
CUSTOMEasyMisc

Змеелов (Snake Catcher)

XESXOR9/2/20263 min read
#misc#custom#easy#pyc_magic_recognition#serpent_encoding_decode#strings_flag_extraction#token_alphabet_indexing#linux

Змеелов (Snake Catcher)

Platform: hackerlab | Category: Misc | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-07-10 | Status: Solved Techniques: pyc_magic_recognition, serpent_encoding_decode, strings_flag_extraction, token_alphabet_indexing

Summary

Task: a Python file is one triple-quoted ASCII-art snake built from 168 tokens of form [PYTHON]{2}[0-9]. Solution: the title Змеелов points to Serpent encoding — each token maps to a byte via a 32-symbol letter-pair alphabet plus 32*digit, yielding a Python 2.7 .pyc whose string constant is the flag (readable with strings).

Змеелов (Snake Catcher) — hackerlab

Description

Предстоит проявить мастерство и стратегическое мышление, чтобы поймать хитрых пресмыкающихся, избегая их смертоносных укусов.

English summary: You must show skill and strategic thinking to catch the cunning reptiles while avoiding their deadly bites. A ZIP archive snake_catcher.zip is provided. It contains a single file flag (3281 bytes) — a Python script whose entire content is one triple-quoted ASCII-art block depicting a snake/totem wrapped around a pole. The goal is to recover the flag hidden in the art. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Analysis

The ASCII art is built from many 3-character tokens such as PY0, HN3, PO3, TH3, YY7. Inspecting them reveals a strict structure:

  • Each token has the form [PYTHON]{2}[0-9]: two letters drawn only from the distinct letters of the word "PYTHON" (P, Y, T, H, O, N), followed by a single digit.
  • Only the digits 0, 1, 2, 3, 7 appear.
  • There are exactly 168 such tokens in reading order.

Two letters from a 6-symbol set give up to 32 useful ordered pairs, and one digit acts as a multiplier — this smells like a byte-per-token encoding: base + 32 * digit, which spans the full 0–255 byte range. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

The semantic leap

The decisive clue is the wordplay in the title. «Змеелов» / "Snake Catcher" + tokens spelling PYTHON point directly to the Serpent encoding (a snake ≡ serpent). In misc challenges the title frequently names the exact technique.

Solution

Serpent encoding maps each token to one byte:

  1. The two-letter prefix indexes into a fixed 32-symbol alphabet of ordered letter pairs.
  2. The trailing digit is a high multiplier (× 32).
  3. byte = ALPHABET.index(token[:2]) + 32 * int(token[2]) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Alphabet (32 ordered letter pairs):

["PY","PT","PH","PO","PN","YP","YT","YH","YO","YN",
 "TP","TY","TH","TO","TN","HP","HY","HT","HO","HN",
 "OP","OY","OT","OH","ON","NP","NY","NT","NH","NO","PP","YY"]

Solver:

python
#!/usr/bin/env python3
import re
from pathlib import Path

ALPHABET = [
    "PY","PT","PH","PO","PN","YP","YT","YH",
    "YO","YN","TP","TY","TH","TO","TN","HP",
    "HY","HT","HO","HN","OP","OY","OT","OH",
    "ON","NP","NY","NT","NH","NO","PP","YY",
]
tokens = re.findall(r"[PYTHON]{2}[0-9]", Path("extracted/flag").read_text())
bytecode = bytes(ALPHABET.index(t[:2]) + 32 * int(t[2]) for t in tokens)
Path("decoded.pyc").write_bytes(bytecode)   # magic 03 f3 0d 0a -> Python 2.7 .pyc
print(re.search(rb"CODEBY\{[^}]+\}", bytecode).group().decode())
# -> CODEBY{REDACTED}

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

Verification

Decoding all 168 tokens produces 168 bytes whose first 4 bytes are 03 f3 0d 0a — the Python 2.7 .pyc magic. This immediately validates the decoding hypothesis: the byte stream is a compiled Python 2.7 module.

No full decompilation is needed. The flag is stored as a string constant in the bytecode, so strings on the recovered .pyc reveals it directly (also showing serpent and flag.py):

bash
strings decoded.pyc   # shows CODEBY{...}, serpent, flag.py

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