Cisco original encryption algorithm in reverse

From Internetworkpro

Jump to: navigation, search
This page or section provides device configuration instructions
Please note that the information on this page has not been checked for accuracy and is not intended as a replacement to documentation. Please ensure you understand your desired objectives before attempting to apply any examples listed.
See more examples at Category:Configuration

This is a Perl script by Riku (http://insecure.org/sploits/cisco.passwords.html) to unencrypt Cisco passwords, encrypted under the deprecated weak encryption. I commented the script, so it should be easy to tell what's going on.

Below is a php script (thanks for all the help Steve) that takes a password and encrypts it with the encryption alogrithm. However a key is used, as to where to start in the translate table. This key is the first two bytes of the encrypted password. I am not sure how this key is generated, but there are only 26 values in the translate table.

The script was tested and it does generate the proper encryption, but there's still a bunch of debugging code in the script.

I posted this because I thought it was interesting, and I've been messing around with Perl. It looks like the encryption was "easily" reveresed. You can see it is a larger encrypted password, two hex digits, per one character of input, and prefixed with a two byte key. So you could create encrypted passwords, and xor the encrypted password (minus the key) with the password and generate the translate table values. So with some intuitive guessing it looks like it was right there.


#!/usr/bin/perl
#grabbing the lines in the router configuration file with the encrypted passwords, and operating on the encrypted pass by running the original algorithm in a reverse manner
 
#hardcoded hex values with which we will XOR our password with to create the encrypted password
@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 (<>) {
        if (/(password|md5)\s+7\s+([\da-f]+)/io) { #test for the lines with the encrypted pass "password 7 HEXSTRING"
            if (!(length($2) & 1)) { #testing that "HEXSTRING" is even, doing bit anding and want 1 returned for test
                $ep = $2; $dp = ""; #dp is going to be our password, ep is our encrypted pass 
                ($s, $e) = ($2 =~ /^(..)(.+)/o); #place the first two chars of the encrypted pass in s, and the rest in e
 
#s is our key, it's where we start in the translate table.  who knows where it's originally derived from, the password or random.  either way there are only 26 possible values
 
#up to the length of the encrypted pass (not the first two chars of it, that's the key), loop through  in increments of 2
                for ($i = 0; $i < length($e); $i+=2) {
 
                    $dp .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++]; #take two chars of the encrypted pass at a time (starting two chars into the encrypted pass, $e) ,convert them to hex, and XOR them against the a hex value in the xlat array, specifically the index of the xlate array based on the first two chars of the encrypted pass.  assign the ascci character representation, of the resulting XOR binary data to dp, keep adding to dp through the loop till the full pass is generated
                }
#woooah, got the real pass!, take the line with the encrypted pass and replace it with the real deal
                s/7\s+$ep/$dp/;
            }
        }
#print it out
        print;
}
# eof

You can try and understand this if you want, but I commented the above program, this has a lot of debugging code.

<?
echo "<div style=\"font-family:monospace\">";
// encrypted: fdgsdfgsdfgdsgf1
// real: adsfasfd
 
$xlat = array( 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 );
 
echo "<p>".nl2br(print_r($xlat,1))."</p>";
$encrypted = '082Fasdfasfdas';
$realpass = 'asdfasdf';
 
$key = substr($encrypted,0,2);
$startkey = base_convert($key,16,10);
echo "<p>$key:$startkey</p>";
 
$pass = str_split(substr($encrypted,2),2);
echo "<p>".print_r($pass,1)."</p>";
$newpass = '';
foreach ($pass as $key=>$val) {
     $newpass .= chr(base_convert($val,16,10)^$xlat[$key+$startkey]);
     echo "<p>character $key: $val (",base_convert($val,16,10),"), xlat: ",$xlat[$key+$startkey],", converted: $newpass</p>";
}
 
echo "<p>----------REVERSE</p>";
 
//$startkey = 8;
$startkey = rand(0,25);
 
$startpass = str_split($realpass);
echo "<p>",print_r($startpass,1),"</p>";
$encpass = str_pad(base_convert($startkey,10,16),2,"0",STR_PAD_LEFT);
echo "<p>$encpass</p>";
 
foreach ($startpass as $key=>$val) {
     $actualkey = $startkey + $key;
     if ($actualkey > 25) { $actualkey -= 26; }
     $thischar = str_pad(base_convert(ord($val)^$xlat[$actualkey],10,16),2,"0",STR_PAD_LEFT);
     $encpass.=$thischar;
     echo "step $key: $encpass<br />";
}
 
?>
Personal tools