Previous section   Next section

Recipe 3.5 Deciphering Cisco's Weak Password Encryption

3.5.1 Problem

You want to reverse the weak Cisco password encryption algorithm to recover forgotten passwords.

3.5.2 Solution

To recover a lost router password from a configuration file, use the following Perl script to decipher weakly encrypted passwords. This script expects to read router configuration commands via STDIN. It then prints the same commands to standard STDOUT with the passwords decrypted.

Here is an example of the program's output:

Freebsd% cpwcrk.pl < Router1-confg
   
version 12.2
   
service password-encryption
!
hostname Router1
!
enable secret 5 $1$4y6Q$bcGReJ3kGgmlpfr7/lT64.
enable password 7 06150E2F4A5C0817 (decrypted: sanfran)
!
username ijbrown password 7 121A0C041104 (decrypted: cisco)
username kdooley password 7 1306181D000E0B2520 (decrypted: cookbook)
!
<Lines removed for brevity>
!
line con 0
 password 7 06120A22445E1E1D (decrypted: techpwd)
line aux 0
 password 7 0212015803161825 (decrypted: techpwd)
line vty 0 4
 password 7 070033494705151C (decrypted: oreilly)
 login
!
end

Example 3-2 contains the Perl script.

Example 3-2. cpwcrk.pl
#!/usr/local/bin/perl
#
#  cpwcrk.pl  -- a small script to crack Cisco's Type 7 password
#                encryption
#
#
$k='dsfd;kfoA,.iyewrkldJKDHSUB';
for($i=0; $i<length($k); $i++) { $ks[$i] = ord(substr($k, $i, 1)); }
   
while (<STDIN>) {
   if(/ord 7 [01]/) {
      chop; $w=$_; s/.* //g; $C = $_;
      printf "$w (decrypted: ";
   
      $o=substr($C, 0, 2);
      for ($i=0; $i < (length($C)-1)/2; $i++) { $cs[$i]=hex(substr($C,2*$i,2)); }
   
      for ($j=1; $j < $i; $j++) { printf("%c", $ks[$o+$j-1] ^ $cs[$j]); }
      printf ")\n";
   } else {
     printf $_;
   }
}

Note that this script will not decrypt enable secret passwords, because they are encrypted using strong MD5 encryption.

3.5.3 Discussion

This little Perl script is deliberately written to be small and fast, which, unfortunately, makes it somewhat difficult to read. Here's a brief explanation of how it works.

The first thing it does is to take the standard key string, "$k", and translate it into an array of hexadecimal numbers, "$ks", to make it easier to work with. Then it reads the input configuration file one line at a time, looking for any lines including "password 7". To make the search slightly quicker, the script looks only for the string "ord 7", followed by a space and either the number 0 or 1. It stores the encrypted password string in the variable "$C".

The first two characters in the encrypted string are used for an offset, so the script stores them in the string "$o". It then goes through the crypt string, two characters at a time, and converts the result into hexadecimal numbers, which it stores in the array "$cs".

The script then does all of the actual decryption work in a loop that simply calculates an XOR (exclusive OR) operation between the offset original key and the elements of the "$cs" array.

The encryption algorithm is nothing more than a bitwise XOR between the password string and a known key offset by a random amount. This random offset is encoded into the first two characters of the result, so it is easy to uniquely reverse the cipher.

Cisco chose to use such a simple algorithm because the router must be able to uniquely decrypt passwords for some applications, such as CHAP authentication. This is different from most password applications in which the device can take an incoming password string, encrypt it with a one-way algorithm, and compare the resulting encrypted version with the encrypted version of the locally stored password. In those applications, it is sufficient to work only with the encrypted versions of the passwords.

3.5.4 See Also

Recipe 3.2; Recipe 3.3; Recipe 3.4


  Previous section   Next section
Top