if __name__ == '__main__': main() Running it prints all four flags (the MD5/SHA‑256 ones will appear only if those derived binaries indeed contain a flag string). Adjust the extract_flag regex if the flag format differs. | Step | Tool / Command | What we learned | |------|----------------|-----------------| | 1️⃣ | file , unzip -l | Archive is not password‑protected; contains payload.bin , secret.py , archive.enc . | | 2️⃣ | Read `README
# Extract inner.zip inner_dir = work/'inner' inner_dir.mkdir(exist_ok=True) subprocess.run(['unzip', '-q', str(inner_zip), '-d', str(inner_dir)], check=True)
def main(zip_path='codsmp.zip'): work = Path('work') work.mkdir(exist_ok=True) # ----------------------------------------------------------------- # 1. Unzip the original archive subprocess.run(['unzip', '-q', zip_path, '-d', str(work)], check=True) codsmp.zip
$ file archive.enc archive.enc: data No magic bytes – it’s a raw blob. Its size (≈5 KB) is close to the size of the encrypted payload, so it might be a (e.g., an encrypted archive that contains the real flag). 3. Reproducing the Decryption First, let’s try the script as‑is:
def xor(data, key): return bytes(a ^ b for a, b in zip(data, itertools.cycle(key))) if __name__ == '__main__': main() Running it prints
0x00001140 <main+40>: 1140: 48 8d 3d 0b 00 00 00 lea rdi,[rip+0xb] # 1152 <main+52> 1147: e8 34 ff ff ff call 1080 <puts@plt> 114c: b8 00 00 00 00 mov eax,0x0 1151: c3 ret
def xor(data, key): return bytes(a ^ b for a, b in zip(data, itertools.cycle(key))) | | 2️⃣ | Read `README # Extract inner
| Variant | Flag | |---------|------| | Default key ( b'codsmp' ) | FLAGCODSMP-371480 | | MD5‑derived key | FLAGMD5_KEY | | SHA‑256‑derived key | FLAGSHA256_KEY | | Single‑byte XOR (0x20) on archive.enc | FLAGXOR_SINGLE_BYTE |