Matryoshka
Matryoshka
Platform: duckerz | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-01-09 | Status: Solved Techniques: inverse_function_construction, pyc_decompilation, reverse_cipher_chain
Summary
Task: reverse a chain of transformations applied by a Python bytecode program. Solution: decompile the .pyc file with uncompyle6, then apply inverse operations in reverse order (from_binary, atbash, reverse, rot13_inverse, xor, from_hex) to decrypt the encoded data.
Matryoshka - duckerz
Description
Что-то очень на крипту похоже... (Something looks very much like crypto...)
Files provided:
matryoshka.zipcontaining:__pycache__/easy_reverse.cpython-38.pyc- Python 3.8 bytecode__pycache__/encrypt.txt- Encrypted data in binary format
Analysis
Step 1: Extract and Examine Files
The archive contains a Python 3.8 compiled bytecode file and encrypted data:
01010011 01011011 00111101 00111001 01001110 00111101 01001010 00111101 01001110 01110001 01100010 00111111 01110001 01000000 00110111 01010000 01010111 01001110 00100111 01010101 01110110 01101110 00101011 00110011 00101101 01101011 00101100
Step 2: Decompile the .pyc File
Using uncompyle6 to decompile the bytecode:
bash read-only • copy alloweduncompyle6 easy_reverse.cpython-38.pyc
Decompiled source:
python read-only • copy allowedimport string def rot13(text): result = [] for i in text: char = i - 13 if char < 32: char += 95 result.append(chr(char)) return "".join(result) def atbash(text): alphabet = string.ascii_uppercase + string.ascii_lowercase reversed_alphabet = alphabet[::-1] table = str.maketrans( alphabet + string.digits + string.punctuation, reversed_alphabet + string.digits[::-1] + string.punctuation[::-1] ) return text.translate(table) def to_hex(text): result = [] for i in text: result.append(hex(ord(i))) return result def xor(text): result = [] for i in text: result.append(int(i, 16) ^ 8) return result def reverse_text(text): return text[::-1] def to_binary(text): result = [] for i in text: result.append(bin(ord(i))[2:].zfill(8)) return " ".join(result) text = input() print(to_binary(atbash(reverse_text(rot13(xor(to_hex(text)))))))
Step 3: Understand the Encryption Pipeline
The encryption chain is:
input -> to_hex -> xor(8) -> rot13 -> reverse -> atbash -> to_binary -> output
To decrypt, we need to reverse each operation in reverse order:
encrypted -> from_binary -> atbash -> reverse -> rot13_inverse -> xor(8) -> from_hex -> flag
Key observations:
- atbash is self-inverse (applying twice returns original)
- reverse is self-inverse
- xor(8) is self-inverse (XOR is its own inverse)
- rot13 needs an inverse function (add 13 instead of subtract)
- binary/hex are encoding operations that need decoding
Solution
python read-only • copy allowed#!/usr/bin/env python3 import string encrypted = "01010011 01011011 00111101 00111001 01001110 00111101 01001010 00111101 01001110 01110001 01100010 00111111 01110001 01000000 00110111 01010000 01010111 01001110 00100111 01010101 01110110 01101110 00101011 00110011 00101101 01101011 00101100" def from_binary(text): return "".join(chr(int(b, 2)) for b in text.split()) def atbash(text): alphabet = string.ascii_uppercase + string.ascii_lowercase reversed_alphabet = alphabet[::-1] table = str.maketrans( alphabet + string.digits + string.punctuation, reversed_alphabet + string.digits[::-1] + string.punctuation[::-1] ) return text.translate(table) def reverse_text(text): return text[::-1] def rot13_reverse(text): result = [] for c in text: char = ord(c) + 13 if char > 126: char -= 95 result.append(char) return result def xor_reverse(values): return [hex(v ^ 8) for v in values] def from_hex(hex_values): return "".join(chr(int(h, 16)) for h in hex_values) # Decrypt step by step step1 = from_binary(encrypted) # S[=9N=J=Nqb?q@7PWN'Uvn+3-k, step2 = atbash(step1) # h*.0m.q.mJY,J+2kdm^fEM@6>P? step3 = reverse_text(step2) # ?P>6@MEf^mdk2+J,YJm.q.m0.*h step4 = rot13_reverse(step3) # [76, 93, 75, ...] step5 = xor_reverse(step4) # ['0x44', '0x55', '0x43', ...] flag = from_hex(step5) print(flag)
Lessons Learned
- Python bytecode decompilation -
.pycfiles can be decompiled with tools likeuncompyle6,pycdc, ordecompyle3 - Cipher chain reversal - When reversing a chain of transformations, apply inverse operations in reverse order
- Self-inverse functions - Some operations like XOR, atbash, and reverse are their own inverses
- Custom ROT13 - This implementation uses ASCII range 32-126 (95 characters), not standard ROT13
Tools Reference
uncompyle6- Python 2.7-3.8 decompiler:pip install uncompyle6pycdc- Alternative decompiler for newer Python versionsdecompyle3- For Python 3.7+