=

XOR Properties


In the last challenge, you saw how XOR worked at the level of bits. In this one, we're going to cover the properties of the XOR operation and then use them to undo a chain of operations that have encrypted a flag. Gaining an intuition for how this works will help greatly when you come to attacking real cryptosystems later, especially in the block ciphers category.


There are four main properties we should consider when we solve challenges using the XOR operator


Commutative: A ⊕ B = B ⊕ A
Associative: A ⊕ (B ⊕ C)= (A ⊕ B)⊕C
Identity: A ⊕ 0 = A
Self-Inverse: A ⊕ A = 0


challenge : Below is a series of outputs where three random keys have been XOR'd together and with the flag. Use the above properties to undo the encryption in the final line to obtain the flag.


KEY1 : a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313

KEY2 ^ KEY1 : 37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e

KEY2 ^ KEY3 : c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1

FLAG ^ KEY1 ^ KEY3 ^ KEY2 : 04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf

Solution : As we know A ⊕ A = 0 and A ⊕ 0 = A
So we can first xor KEY1 ^ KEY2 ^ KEY3 = A then we will Xor it with final value with flag flag ^ A ^ A ⇒ flag

Code python
k1 = 0xa6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313
k23 = 0xc1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1
fk123 = 0x04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf

k123 = k1 ^ k23

intflag = fk123 ^ k123
hxflag = hex(intflag).lstrip("0x")
flag = bytes.fromhex(hxflag)
print(flag) # Output : b'crypto{x0r_i5_ass0c1at1v3}'

Flag : crypto{x0r_i5_ass0c1at1v3}