Reply Cyber Security Challenge - Stop sharing

crypto
tags: ctf challenge write-up crypto one-time pad
by GaspareG

R-Boy restores the back-up on a VM in his laptop to see if he can find anything useful. Finally, he discovers a folder containing several encrypted texts. They look encrypted with a familiar algorithm and it seems all the cipher texts have something in common, but he can’t grasp what. Can you help him decrypt all the cipher texts?

The challenge provide a .txt file with 3 strings encoded in base64:

1P3riYWcuvPwhXMjU5Z8U+zKFCpuYyGpZrQJ xPqilMqB6aD7iGA1AItyX6ndUSR9cjA= +9POvZ+WoeDwgk01Tb9zVvQ=

Of course the base64 decoding doesn’t provide a readable text…

After some hours the organizer gives us one hint about the problem:

[CRYPTO400] Cipher texts are encrypted using a classic symmetric cipher

Remembering the problem text “all the cipher texts have something in common”, we think the cipher could be the One-time pad where the “something in common” it’s the key.

Reusing the key in the One-time pad cipher it’s a problem because we can recover it very easily if we know some portion of the text, in this case we know that the beginning of one of the strings is {FLG:.

After a few attempts we find:

This ??????????????????????
Do no??????????????????
{FLG:????????????

Interesting!

We continue to recover the key by completing the sentences, like “Do no” could be “Do not “:

This is????????????????????
Do not ????????????????
{FLG:ch??????????

The final decoded text is:

This is classified?????????
Do not share the s?????
{FLG:ch3ck_em@il}

Yeah! The flag is: {FLG:ch3ck_em@il}

Source code:

#!/bin/python3

import base64

lines = []

with open('cipher_texts.b64') as f:
  lines = f.readlines()

for i in range(3):
  lines[i] = base64.b64decode(lines[i])

key = [-1]*37

# First part "{FLG:"
key[0] = lines[2][0]^ord('{')
key[1] = lines[2][1]^ord('F')
key[2] = lines[2][2]^ord('L')
key[3] = lines[2][3]^ord('G')
key[4] = lines[2][4]^ord(':')

# Second part "t share"
key[5] = lines[1][5]^ord('t')
key[6] = lines[1][6]^ord(' ')
key[7]  = lines[1][7]^ord('s')
key[8]  = lines[1][8]^ord('h')
key[9]  = lines[1][9]^ord('a')
key[10] = lines[1][10]^ord('r')
key[11] = lines[1][11]^ord('e')

# Third part "sified"
key[12] = lines[0][12]^ord('s')
key[13] = lines[0][13]^ord('i')
key[14] = lines[0][14]^ord('f')
key[15] = lines[0][15]^ord('i')
key[16] = lines[0][16]^ord('e')
key[17] = lines[0][17]^ord('d')

for line in lines:
  for x in range(0, len(line)):
    if key[x] == -1:
      print("?", end="")
    else:
      print(chr(line[x] ^ key[x]), end = "")
  print()
print()