← Back to Writeups
CUSTOMMediumReversing

Змеиный укус (Snake Bite)

XESXOR9/2/20263 min read
#reversing#custom#medium#file-format-identification-fro#python-bytecode-manual-analysi#xor-cipher-reversal-with-known

Змеиный укус (Snake Bite)

Platform: hackerlab | Category: Reversing | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2025-12-27 | Status: Solved Techniques: File format identification from decrypted output, Python bytecode manual analysis, XOR cipher reversal with known key

Summary

Task: Analyze disassembled Python bytecode and decrypt an encrypted file. Solution: Extract XOR key from bytecode constants and apply reversible XOR decryption to recover a PNG image with the flag.

Змеиный укус (Snake Bite) — HackerLab

Description

Вас покусала змея. Пришло время читать байткод!

Files

  • program.txt — disassembled Python bytecode
  • flag.enc — encrypted flag

Analysis

Bytecode Investigation

The program.txt file contains Python dis module output — disassembled bytecode of two functions.

main Function

Disassembly of main:
  LOAD_CONST               0 (0)
  LOAD_CONST               1 (('FLAG',))
  IMPORT_NAME              0 (secret)
  IMPORT_FROM              1 (FLAG)
  ...
  LOAD_CONST               2 ('ZHEkjgfhdiIR')
  ...
  CALL_FUNCTION            2
  ...
  LOAD_CONST               3 ('flag.enc')
  LOAD_CONST               4 ('wb')
  ...

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

From the bytecode we can see:

  1. FLAG is imported from the secret module
  2. Encryption key: 'ZHEkjgfhdiIR'
  3. Function encrypt(flag, key) is called
  4. Result is written to flag.enc in binary mode

encrypt Function

Disassembly of encrypt:
  LOAD_CONST               1 (b'')
  STORE_FAST               2 (c)
  ...
  FOR_ITER                 ...
  ...
  BINARY_XOR
  ...

Analysis reveals a classic XOR cipher:

  • For each byte a[i], XOR is performed with ord(b[i % len(b)])
  • a — source data (flag)
  • b — encryption key ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Reconstructed Algorithm

python
def encrypt(a, b):
    c = b''
    for i in range(len(a)):
        c += bytes([a[i] ^ ord(b[i % len(b)])])
    return c

def main():
    from secret import FLAG
    key = 'ZHEkjgfhdiIR'
    encrypted = encrypt(FLAG, key)
    with open('flag.enc', 'wb') as f:
        f.write(encrypted)

Solution

XOR encryption is reversible: A XOR K XOR K = A. We apply the same XOR with the same key for decryption:

python
#!/usr/bin/env python3
"""
Snake Bite - XOR decryption
"""
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Read encrypted file
with open('flag.enc', 'rb') as f:
    encrypted = f.read()

# Key from bytecode
key = 'ZHEkjgfhdiIR'

# XOR decryption (identical to encryption)
decrypted = b''
for i in range(len(encrypted)):
    decrypted += bytes([encrypted[i] ^ ord(key[i % len(key)])])

# Determine format by magic bytes
print(f"Magic bytes: {decrypted[:8].hex()}")
print(f"First 20 bytes: {decrypted[:20]}")

# Save result
# PNG magic: 89 50 4E 47 0D 0A 1A 0A
if decrypted[:4] == b'\x89PNG':
    output_file = 'flag.png'
else:
    output_file = 'flag.bin'
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

with open(output_file, 'wb') as f:
    f.write(decrypted)

print(f"Decrypted file saved as: {output_file}")

Result

The decrypted file turned out to be a PNG image (288x34 pixels) containing the flag text.

Notes

Reading Python Bytecode

Key instructions:

  • LOAD_CONST n — load constant at index n
  • LOAD_FAST n — load local variable
  • STORE_FAST n — store to local variable
  • BINARY_XOR — XOR two top stack elements
  • CALL_FUNCTION n — call function with n arguments
  • FOR_ITER — loop iteration ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

XOR Properties

  • A XOR 0 = A (identity element)
  • A XOR A = 0 (self-inverse)
  • A XOR B XOR B = A (reversibility)
  • Commutativity and associativity

Task Name

"Snake Bite" — a reference to Python (snake) and the need to "read bytecode" (bite = diving into low-level details). ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍