El Capo 2 Cap 57 -

def rotl8(v, r): return ((v << r) | (v >> (8 - r))) & 0xFF

# Choose 63 arbitrary bytes (e.g., all zeros) key = bytearray(SIZE) checksum = 0

# Write to file with open("key.bin", "wb") as f: f.write(key)

key = bytearray(SIZE) csum = 0 for i in range(SIZE-1): key[i] = inv_rotl8(0, i % 8) ^ CONST_XOR # keep transformed byte = 0 # csum unchanged (adds 0) el capo 2 cap 57

def inv_rotl8(v, r): return ((v >> r) | (v << (8 - r))) & 0xFF

static const char flag[] = "ECTFel_capo_2_cap_57_success"; Because the binary is stripped, the name isn’t visible in strings , but the decompiler reveals it as a global pointer used only in the success branch. The problem reduces to crafting a 64‑byte key.bin such that the checksum after the transformation equals the required constant ( 0xdeadbeef in the example). 4.1 Deriving the Required Plain‑text Let T[i] be the transformed byte for index i . We know:

(The exact constants differ slightly, but the structure is identical.) The flag is embedded as a static string in the binary’s .rodata section: def rotl8(v, r): return ((v &lt;&lt; r) |

CONST_XOR = 0x5A TARGET = 0xdeadbeef SIZE = 64

#!/usr/bin/env python3 from Crypto.Util.number import long_to_bytes import struct

CONST_XOR = 0x5A TARGET = 0xdeadbeef SIZE = 64 We know: (The exact constants differ slightly, but

need = (TARGET - csum) & 0xffffffff need_byte = need & 0xFF i = SIZE-1 key[i] = inv_rotl8(need_byte, i % 8) ^ CONST_XOR

if (chk == 0xdeadbeef) // Success path – print the flag stored in the binary puts(flag); return 0; return -1;

# Compute needed final transformed byte need = (TARGET - checksum) & 0xffffffff # Since only one byte contributes, need must fit in a byte need_byte = need & 0xFF i = SIZE-1 key[i] = inv_rotl8(need_byte, i % 8) ^ CONST_XOR

def rotl8(v, r): return ((v << r) | (v >> (8 - r))) & 0xFF def inv_rotl8(v, r): return ((v >> r) | (v << (8 - r))) & 0xFF

open("key.bin","wb").write(key)

Newsletter

Sign up for our newsletter with news about our German courses, schools and much more: