# Romper el cifrado de Vigenère

Para romper el cifrado de Vigenère o las contraseñas tipo 7 de Cisco, podemos utilizar varios métodos:

- Utilizar herramientas en línea:

http://www.kazmier.com/computer/cisco-apps.html
http://www.ifm.net.nz/cookbooks/passwordcracker.html

- Utilizar la herramienta 'Cain and Abel'.

Descargar la herramienta, instalarla y ejecutarla. Una vez en ejecución, presionar Alt+7 y aparecerá la ventana 'Cisco Type-7 Password Decoder'.

- Utilizar un código en C o en perl.

- Utilizar el propio IOS del router:
router(config)#enable password crackmeifyoucan
router(config)#service password-encryption
router#show run
...
enable password 7 0307490A05042C49470F000A02110A02
...
router(config)#key chain tipo7
router(config-keychain)#key 0
router(config-keychain-key)#key-string 7 0307490A05042C49470F000A02110A02
router#show key chain tipo7
Key-chain tipo7:
key 0 -- text "crackmeifyoucan"
accept lifetime (always valid) - (always valid) [valid now]
send lifetime (always valid) - (always valid) [valid now]
Los dos primeros carácteres (03) del ciphertext (0307490A05042C49470F000A02110A02) corresponden a la semilla (seed). La semilla nos da el punto de entrada en un array de bytes para obtener la clave circular que permite cifrar/descifrar con Vigenère. Veamos paso a paso cómo desciframos el siguiente ciphertext:
# ./vigenere 0307490A05042C49470F000A02110A02 -v
seed=('enc_pw[0]'-'0')*10+'enc_pw[1]'-'0'='0'-'0')*10+'3'-'0'+1=(48-48)*10+51-48+1
seed=3

key table[]:  d  s  f  d  ;  k  f  o  A  ,  .  i  y  e  w  r  k  l  d  J  K  D
              0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21

key: d;kfoA,.iyewrkldJKDdsf

***I=2 '0'
***I=3 '7'
  '07' ^ key_table[3] = 0x7 ^ 0x64 = 001100011b = c
  password=c
***I=4 '4'
***I=5 '9'
  '49' ^ key_table[4] = 0x49 ^ 0x3b = 001110010b = r
  password=cr
***I=6 '0'
***I=7 'A'
  '0A' ^ key_table[5] = 0xa ^ 0x6b = 001100001b = a
  password=cra
***I=8 '0'
***I=9 '5'
  '05' ^ key_table[6] = 0x5 ^ 0x66 = 001100011b = c
  password=crac
***I=10 '0'
***I=11 '4'
  '04' ^ key_table[7] = 0x4 ^ 0x6f = 001101011b = k
  password=crack
***I=12 '2'
***I=13 'C'
  '2C' ^ key_table[8] = 0x2c ^ 0x41 = 001101101b = m
  password=crackm
***I=14 '4'
***I=15 '9'
  '49' ^ key_table[9] = 0x49 ^ 0x2c = 001100101b = e
  password=crackme
***I=16 '4'
***I=17 '7'
  '47' ^ key_table[10] = 0x47 ^ 0x2e = 001101001b = i
  password=crackmei
***I=18 '0'
***I=19 'F'
  '0F' ^ key_table[11] = 0xf ^ 0x69 = 001100110b = f
  password=crackmeif
***I=20 '0'
***I=21 '0'
  '00' ^ key_table[12] = 0x0 ^ 0x79 = 001111001b = y
  password=crackmeify
***I=22 '0'
***I=23 'A'
  '0A' ^ key_table[13] = 0xa ^ 0x65 = 001101111b = o
  password=crackmeifyo
***I=24 '0'
***I=25 '2'
  '02' ^ key_table[14] = 0x2 ^ 0x77 = 001110101b = u
  password=crackmeifyou
***I=26 '1'
***I=27 '1'
  '11' ^ key_table[15] = 0x11 ^ 0x72 = 001100011b = c
  password=crackmeifyouc
***I=28 '0'
***I=29 'A'
  '0A' ^ key_table[16] = 0xa ^ 0x6b = 001100001b = a
  password=crackmeifyouca
***I=30 '0'
***I=31 '2'
  '02' ^ key_table[17] = 0x2 ^ 0x6c = 001101110b = n
  password=crackmeifyoucan
Password: crackmeifyoucan
Código fuente de vigenere:
# cat vigenere.c 
#include <stdio.h>
#include <string.h>

char xlat[]={
 0x64,0x73,0x66,0x64,0x3b,0x6b,0x66,0x6f,
 0x41,0x2c,0x2e,0x69,0x79,0x65,0x77,0x72,
 0x6b,0x6c,0x64,0x4a,0x4b,0x44
};

int verbose=0;

const char* byte_to_binary(int x){
 static char b[9];
 int z;
 b[0]='\0';
 for(z=256;z>0;z>>=1){
  strcat(b,((x & z) == z) ? "1" : "0");
 }
 return b;
}

int cdecrypt(char *enc_pw,char *dec_pw){
 unsigned int seed,i,val=0;
 if(strlen(enc_pw)&1) return(-1);
 seed=(enc_pw[0]-'0')*10+enc_pw[1]-'0';
 if(verbose){
  printf("seed=('enc_pw[0]'-'0')*10+'enc_pw[1]'-'0'=");
  printf("'%c'-'0')*10+'%c'-'0'+1",enc_pw[0],enc_pw[1]);
  printf("=(%d-%d)*10+%d-%d+1\n",enc_pw[0],'0',enc_pw[1],'0');
  printf("seed=%d\n\n",seed); 
  printf("key table[]:");
  for(i=0;i<22;i++){printf("  %c",xlat[i]);}printf("\n"); 
  printf("            ");
  for(i=0;i<22;i++){printf("%3d",i);}printf("\n\n"); 
  printf("key: ");
  for(i=seed;i<22;i++){printf("%c",xlat[i]);} 
  for(i=0;i<seed;i++){printf("%c",xlat[i]);}printf("\n\n"); 
 }
 if(seed>15 || !isdigit(enc_pw[0]) || !isdigit(enc_pw[1])) return(-1);
 for(i=2;i<=strlen(enc_pw);i++){
  if(i!=2 && !(i&1)){
   dec_pw[i/2 - 2]=val^xlat[seed];
   if(verbose){
    printf("\t\t'%c%c' ^ key_table[%d] = 0x%x ^ 0x%x = %sb = ",
     enc_pw[i-2],enc_pw[i-1],seed,val,xlat[seed],byte_to_binary(dec_pw[i/2 - 2]));
    printf("%c\n",dec_pw[i/2 - 2]);
    printf("\t\tpassword=%s\n",dec_pw);
   }
   val=0;
   seed++;
  }
  if(verbose){if(i<strlen(enc_pw)){printf("***I=%d '%c'\n",i,enc_pw[i]);}}
  val*=16;
  if(isdigit(enc_pw[i]=toupper(enc_pw[i]))){
   val+=enc_pw[i]-'0';
   continue;
  }
  if(enc_pw[i]>='A' && enc_pw[i]<='F'){
   val+=enc_pw[i]-'A'+10;
   continue;
  }
  if(strlen(enc_pw)!=i) return(-1);
 }
 dec_pw[++i/2]=0;
 return(0);
}

int main(int argc,char **argv){
 char passwd[65];
 memset(passwd,0 , sizeof(passwd));
 if((argv[2]!=0)&&!strcmp(argv[2],"-v")){verbose=1;}
 cdecrypt(argv[1],passwd);
 printf("Password: %s\n",passwd);
 return 0;
}

No comments: