Tags: engineering reverse
Rating: 5.0
We're given a binary `"superencryption"` which has a encryption routine, but no decryption routine.
Encryption is fairly simple, consisting of three steps: mangle all characters, swap (reverse) in chunks of five, then in chunks of three.
Each swap leaves the remaining characters, e.g.: `swap3("ABCD") -> "CBAD`.
Mangling adds a small "derivative" of char num.
The solution is to undo the mangling (subtract the "derivative"), and the swap operations, in reverse order, resulting in the flag `"tpctf{Y4Y_f0r_r3v3rse_3ngin33ring}"`.
# solve.py
``` python
def mangle(buf):
l = len(buf)
out = l*[0]
i = 0
while i < l:
if buf[i] == 0xa:
break
out[i] = int(
buf[i] + (
(((i+22) / 2) ^ 0x1b) % 11
)
)
i += 1
return out
def demangle(buf):
l = len(buf)
out = l*[0]
i = 0
while i < l:
if buf[i] == 0xa:
break
out[i] = int(
buf[i] - (
(((i+22) / 2) ^ 0x1b) % 11
)
)
i += 1
return out
def swap_5(buf):
l = len(buf)
out = l*[0]
i = 0
while i+4 < l:
out[i+0] = buf[i+4]
out[i+1] = buf[i+3]
out[i+2] = buf[i+2]
out[i+3] = buf[i+1]
out[i+4] = buf[i+0]
i += 5
while i < l:
out[i] = buf[i]
i += 1
return out
def swap_3(buf):
l = len(buf)
out = l*[0]
i = 0
while i+3 < l: # typo? should be i+2<l
out[i+0] = buf[i+2]
out[i+1] = buf[i+1]
out[i+2] = buf[i+0]
i += 3
while i < l:
out[i] = buf[i]
i += 1
return out
def encrypt(buf):
buf = list(map(ord, buf))
return "".join(map(chr,
swap_3(swap_5(mangle(buf)))
))
def decrypt(buf):
buf = list(map(ord, buf))
return "".join(map(chr,
demangle(swap_5(swap_3(buf)))
))
if __name__ == "__main__":
test = list(map(ord, "ABCDEFG"))
assert swap_3(swap_3(test)) == test, "swap3 doesn't work"
assert swap_5(swap_5(test)) == test, "swap5 doesn't work"
assert demangle(mangle(test)) == test, "(de)mangle doesn't work"
print(decrypt("dufhyuc>bi{{f0|;vwh<~b5p5thjq6goj}"))
```
Fun fact: they made a mistake in their swap 3 step (doesn't impact the flag). See if you can spot it ;)
how did you get this code from the file that they gave you