summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2012-03-10 16:43:05 -0500
committerEli Collins <elic@assurancetechnologies.com>2012-03-10 16:43:05 -0500
commit929d2168c5119c4b9b401e0ece4a39bf8b944b08 (patch)
treebbe311ed8fa8cccd397166838fe6ccf488c7e326 /docs
parent557d17ba4e0123bce7e1659002270aa8dedb2f24 (diff)
downloadpasslib-929d2168c5119c4b9b401e0ece4a39bf8b944b08.tar.gz
added support for Cisco PIX & Type 7 hashes
* Cisco Type 5 appears to be same as md5_crypt * added requires_user=False support to HandlerCase * added more through salt-generation test (since cisco_pix has only 4 bits of salt) * added HandlerCase test to ensure user is used as salt
Diffstat (limited to 'docs')
-rw-r--r--docs/lib/passlib.hash.cisco_pix.rst146
-rw-r--r--docs/lib/passlib.hash.cisco_type7.rst134
-rw-r--r--docs/lib/passlib.hash.md5_crypt.rst33
-rw-r--r--docs/lib/passlib.hash.rst8
4 files changed, 315 insertions, 6 deletions
diff --git a/docs/lib/passlib.hash.cisco_pix.rst b/docs/lib/passlib.hash.cisco_pix.rst
new file mode 100644
index 0000000..52ee277
--- /dev/null
+++ b/docs/lib/passlib.hash.cisco_pix.rst
@@ -0,0 +1,146 @@
+.. index:: cisco; pix hash
+
+==================================================================
+:class:`passlib.hash.cisco_pix` - Cisco PIX hash
+==================================================================
+
+.. currentmodule:: passlib.hash
+
+This class implements the password hash algorithm commonly found on Cisco
+PIX firewalls.
+
+.. warning::
+
+ This hash is not secure, and should not be used for any purposes
+ besides manipulating existing Cisco PIX password hashes.
+
+.. seealso::
+
+ * :doc:`passlib.hash.md5_crypt` (referred to as a "type 5" hash by Cisco)
+ * :doc:`passlib.hash.cisco_type7`
+
+Usage
+=====
+.. note::
+
+ This hash algorithm has a context-sensitive percularity.
+ It takes in an optional username, used to salt the hash,
+ but with specific restrictions...
+
+ * The username *must* be provided in order to correctly hash passwords
+ associated with a user account on the Cisco device.
+
+ * Conversely, the username *must not* be provided (or must be set to ``""``)
+ in order to correctly hash passwords which don't have an associated user
+ account (such as the "enable" password).
+
+This class can be used directly as follows::
+
+ >>> from passlib.hash import cisco_pix as pix
+
+ >>> # encrypt password using specified username
+ >>> h = pix.encrypt("password", "user")
+ >>> h
+ 'A5XOy94YKDPXCo7U'
+
+ >>> pix.identify(h) #check if hash is recognized
+ True
+ >>> pix.identify('$1$3azHgidD$SrJPt7B.9rekpmwJwtON31') #check if some other hash is recognized
+ False
+
+ >>> pix.verify("password", h, "user") #verify correct password
+ True
+ >>> pm.verify("password", h, "other") #verify correct password w/ wrong username
+ False
+ >>> pm.verify("letmein", h, "user") #verify incorrect password
+ False
+
+ >>> # encrypt password without associate user account
+ >>> h2 = pix.encrypt("password")
+ >>> h2
+ 'NuLKvvWGg.x9HEKO'
+
+ >>> # verify password without associated user account
+ >>> pix.verify("password", h2)
+ True
+
+Interface
+=========
+.. autoclass:: cisco_pix()
+
+.. rst-class:: html-toggle
+
+Format & Algorithm
+==================
+Cisco PIX hashes consist of a 12 byte digest, encoded as a 16 character
+:data:`HASH64 <passlib.utils.h64>`-encoded string. An example
+hash (of ``"password"``) is ``"NuLKvvWGg.x9HEKO"``.
+
+The digest is calculated as follows:
+
+1. The password is encoded using an ``ASCII``-compatible encoding
+ (all known references are strict 7-bit ascii, and Passlib uses ``UTF-8``
+ to provide unicode support).
+2. If the hash is associated with a user account,
+ append the first four bytes of the user account name
+ to the end of the password. If the hash is NOT associated
+ with a user account (e.g. it's the "enable" password),
+ this step should be omitted.
+3. The resulting password should be truncated to 16 bytes,
+ or the right side NULL padded to 16 bytes, as appropriate.
+4. Run the result of step 3 through MD5.
+5. Discard every 4th byte of the 16-byte MD5 hash, starting
+ with the 4th byte.
+6. Encode the 12-byte result using :data:`HASH64 <passlib.utils.h64>`.
+
+Security Issues
+===============
+This algorithm is not suitable for *any* use besides manipulating existing
+Cisco PIX hashes, due to the following flaws:
+
+* It's use of the username as a salt value (and only the first four characters
+ at that), means that common usernames (eg ``admin``, ``cisco``) will occur
+ more frequently as salts, weakening the effectiveness of the salt in
+ foiling pre-computed tables.
+
+* It's truncation of the ``password+user`` combination to 16 characters
+ additionally limits the keyspace, and the effectiveness of the username
+ as a salt; making pre-computed and brute force attacks much more feasible.
+
+* Since the keyspace of ``user+password`` is still a subset of ascii characters,
+ existing MD5 lookup tables have an increased chance of being able to
+ reverse common hashes.
+
+* It's simplicity, and the weakness of MD5, makes high-speed brute force attacks
+ much more feasible.
+
+* Furthermore, it discards of 1/4 of MD5's already small 16 byte digest,
+ making collisions much more likely.
+
+Deviations
+==========
+This implementation differs from the standard in one main way:
+
+* Unicode Policy:
+
+ The official Cisco PIX algorithm is primarily used with ``ascii`` passwords,
+ how it handles other characters is not known.
+
+ In order to provide support for unicode strings,
+ PassLib will encode unicode passwords using ``utf-8``
+ before running them through this algorithm. If a different
+ encoding is desired by an application, the password should be encoded
+ before handing it to PassLib.
+
+* While this implementation agrees with all known references,
+ the actual algorithm has not been published by Cisco, so there may be other
+ unknown deviations.
+
+.. rubric:: Footnotes
+
+.. [#] Description of PIX algorithm -
+ `<http://www.perlmonks.org/index.pl?node_id=797623>`_
+
+.. [#] Message threads hinting at how username is handled -
+ `<http://www.openwall.com/lists/john-users/2010/02/02/7>`_,
+ `<www.freerainbowtables.com/phpBB3/viewtopic.php?f=2&t=1441>`_
diff --git a/docs/lib/passlib.hash.cisco_type7.rst b/docs/lib/passlib.hash.cisco_type7.rst
new file mode 100644
index 0000000..7d9c83b
--- /dev/null
+++ b/docs/lib/passlib.hash.cisco_type7.rst
@@ -0,0 +1,134 @@
+.. index:: cisco; type 7 hash
+
+==================================================================
+:class:`passlib.hash.cisco_type7` - Cisco "Type 7" hash
+==================================================================
+
+.. currentmodule:: passlib.hash
+
+This class implements the "Type 7" password encoding used Cisco IOS.
+This is not actually a true hash, but a reversible encoding of the plaintext
+password. Type 7 strings are (and were designed to be) **plaintext equivalent**;
+the goal was to protect from "over the shoulder" eavesdropping, and
+little else. They can be trivially decoded. **Do not use for any purpose
+where actual security is needed**.
+
+.. note::
+
+ This implementation should work correctly for most cases, but may not
+ fully implement some edge cases (see `Deviations`_ below).
+ Please report any issues encountered.
+
+.. seealso::
+
+ * :doc:`passlib.hash.md5_crypt` (referred to as a "type 5" hash by Cisco)
+ * :doc:`passlib.hash.cisco_pix`
+
+Usage
+=====
+This class can be used directly as follows::
+
+ >>> from passlib.hash import cisco_type7 as ct
+
+ >>> # encode password
+ >>> h = ct.encrypt("password")
+ >>> h
+ '044B0A151C36435C0D'
+
+ >>> #verify correct password
+ >>> ct.verify("password", h)
+ True
+ >>> #verify incorrect password
+ >>> pm.verify("letmein", h)
+ False
+
+ >>> #check if hash is recognized
+ >>> ct.identify(h)
+ True
+ >>> #check if some other hash is recognized
+ >>> ct.identify('$1$3azHgidD$SrJPt7B.9rekpmwJwtON31')
+ False
+
+ >>> # to demonstrate this is an encoding, not a real hash,
+ >>> # this class supports decoding the resulting string:
+ >>> ct.decode(h)
+ "password"
+
+Interface
+=========
+.. autoclass:: cisco_type7()
+
+.. rst-class:: html-toggle
+
+Format & Algorithm
+==================
+The Cisco Type 7 encoding consists of two decimal digits
+(encoding the salt), followed a series of hexdecimal characters,
+two for every byte in the encoded password.
+An example encoding (of ``"password"``) is ``044B0A151C36435C0D``.
+This has a salt/offset of 4 (``04`` in the example),
+and encodes password via ``4B0A151C36435C0D``.
+
+The algorithm is a straightforward XOR Cipher (though note the description below
+may not be entirely correct, see `Deviations`_ for details):
+
+1. The algorithm relies on the following ``ascii``-encoded 53-byte
+ secret key::
+
+ dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncxv9873254k;fg87
+
+2. A integer salt should be generated from the range
+ 0 .. 15. The first two characters of the encoded string are the
+ zero-padded decimal encoding of the salt.
+
+3. The remaining characters of the encoded string are generated as follows:
+ For each byte in the password (starting with the 0th byte),
+ the :samp:`{i}`'th byte of the password is encoded as follows:
+
+ * let ``j=(i + salt) % keylen``
+ * XOR the :samp:`{i}`'th byte of the password with the :samp:`{j}`'th byte
+ of the secret key.
+ * encode the resulting byte as uppercase hexidecimal,
+ and append to the encoded string.
+
+Deviations
+==========
+This implementation differs from the official one in a few ways.
+It may be updated as more information becomes available.
+
+* Unicode Policy:
+
+ Type 7 encoding is primarily used with ``ASCII`` passwords,
+ how it handles other characters is not known.
+
+ In order to provide support for unicode strings, PassLib will encode unicode
+ passwords using ``UTF-8`` before running them through this algorithm. If a
+ different encoding is desired by an application, the password should be
+ encoded before handing it to PassLib.
+
+* Magic Key:
+
+ Some implementations contain a truncated 26-byte key instead of the
+ 53-byte key listed above. However, it is likely those implementations have an
+ incomplete copy of the key, as they exhibit other issues as well after
+ the 26th byte is reached (throwing an error, truncating the password,
+ outputing garbage), instead of wrapping around to the beginning of the key.
+
+* Salt Range:
+
+ All known test vectors contain salt values in ``range(0,16)``.
+ However, the algorithm itself should be able to handle any salt value
+ in ``range(0,53)`` (the size of the key). For maximum compatibility with
+ other implementations, Passlib will accept ``range(0,53)``, but only
+ generate salts in ``range(0,16)``.
+
+* While this implementation handles all known test vectors,
+ and tries to make sense of the disparate implementations,
+ the actual algorithm has not been published by Cisco,
+ so there may be other unknown deviations.
+
+.. rubric:: Footnotes
+
+.. [#] Description of Type 7 algorithm -
+ `<http://pen-testing.sans.org/resources/papers/gcih/cisco-ios-type-7-password-vulnerability-100566>`_,
+ `<http://wiki.nil.com/Deobfuscating_Cisco_IOS_Passwords>`_
diff --git a/docs/lib/passlib.hash.md5_crypt.rst b/docs/lib/passlib.hash.md5_crypt.rst
index 538ced5..6305e8f 100644
--- a/docs/lib/passlib.hash.md5_crypt.rst
+++ b/docs/lib/passlib.hash.md5_crypt.rst
@@ -1,3 +1,5 @@
+.. index:: cisco; type 5 hash
+
==================================================================
:class:`passlib.hash.md5_crypt` - MD5 Crypt
==================================================================
@@ -12,25 +14,41 @@ Security-wise it is considered to be steadily weakening (due to fixed cost),
and most unix flavors have since replaced with with stronger schemes,
such as :class:`~passlib.hash.sha512_crypt` and :class:`~passlib.hash.bcrypt`.
+This is also referred to under Cisco IOS systems as a "type 5" hash.
+The format and algorithm are identical, though Cisco seems to require [#cisco]_
+4 salt characters instead of the full 8 characters
+used by most systems.
+
Usage
=====
PassLib provides an md5_crypt class, which can be can be used directly as follows::
- >>> from passlib.hash import md5_crypt as mc
+ >>> from passlib.hash import md5_crypt
- >>> mc.encrypt("password") #generate new salt, encrypt password
+ >>> #generate new salt, encrypt password
+ >>> h = md5_crypt.encrypt("password")
+ >>> h
'$1$3azHgidD$SrJPt7B.9rekpmwJwtON31'
- >>> mc.identify('$1$3azHgidD$SrJPt7B.9rekpmwJwtON31') #check if hash is recognized
+
+ >>> #verify correct password
+ >>> md5_crypt.verify("password", h)
True
- >>> mc.identify('JQMuyS6H.AGMo') #check if some other hash is recognized
+ >>> #verify incorrect password
+ >>> md5_crypt.verify("secret", h)
False
- >>> mc.verify("password", '$1$3azHgidD$SrJPt7B.9rekpmwJwtON31') #verify correct password
+ >>> #check if hash is recognized
+ >>> md5_crypt.identify(h)
True
- >>> mc.verify("secret", '$1$3azHgidD$SrJPt7B.9rekpmwJwtON31') #verify incorrect password
+ >>> #check if some other hash is recognized
+ >>> md5_crypt.identify('JQMuyS6H.AGMo')
False
+ >>> # encrypt password using cisco-compatible 4-char salt
+ >>> md5_crypt.encrypt("password", salt_size=4)
+ '$1$wu98$9UuD3hvrwehnqyF1D548N0'
+
Interface
=========
.. autoclass:: md5_crypt()
@@ -178,3 +196,6 @@ PassLib's implementation of md5-crypt differs from the reference implementation
.. [#f2] Security issues with MD5 -
`<http://en.wikipedia.org/wiki/MD5#Security>`_.
+
+.. [#cisco] Note about Cisco Type 5 salt size -
+ `<http://serverfault.com/a/46399>`_.
diff --git a/docs/lib/passlib.hash.rst b/docs/lib/passlib.hash.rst
index 13c2397..dba95c7 100644
--- a/docs/lib/passlib.hash.rst
+++ b/docs/lib/passlib.hash.rst
@@ -191,6 +191,14 @@ in one of the above categories:
.. toctree::
:maxdepth: 1
+ passlib.hash.cisco_pix
+
+* *Cisco "Type 5" hashes* - see :doc:`md5_crypt <passlib.hash.md5_crypt>`
+
+.. toctree::
+ :maxdepth: 1
+
+ passlib.hash.cisco_type7
passlib.hash.django_std
passlib.hash.grub_pbkdf2_sha512
passlib.hash.hex_digests