Siguiendo con los writeups de la SECCON ahora os traigo una prueba de criptografía.
Nos dan el siguiente enunciado:
Vigenere
k: ???????????? p: SECCON{???????????????????????????????????} c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ k=key, p=plain, c=cipher, md5(p)=f528a6ab914c1ecf856a1d93103948fe |ABCDEFGHIJKLMNOPQRSTUVWXYZ{} -+---------------------------- A|ABCDEFGHIJKLMNOPQRSTUVWXYZ{} B|BCDEFGHIJKLMNOPQRSTUVWXYZ{}A C|CDEFGHIJKLMNOPQRSTUVWXYZ{}AB D|DEFGHIJKLMNOPQRSTUVWXYZ{}ABC E|EFGHIJKLMNOPQRSTUVWXYZ{}ABCD F|FGHIJKLMNOPQRSTUVWXYZ{}ABCDE G|GHIJKLMNOPQRSTUVWXYZ{}ABCDEF H|HIJKLMNOPQRSTUVWXYZ{}ABCDEFG I|IJKLMNOPQRSTUVWXYZ{}ABCDEFGH J|JKLMNOPQRSTUVWXYZ{}ABCDEFGHI K|KLMNOPQRSTUVWXYZ{}ABCDEFGHIJ L|LMNOPQRSTUVWXYZ{}ABCDEFGHIJK M|MNOPQRSTUVWXYZ{}ABCDEFGHIJKL N|NOPQRSTUVWXYZ{}ABCDEFGHIJKLM O|OPQRSTUVWXYZ{}ABCDEFGHIJKLMN P|PQRSTUVWXYZ{}ABCDEFGHIJKLMNO Q|QRSTUVWXYZ{}ABCDEFGHIJKLMNOP R|RSTUVWXYZ{}ABCDEFGHIJKLMNOPQ S|STUVWXYZ{}ABCDEFGHIJKLMNOPQR T|TUVWXYZ{}ABCDEFGHIJKLMNOPQRS U|UVWXYZ{}ABCDEFGHIJKLMNOPQRST V|VWXYZ{}ABCDEFGHIJKLMNOPQRSTU W|WXYZ{}ABCDEFGHIJKLMNOPQRSTUV X|XYZ{}ABCDEFGHIJKLMNOPQRSTUVW Y|YZ{}ABCDEFGHIJKLMNOPQRSTUVWX Z|Z{}ABCDEFGHIJKLMNOPQRSTUVWXY {|{}ABCDEFGHIJKLMNOPQRSTUVWXYZ }|}ABCDEFGHIJKLMNOPQRSTUVWXYZ{
Vigenere cipher
https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
Otra vez nos dan una pista enorme con el título de la prueba e incluso un link a la wikipedia. La verdad es que muy difícil no lo estaban poniendo.
Si no llegase con lo anteriormente mencionado además nos dan el charset y el md5 de la respuesta con lo cual el gran maestro Patatas construyo los siguientes scripts para resolver la prueba, primero se realiza un ataque de texto conocido utilizando el texto que conocemos de la flag:
<?php function vigenere_decrypt_customcharset($txt, $clave, $charset) { $lentxt = strlen($charset); $lenkey = strlen($clave); $txt2 = ''; for($i=0; $i<strlen($txt); $i++) { $c = strpos($charset, $txt[$i]); // caracter texto $x = strpos($charset, $clave[$i%$lenkey]); // caracter clave if($x!==FALSE and $c!==FALSE) { $txt2 .= $charset[($c - $x + $lentxt) % $lentxt]; // aplicar vigenere } else { $txt2 .= '?'; // aplicar vigenere //echo "X"; } } return $txt2; } $charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ{}'; $p = 'SECCON{???????????????????????????????????}'; $c = 'LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ'; // PRIMERA PARTE $key1 = vigenere_decrypt_customcharset($c, $p, $charset); echo "KEY1: $key1\n\n"; ?>
Lo cual nos da el siguiente resultado:
php vigenere_part1.php SECCON{???????????????????????????????????} KEY1: VIGENER???????????????????????????????????R
Como solo conocemos los 7 primeros caracteres podemos ver que la primera parte de la clave es «VIGENERE». Con esto, sabiendo la longitud de la clave y el md5 podemos realizar un ataque de fuerza bruta contra el resto de la clave:
<?php /* --------------------------------------------------- VIGENERE --------------------------------------------------- */ function vigenere_decrypt_customcharset($txt, $clave, $charset) { $lentxt = strlen($charset); $lenkey = strlen($clave); $txt2 = ''; for($i=0; $i<strlen($txt); $i++) { $c = strpos($charset, $txt[$i]); // caracter texto $x = strpos($charset, $clave[$i%$lenkey]); // caracter clave if($x!==FALSE and $c!==FALSE) { $txt2 .= $charset[($c - $x + $lentxt) % $lentxt]; // aplicar vigenere } else { $txt2 .= '?'; // aplicar vigenere //echo "X"; } } return $txt2; } $charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ{}'; $p = 'SECCON{???????????????????????????????????}'; $c = 'LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ'; $keyx = 'VIGENERE'; for($i=0; $i<strlen($charset); $i++) { for($j=0; $j<strlen($charset); $j++) { for($k=0; $k<strlen($charset); $k++) { for($l=0; $l<strlen($charset); $l++) { $key = $keyx . $charset[$i]. $charset[$j] . $charset[$k] . $charset[$l]; $p2 = vigenere_decrypt_customcharset($c, $key, $charset); echo "PLAIN: $p2\n\n"; $md5 = md5($p2); if($md5=='f528a6ab914c1ecf856a1d93103948fe') { echo "FOUND!! $key $p2\n"; exit; } }}}} ?>
Ejecutamos el script y en menos de 2 segundos tenemos la flag:
php vigenere_part2.php CLAVE: VIGENEREAAAA PLAIN: SECCON{ADOEEBCDEDEFGJWMNKLMNOPQRUFWYVWXYYZ} CLAVE: VIGENEREAAAB PLAIN: SECCON{ADOEDBCDEDEFGJWMMKLMNOPQRUFWXVWXYYZ} CLAVE: VIGENEREAAAC PLAIN: SECCON{ADOECBCDEDEFGJWMLKLMNOPQRUFWWVWXYYZ} CLAVE: VIGENEREAAAD PLAIN: SECCON{ADOEBBCDEDEFGJWMKKLMNOPQRUFWVVWXYYZ} ..... CLAVE: VIGENERECODC PLAIN: SECCON{ABABCBCDEDEFGHIJLKLMNOPQRSTTWVWXYYZ} CLAVE: VIGENERECODD PLAIN: SECCON{ABABBBCDEDEFGHIJKKLMNOPQRSTTVVWXYYZ} CLAVE: VIGENERECODE PLAIN: SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ} FOUND!! VIGENERECODE SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ}
Y ahí tenemos la pass «VIGENERECODE» y la flag:
SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ}
Otra vez las pistas nos han facilitado la parte de investigación y nos hemos podido limitar a resolver el reto.
Espero os haya gustado, un saludo!