The Handout#
✦ . * . ✦
✦ . SHADOW PROTOCOL INITIATED . ✦
* ✦ . ✶ .
[SPACE] A cosmic signal has been scrambled using the Shadow Protocol at time: 1759252620.
[SPACE] Encrypted message:
9C725B044895CC168D324C4059D49B03985E0F1B1F859A1A865E4A011BD69A0ECF6D0F2C1AD4F50ECC730D471A8F9B14A06F0A4474D29E1E867C
We 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.q
macro means zero extend to quadword which is 8 bytes long. And.b
means 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