Upgrading your Cisco IOS Password Hashes
Most people going through CCNA training will know that by default, Cisco IOS and IOS-XE devices do not hash passwords in the configuration. We have to turn on password encryption on the system but even this is a pretty weak encryption algorithm. Using the secret keyword forces the system to use MD5 hashing but this still isn't the best we could use. So, what it?
Let's go over password basics and explain some things. Hashing and encryption are different from one another. Hashing is an algorithm that is one way. Output from a hashing algorithm cannot be put back into the algorithm to get the original input. An encryption algorithm is two way and requires a key. Output from an encryption algorithm can be fed back into the algorithm with the key to get the original input.
To be clear, for things like passwords, we want them to be stored as a hash not encrypted because if the key is compromised, so is your password. However, hashing has a different problem that we have to cope with. Every time you put the same input into the hashing algorithm you will always get the same output. If we went ahead and precomputed all of hashes for a large number of inputs and stored them in a file, every time we came across a hash and wanted to know it's original value we could just look up that hash in the file and we would know the input. This is called a "rainbow table". So, for example, our file for the MD5 algorithm could look like this:
aaa;5c9597f3c8245907ea71a89d9d39d08e aab;2720737f2d56c6f50528fc3307d5fa91 aac;f0708d327f2a0dd07122fdb81f017b61 aad;...
And now it's really easy to figure out the input if we know the hash.
Secondly, if two users used the same password (say "password123"), we would know that because their hashes match each other that they have the same password which would save the attacker some time. To combat this, password storage can include a "salt". Basically, a salt is a string that gets added onto the password and then ran through the hashing algorithm to create a unique hash. Every password would include a unique salt and that salt would be stored alongside the resulting hash. Then, when the system wanted to check whether a user’s password input matched the stored value, the system would tack on the salt and run it through the algorithm. This prevents the hash from two users from matching.
The last hurdle to overcome with hashing is that the algorithm should be "expensive" or time consuming to run. This is because a hashing algorithm that is very efficient to run means that an attacker can brute force every password combination very quickly. Also, if the output of a hash is relatively short, it's easier to keep a file with all of the possible passwords. Secondly, the smaller the hash, the more likely that two different inputs could result in the same output which means that even if the attacker didn't get the right password, they could still get into the system. This is called a "hash collision".
We can increase the amount of computing power required to run a particular hash by forcing the system to run the algorithm multiple times. MD5 for example isn't very difficult by modern standards but if we were to take the output from the original password and feed it through again, we would double the difficulty of the algorithm.
Alternatively, modern secure hashing algorithms have this difficulty built into the design and also produce hashes that are long enough that the likelihood of a hashing collision is minute.
Let's tie this all back to Cisco IOS. Like I said at the beginning of this article, Cisco has a command called "service password-encryption" and as the command implies, this is an encryption not a hash. Why don't we like this? Well if a malicious person were to get ahold of the encrypted output of the password, they could go to any of the multiple websites out there that can reverse this back to the original in seconds. This type of password is known as "type 7" in the Cisco context sensitive help.
After the terrible type 7 password encryption, Cisco also has "type 5" passwords. This is what's performed when you use the command, "enable secret password123". This uses the MD5 algorithm and is okay. Hey and at least they even implemented salting in type 5. But the problem as stated above is that the MD5 algorithm is a bit old and not very difficult to perform by modern CPU and GPU standards as well as there are a lot of easily accessible rainbow tables for MD5.
Cisco later implemented "type 4" which was a badly implemented version of the PBKDF2 algorithm which is more modern than MD5 but because the bugs makes it less secure than type 5.
Type 8 was introduced to fix the issues with type 4 and was implemented correctly this time. While this is secure, it's not the best we have available to us.
So What’s Best?
Type 9 passwords are where it's at currently. Type 9 uses the scrypt algorithm to do the hashing and is extremely CPU intensive. Scrypt was an algorithm specifically design to be hard to implement in parallel on GPUs and ASICs which means that any attacker is going to run out of years on this earth before they can compute a difficult password.
You implement type 9 password hashing by specifying the algorithm before the password. For example, enable secret passwords become:
enable algorithm-type scrypt secret <password>
And usernames become:
username <user> privilege 15 algorithm-type scrypt secret <password>
The next thing we can do is also force everyone to use long passwords. This is done simply enough with:
security passwords min-length 15
I'd recommend you go with 15 as the minimum length as this causes brute force password attacks to be unreasonably long times. The minimum length should also be set in your RADIUS or TACACS+ server as well but that's a different blog post.
As for other passwords and shared keys in IOS, we can specify AES as the encryption algorithm. Things like PSKs in OSPF and TACACS+ can be encrypted by setting an encryption key and then specifying AES. Implement this with:
key config-key password-encrypt <password> password encryption aes
Your encryption key needs to be at least 8 characters long. Be sure to keep track of your shared secrets if you're implementing AES as you're never going to get these back if you lose them.