Rating:
We are given this python code:
```
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 64 bytes
FLAG = b'LINECTF{...}'
def xor(a:bytes, b:bytes) -> bytes:
return bytes(i^j for i, j in zip(a, b))
S = [None]*4
R = [None]*4
Share = [None]*5
S[0] = FLAG[0:8]
S[1] = FLAG[8:16]
S[2] = FLAG[16:24]
S[3] = FLAG[24:32]
# Ideally, R should be random stream. (Not hint)
R[0] = FLAG[32:40]
R[1] = FLAG[40:48]
R[2] = FLAG[48:56]
R[3] = FLAG[56:64]
Share[0] = R[0] + xor(R[1], S[3]) + xor(R[2], S[2]) + xor(R[3],S[1])
Share[1] = xor(R[0], S[0]) + R[1] + xor(R[2], S[3]) + xor(R[3],S[2])
Share[2] = xor(R[0], S[1]) + xor(R[1], S[0]) + R[2] + xor(R[3],S[3])
Share[3] = xor(R[0], S[2]) + xor(R[1], S[1]) + xor(R[2], S[0]) + R[3]
Share[4] = xor(R[0], S[3]) + xor(R[1], S[2]) + xor(R[2], S[1]) + xor(R[3],S[0])
# This share is partially broken.
Share[1] = Share[1][0:8] + b'\x00'*8 + Share[1][16:24] + Share[1][24:32]
with open('./Share1', 'wb') as f:
f.write(Share[1])
f.close()
with open('./Share4', 'wb') as f:
f.write(Share[4])
f.close()
```
We are also given 2 files.
**Share1** (hex):
`25 24 3E 2A 31 20 27 15 00 00 00 00 00 00 00 00 2B 07 19 07 3A 0D 2C 2F 02 14 25 1C 09 40 48 13`
**Share4** (hex):
`1D 08 08 1B 2D 1D 12 31 03 31 36 1E 33 19 06 1C 06 07 00 1B 3A 0F 31 1F 39 33 34 29 26 75 67 06`
Values S[0]-S[3],R[0]-R[3] are taken from the flag string, we only know what the flag starts with:
`LINECTF{`
Also, **Share1** is damaged.
Let's look at how Shares are built:
```
Share[0] = R[0] + xor(R[1], S[3]) + xor(R[2], S[2]) + xor(R[3],S[1])
Share[1] = xor(R[0], S[0]) + R[1] + xor(R[2], S[3]) + xor(R[3],S[2])
Share[2] = xor(R[0], S[1]) + xor(R[1], S[0]) + R[2] + xor(R[3],S[3])
Share[3] = xor(R[0], S[2]) + xor(R[1], S[1]) + xor(R[2], S[0]) + R[3]
Share[4] = xor(R[0], S[3]) + xor(R[1], S[2]) + xor(R[2], S[1]) + xor(R[3],S[0])
```
In the final form (from the files) we have some values. Let's put them into their corresponding places:
```
# Share[0] \x__\x__\x__\x__\x__\x__\x__\x__ \x__\x__\x__\x__\x__\x__\x__\x__ \x__\x__\x__\x__\x__\x__\x__\x__ \x__\x__\x__\x__\x__\x__\x__\x__
# Share[1] \x25\x24\x3e\x2a\x31\x20\x27\x15 \x__\x__\x__\x__\x__\x__\x__\x__ \x2b\x07\x19\x07\x3a\x0d\x2c\x2f \x02\x14\x25\x1c\x09\x40\x48\x13
# Share[2] \x__\x__\x__\x__\x__\x__\x__\x__ \x__\x__\x__\x__\x__\x__\x__\x__ \x__\x__\x__\x__\x__\x__\x__\x__ \x__\x__\x__\x__\x__\x__\x__\x__
# Share[3] \x__\x__\x__\x__\x__\x__\x__\x__ \x__\x__\x__\x__\x__\x__\x__\x__ \x__\x__\x__\x__\x__\x__\x__\x__ \x75\x7a\x7a\x6c\x65\x21\x21\x7d
# Share[4] \x1d\x08\x08\x1b\x2d\x1d\x12\x31 \x03\x31\x36\x1e\x33\x19\x06\x1c \x06\x07\x00\x1b\x3a\x0f\x31\x1f \x39\x33\x34\x29\x26\x75\x67\x06
```
The beginning of the flag fits into the S[0]:
`S[0] = FLAG[0:8] # LINECTF{ - \x4c\x49\x4e\x45\x43\x54\x46\x7b`
We got `S[0]` and we got `Share[1][0:8]` => we got one of the values in the `xor(R[0], S[0])` and it's result. If we xor one of the values with the result of the xor - we'll get the second value: `xor(Share[1][0:8], S[0])` = `R[0]`
=> We just got `R[0]`! (importan - \x69\x6d\x70\x6f\x72\x74\x61\x6e)
=> Now that we have `R[0]`, we can use it with shares the same way to get `S[3]` from `xor(R[0], S[3])`!
After this, we can get `R[2]` => `S[1]` => `R[3]` => `S[2]` => `R[1]`
Just use the same `xor` technique :)
By putting these fragments in the right sequence (`S[0]S[1]S[2]S[3]R[0]R[1]R[2]R[3]`) we get the flag!