Змеиный укус (Snake Bite)
Змеиный укус (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 bytecodeflag.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:
FLAGis imported from thesecretmodule- Encryption key:
'ZHEkjgfhdiIR' - Function
encrypt(flag, key)is called - Result is written to
flag.encin 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 withord(b[i % len(b)]) a— source data (flag)b— encryption key
Reconstructed Algorithm
python read-only • copy alloweddef 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 read-only • copy allowed#!/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 nLOAD_FAST n— load local variableSTORE_FAST n— store to local variableBINARY_XOR— XOR two top stack elementsCALL_FUNCTION n— call function with n argumentsFOR_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).