#Vigenere - Crypto 100
As the title for this chall claims, this is all about Vigenere cipher. Interestingly the alphabet used is not [A-Z], but also includes '{' and '}'. Besides giving us a full Vigenere table, the chall also provides some information about the key, the plaintext and the ciphertext.
~~~~k: ????????????p: SECCON{???????????????????????????????????}c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ
k=key, p=plain, c=cipher, md5(p)=f528a6ab914c1ecf856a1d93103948fe~~~~
From now on we are going to assume *len(k)==12*. Our main goal is clearly to find *p*. Since we have the first 7 chars of *p* we could easily find the first 7 chars of *c*. We could even use the given table and do it manually. For the first char of *p*, *p[0]=='S'*, we would check the row of the table corresponding to *S*. Since *S* gets mapped to *c[0]=='L'*, we look for *L* in this row, which is in the column of *V*. The figure below ilustrates this process:
![Vigenere](https://github.com/pogTeam/writeups/blob/master/2016/seccon/Vigenere/vigenere.png)
~~~~pt = "SECCON{"ct = "LMIG}RP"
res = ""for p,c in zip(pt, ct):    res += chr( ord('A') + ( (ord(c) - ord(p)) % 28) ) 
print(res)~~~~
This simple procedure results in *VIGESEN* as the first part of the key. Evidently the chars '{' and '}' are not being correctly treated in positions 5 and 7. Either by correcting them manually or by guessing, we might deduce that *VIGENER* is indeed the first part. It is not hard to find that *VIGENERE* are the first 8 chars of the key.
We have the following result so far:
~~~~P: SECCON{A_ _ _ _BCDEDEFG_ _ _ _KLMNOPQR_ _ _ _VWXYYZ}K: VIGENERE_ _ _ _VIGENERE_ _ _ _VIGENERE_ _ _ _VIGENERC: LMIG}RPED O E EWKJIQIWKJ W M NDTSR}TFVU F W YOCBAJBQ~~~~
It seems the alphabet is part of *p*. After *G* there might be *HIJ_* or maybe *_HIJ*. The same goes for *STU_* or *_STU* right after *R*. Before going for a bruteforce solution we decided to test a few possibilities manually. We tried *H* in position 23 and *S* in position 32. Surprisingly, we got *C* as the result for the key in both cases. Certainly a good sign. Trying the other chars we got *VIGENERECOD_* for the key. Not hard to guess the answer should be *VIGENERECODE*, proving our first guess was correct!
With the key in hands all we had to do was decode the ciphertext in order to obtain **SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ}**.
Although we used a lot of guessing to make things quicker, our next approach would be bruteforcing the given md5 hash. In fact, we decided to confirm our guesses with a little coding:
~~~~import itertoolsimport hashlibimport binascii
hashChall = "f528a6ab914c1ecf856a1d93103948fe"res = ""
# the range could include the whole alphabet for more extensive searchfor a in itertools.product("AB",repeat=4):    for b in itertools.product("HIJJ",repeat=4):        for c in itertools.product("STTU",repeat=4):            pt = "SECCON{A"+"".join(a)+"BCDEDEFG"+"".join(b)+"KLMNOPQR"+"".join(c)+"VWXYYZ}"            hashTst = hashlib.md5(pt.encode('utf-8')).hexdigest()            if hashTst == hashChall:                res = ptprint(res)~~~~