[Crypto] CSAW 2017 - Another Xor


Another Xor
Hey, hey can you find my secret.

https://ctf.csaw.io/files/ef303796b276cd0bdf4f7c61b2606df5/cipher.py
https://ctf.csaw.io/files/02a457c28ec0b04e5f7118e54ac8e138/encrypted

Our first attempt to solve this challenge was to use xortool. However, it was a dead end.

By looking at the given code we understand the cipher is just xoring with a repeated key. As a consequence, the second try was to perform a known-plaintext attack on recover a part of the key. We know the first bytes of the plaintext, which are “flag{“.We can xor the first 5 bytes of the ciphertext with “flag{“ to get the first 5 bytes of the key. The result is “A qua”.

The next step is to find the key length. We know that the last 16 bytes are from a hex encoded md5 hash, so our
strategy was to try several key lengths while decrypting with the bytes “A qua” that we know. By looking at the partial decrypted values we can find possible key lengths where the resulting chars are printable and the last ones are in hexadecimal.

The code used to find the key length was the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
with open("encrypted", "r") as f:
c = f.read()

key = "A qua"

for j in range(5, 100):
keyz = key + ("<" * (j - len(key)))
print
cz = ""
print "Trying with keysize of " + str(len(keyz))
for i in range(len(c)):
if keyz[i%len(keyz)] != "<":
cz += chr(ord(c[i]) ^ ord(keyz[i%len(keyz)]))
else:
# we still do not have that portion of the key
cz += "?"

print "plaintext: " + cz[0:len(cz)-32-len(keyz)]
print "key: " + cz[len(cz)-32-len(keyz): len(cz)-32]
print "md5: " + cz[len(cz)-32:]

Key-length 67 was one of the few that the last 16 bytes were hex chars. We noticed this:

1
2
3
4
trying with keysize of 67
plaintext: flag{?????????????????????????????????
key: ????????????????????????????? zinc?????????????????????????????????
md5: ?????????????????????????????df2

Lets try with key-length 67.
As the ciphertext contains the encryption of the key, it is possible to iteratively find more bytes of the key.
This is what implemented to find the flag:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
with open("encrypted", "r") as f:
c = f.read()

keyz = "A qua??????????????????????????????????????????????????????????????"
print "trying with key of length %d" % len(keyz)

while "?" in keyz:
cz = ""
for i in range(len(c)):
if keyz[i%len(keyz)] != "?":
cz += chr(ord(c[i]) ^ ord(keyz[i%len(keyz)]))
else:
cz += "?"

print "Partial key --> " + keyz

ak = cz[len(cz)-32-len(keyz): len(cz)-32]
keyz = "A qua" + ak[5:] # the first 5 bytes we already know

print "plaintext: " + cz[0:len(cz)-32-len(keyz)]
print keyz

With this, we got the flag:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
trying with key of length 67
Partial key --> A qua??????????????????????????????????????????????????????????????
Partial key --> A qua???????????????????????? zinc?????????????????????????????????
Partial key --> A qua???????????????????????? zinc????????????????????????ht pa????
Partial key --> A qua???????????????ixed ???? zinc????????????????????????ht pa????
Partial key --> A qua???????????????ixed ???? zinc???????????????very ????ht pa????
Partial key --> A qua?????? of o????ixed ???? zinc???????????????very ????ht pa????
Partial key --> A qua?????? of o????ixed ???? zinc?????? make????very ????ht pa????
Partial key --> A quart???? of o????ixed ???? zinc?????? make????very ????ht pa????
Partial key --> A quart???? of o????ixed ???? zinc o???? make????very ????ht pa????
Partial key --> A quart???? of o????ixed ???? zinc o???? make????very ????ht pain??
Partial key --> A quart???? of o????ixed wi?? zinc o???? make????very ????ht pain??
Partial key --> A quart???? of o????ixed wi?? zinc o???? make????very br??ht pain??
Partial key --> A quart???? of oil??ixed wi?? zinc o???? make????very br??ht pain??
Partial key --> A quart???? of oil??ixed wi?? zinc o???? makes ??very br??ht pain??
Partial key --> A quart j?? of oil??ixed wi?? zinc o???? makes ??very br??ht pain??
Partial key --> A quart j?? of oil??ixed wi?? zinc oxi?? makes ??very br??ht pain??
Partial key --> A quart j?? of oil??ixed wi?? zinc oxi?? makes ??very br??ht paint|
Partial key --> A quart j?? of oil??ixed with zinc oxi?? makes ??very br??ht paint|
Partial key --> A quart j?? of oil??ixed with zinc oxi?? makes ??very bright paint|
Partial key --> A quart j?? of oil mixed with zinc oxi?? makes ??very bright paint|
Partial key --> A quart j?? of oil mixed with zinc oxi?? makes a very bright paint|
Partial key --> A quart jar of oil mixed with zinc oxi?? makes a very bright paint|
plaintext: flag{sti11_us3_da_x0r_for_my_s3cratz}|
A quart jar of oil mixed with zinc oxide makes a very bright paint|

Very nice challenge.