—– Vigenere3d.py
import sys
def _l(idx, s):
return s[idx:] + s[:idx]
def main(p, k1, k2):
s = “ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}”
t = [[_l((i+j) % len(s), s) for j in range(len(s))] for i in range(len(s))]
i1 = 0
i2 = 0
c = “”
for a in p:
c += t[s.find(a)][s.find(k1[i1])][s.find(k2[i2])]
i1 = (i1 + 1) % len(k1)
i2 = (i2 + 1) % len(k2)
return c
print main(sys.argv[1], sys.argv[2], sys.argv[2][::-1])
—–
$ python Vigenere3d.py SECCON{**************************} **************
POR4dnyTLHBfwbxAAZhe}}ocZR3Cxcftw9

We are given a python script which encrypts a given plaintext using the given key. First, it creates a 2d-array of alphabets by cyclic shifting. It shifts the alphabet to the left by i+j. Due to this, t[i][j][k] = t[i][k][j]. While encrypting the string it uses k1 and k2 where k1 is the key and k2 is the reverse of the key. Since we have the first 7 characters of the plaintext, which is “SECCON{“, we find a valid key’s first 7 and last 7 characters by brute forcing. When we count the amount of *s in the description, the key’s length looks like 14. If it is the real case, then we can decrypt the ciphertext with the valid key we found.

Here is my script to find a valid key.

Let’s run it and get our key.

Now, we can modify the encryption code to brute force plaintext characters using the key we just found.

Finally, let’s run it and decrypt the ciphertext.

Here we get SECCON{Welc0me_to_SECCON_CTF_2017}.