Decrypting Cisco Type 7 Passwords

Introduction

This one is for all you coding junkies.  Yes, there was a time where I actually wrote code haha…One Saturday morning about three years ago I ventured out to write a program from scratch in C that could decrypt Cisco type 7 passwords.  I was successful.  I was digging around my system today and found the code so I thought I would post it here for fun.

Note — I am not a programmer by trade.  I knew enough to be dangerous from school when I was doing it on a regular basis.  I am in no way saying this is the best way to do things.  I’m 100% sure there is a better way, but I am proud to say I wrote this from scratch.  Sure, I went the long way not using any predefined functions to convert from ASCII to HEX bytes and such, but it was fun and I learned a lot

Disclaimer – I am not personally responsible for what you do with this code. Use at your own risk

How the decryption process works

This is a very simple process overall. First off, there is a well known key used in this decryption process.  The key was leaked at some point and is readily available on the internet.  The key is 40 bytes long and stored in my program as a hex array.  When a password is encrypted with the algorithm, you will see a hash string in the running-config.

In the decryption process, the hash string is really processed as a string of bytes. The first 2 characters of that password hash are looked at and are used as an index into the key for later computations. Once the index into the key is known, the process picks up at the next character in the hash (after the index) where that byte is XOR’d with the byte stored in the key hex array referenced by the index you just found. The byte after that is XOR’d with the next byte in the key, and so on and so forth. The “index” byte will randomly be picked, and will be a value between 0-15. This assures that two identical passwords could still have unique hashes. It also means the limit of password is 25 characters. If the random index picked happened to be the maximum of 15, that leaves you 25 more bytes in the key array to cycle through before you hit the end.

So to summarize, you have this 40 byte key…you find the index into that key by looking at the first byte of the password.  The second byte of the password is then XOR’d with the byte being stored in the key array position referenced by the index.  Then, it moves to the next byte in the password and XORs it with the next byte in the key array.

How my code works

Since the user input here is stored as a string, and I was working in C and decided not to use any fancy libraries to do all the hard work for me, that was the biggest problem.  Since the hash input is a string, that means it is an array of characters.  Those characters originally are stored in the computer as numbers based on their ASCII codes.  However, to be of any use we don’t need ASCII code values, we need hexadecimal.  For example if the first byte of the password has was “14” I want that as a actual hex number 0x14 but the computer would store it as something like “49” “52” because those are the ASCII values for the number 1 and the number 4 respectively.

The first thing I do is extract the index.  I look at the first byte of the password hash, and I manually convert it from ASCII into a decimal number using a custom written function called “extract_index”.  The function takes the first 2 characters of the password hash, converts it to decimal and returns that value.  Now I have my decimal index into the array.

Next, I skip ahead to the next character and I convert the entire rest of the password hash into an array of hex bytes in the custom written function “string2bytes”.

At this point I have the key, an index into the key so I know where to start my XOR process, and the password hash stored in hex format.  Now, I simply XOR my first byte with the byte stored in the key referenced by the index.  Then I move to the next byte, increment the position in the key and repeat.  Done.

All in all, it was a really fun project!

Source Code

/* This program takes the hash of a Cisco "service password-encryption" type 7 password up to 25 characters and decrypts it - Joe Astorino 3/9/2008 */

#include
#include

int extract_index(char *string) {
/* Function to extract the index into the known key from the hash string */

int tens = 0;
int ones = 0;
int index = 0;

tens = (*string - 48) * 10;
string++;
ones = *string - 48;
index = tens + ones;
return index;
}

char *string2bytes(char *string, char *hexbytes) {
/* Take the hash string after extracting the index and convert it to an array of hex bytes */

char hex;
char ones;
char cur;
int length;
int i;

length = strlen(string);

for (i = 0; i < length/2; i++) {
if (*string <= 57 && *string >= 48)
hex = (*(string) - 48) * 16;

else
hex = (*(string) - 55) * 16;

string++;

if (*string <= 57 && *string >= 48)
ones = *(string) - 48;

else
ones = *(string) - 55;

cur = hex + ones;
string++;
hexbytes[i] = cur;
}
hexbytes[i] = 0;
return hexbytes;
}

int main() {

/* Known Key */
char ciscokey[] = {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, 0x73,
0x67, 0x76, 0x63, 0x61, 0x36, 0x39, 0x38, 0x33, 0x34,
0x6e, 0x63, 0x78, 0x76};

char hash[53];
char hexhash[51];
char password[26];
char *hexhashptr;
char *ptr;
int index;
int len;
int i;
int n;

/* 0 out hexhash */
for (i = 0; i<52; i++){
hexhash[i] = 0;
}

/* input is truncated to 52 characters plus the newline */
printf("Enter Hash: ");
fgets(hash, 53, stdin);

ptr = hash;

/* Extract 1st 2 characters of hash string, and convert them to decimal integer to be used as index into the key */

index = extract_index(ptr);
ptr += 2;
len = (strlen(hash) / 2) - 1 ;
hexhashptr = string2bytes(ptr,hexhash);
for(i = 0; i < len; i++) {
password[i] = ciscokey[index] ^ hexhashptr[i];
index++;
}
password[i] = 0;
printf("password: %s\n",password);
return 0;
}

5 Comments

Leave a Reply