The Handout#
✦ . * . ✦
✦ . SHADOW PROTOCOL INITIATED . ✦
* ✦ . ✶ .
[SPACE] A cosmic signal has been scrambled using the Shadow Protocol at time: 1759252620.
[SPACE] Encrypted message:
9C725B044895CC168D324C4059D49B03985E0F1B1F859A1A865E4A011BD69A0ECF6D0F2C1AD4F50ECC730D471A8F9B14A06F0A4474D29E1E867CWe were given the shadow_protocol binary. Which on decompiling and opening up showed a lot of scary stuff. Bit tree calculations and other things that I got scared of.
Analysis#
Eventually if you go through the main function you see the final encryption layer
for (int64_t i = 0; i u< rax_36; i += 1)
printf(format: "%02X",
zx.q((rax_25 u>> ((i.d & 7) << 3).b).b) ^ zx.q(*(i + &buf)))Where rax_25 is a number that comes from the main shadow_protocol function, and buf is the flag character pointer.
Let’s try and simplify this. i.d & 7 is the same as i % 8. << 3 is the same as * 8. So we get
shadow_protocol >> ((i%8)*8)and this value it xors with flag[i] and prints the hex value.
The Exploit#
Now notice how ((i%8)*8) only takes 8 different values and cycles through them. We happen to know the first eight characters of the flag! csawctf{. So using those we can get the “key” and thus the rest of the flag
ℹ️ note
the
zx.qmacro means zero extend to quadword which is 8 bytes long. And.bmeans extract the least significant byte
We can now get the flag pretty simply.
enc = "9C725B044895CC168D324C4059D49B03985E0F1B1F859A1A865E4A011BD69A0ECF6D0F2C1AD4F50ECC730D471A8F9B14A06F0A4474D29E1E867C"
enc = bytes.fromhex(enc)
format = b"csawctf{"
key = [0, 0, 0, 0, 0, 0, 0, 0]
for i in range(len(format)):
key[i] = (format[i] ^ enc[i])
for i in range(len(enc)):
print(chr(key[i%8]^enc[i]), end='')csawctf{r3v3r51ng_5h4d0wy_pr070c0l5_15_c3r741n1y_n07_34sy}
hehehehehehehe
Reply by Email
