TL;DR
0x100byte blob -> lookup table -> SBOX
additive key stream, decoding = inverse tble + modular substraction
1. i skimmed the instructions and found an instereting loop
2. right be4 the loop a counter and starting key was inited
3. identified how key is being transformed
wrapping add_assign from rust -> mod-256 addition
key = (key + byte) & 0xFF
4. and found the lookup table
5. Well now its all about understanding the algo, dumping the data and decoding
Heres the wrapping additon math: keyₙ = 0x75 + Σ flag (mod 256)
Wrap up
well pretty trivial challenge considering it should be a hard one
wrapping add_assign from rust reveals the mod-256 addition
theres also a bound check which limits flag to 21bytes (cmp .., 0x15)
seeing initial key pretty trivial, identifying the loop and algo pretty easy
chall would have been a lil better with some sort of flow obfuscation, which requries actual understanding
Flag:> DawgCTF{S0000_CL43N!}
0x100byte blob -> lookup table -> SBOX
additive key stream, decoding = inverse tble + modular substraction
1. i skimmed the instructions and found an instereting loop
2. right be4 the loop a counter and starting key was inited
3. identified how key is being transformed
wrapping add_assign from rust -> mod-256 addition
key = (key + byte) & 0xFF
4. and found the lookup table
5. Well now its all about understanding the algo, dumping the data and decoding
Python:
mov byte ptr [rsp+…+var_121], 75h ; initial key = 0x75 ('u')
…
loop:
byte = Receiver<u8>::recv() ; get next plaintext byte
if byte == 0 || recv_failed: exit
key = (key + byte) & 0xFF ; 8‑bit wrapping add
enc = lookup_table[key] ; index into 256‑byte table
Sender<u8>::send(enc) ; forward encoded byte
counter++ (max 0x15 = 21 bytes)
Heres the wrapping additon math: keyₙ = 0x75 + Σ flag (mod 256)
Python:
key = 0x75
plain = []
for enc in encoded:
idx = rev[enc] # key after addition
ch = (idx - key) & 0xFF # undo wrapping add
plain.append(ch)
key = idx # next loop
flag = bytes(plain).decode()
Wrap up
well pretty trivial challenge considering it should be a hard one
wrapping add_assign from rust reveals the mod-256 addition
theres also a bound check which limits flag to 21bytes (cmp .., 0x15)
seeing initial key pretty trivial, identifying the loop and algo pretty easy
chall would have been a lil better with some sort of flow obfuscation, which requries actual understanding
Flag:> DawgCTF{S0000_CL43N!}