Tags: crypto xor

Rating:

All flags contain the string evlz{ }ctf, we can brute-force an XOR key:


1 import string
2
3 cipher = bytes.fromhex("56141449194b6c200104274d6c1a48411f1b4704")
4
5 def byte_xor(ba1, ba2):
6 return bytes([_a ^ _b for _a, _b in zip(ba1, ba2)])
7
8 for i in string.printable:
9 print(i, byte_xor(cipher, bytes(i, 'utf8')))


Hits on '3' as it returns 'e', the first character we are looking for:


0 b'f'
1 b'g'
2 b'd'
3 b'e'


Trying a string of '3':


print(byte_xor(cipher, bytes('3' * 20, 'utf8')))

b"e''z*x_\x1327\x14~_){r,(t7"


Results in gibberish so we brute-force the rest of the known value:


1 import string
2
3 cipher = bytes.fromhex("56141449194b6c200104274d6c1a48411f1b4704")
4
5 def byte_xor(ba1, ba2):
6 return bytes([_a ^ _b for _a, _b in zip(ba1, ba2)])
7
8 prefix = "evlz{"
9
10 cracked = ""
11 key = ""
12
13 while cracked != prefix:
14 for i in string.printable:
15 tmp = key + i
16 a = byte_xor(cipher, bytes(tmp, 'utf8'))
17 if a == bytes(prefix[:len(tmp)], 'utf8'):
18 cracked = prefix[:len(tmp)]
19 key += i
20 break
21
22 print(cracked)
23 print(key)


Which results in:


evlz{
3bx3b


Using **3bx3b** expanded to the length of the cipher:


25 key = '3bx3b' * 4
26 print(key)
27 print(byte_xor(cipher,bytes(key, 'utf8')))


Results in a valid prefix and suffix - the known text - but the rest gibberish (not that ctf flags always make sense, but this is a little too much):


3bx3b3bx3b3bx3b3bx3b
b'evlz{x\x0eX2f\x14/\x14)*r}ctf'


Closer, but not quite right. If we go with **3bx** expanded out to the length of the cipher:


29 key = '3bx' * 7
30 print(byte_xor(cipher,bytes(key, 'utf8')))


The key is revealed:

**evlz{3_By7E5_x0r}ctf**

For you to copy and paste:


import string

cipher = bytes.fromhex("56141449194b6c200104274d6c1a48411f1b4704")

def byte_xor(ba1, ba2):
return bytes([_a ^ _b for _a, _b in zip(ba1, ba2)])

key = '3bx' * 7
print(byte_xor(cipher,bytes(key, 'utf8')))