[转载]John the Ripper 1.7 (by Solar Designer)
信息来源:[url]http://www.openwall.com/[/url]原始连接:[url]http://www.securityfocus.com/columnists/388[/url]
Federico Biancuzzi interviews Solar Designer, creator of the popular John the Ripper password cracker. Solar Designer discusses what's new in version 1.7, the advantages of popular cryptographic hashes, the relative speed at which many passwords can now be cracked, and how one can choose strong passphrases (forget passwords) that are harder to break.
“ With some vendors re-inventing password hashing and doing it wrongly (or trying to be compatible with something ancient), and with increasing CPU performance, it is not possible to have passwords that are stored using certain hash types withstand offline attacks, even if the most stringent password policy is followed. That is, if someone would steal LM hashes from a Windows system (or capture them on the wire), those passwords would be relatively easily cracked, no matter what. ”
Solar Designer Could you introduce yourself?
Solar Designer: For the past 9 years I've been spending much of my time on computer and network security. In particular, I've been developing free Unix security tools and other (non-security) software designed to be safe to use, as well as making existing software and technologies safer to use (discovering, dealing with, and sometimes publicizing vulnerabilities whenever that seemed appropriate). This is what the Openwall Project is about.
Although I am the author of most of the individual pieces of software released under Openwall, our biggest development project, Openwall GNU/*/Linux (or Owl for short), is a team effort which I am leading. Owl is a security-enhanced OS intended primarily for Internet servers.
What new features does the latest version 1.7 of John the Ripper include?
Solar Designer: The new "features" this time are primarily performance improvements possible due to the use of better algorithms (bringing more inherent parallelism of trying multiple candidate passwords down to processor instruction level), better optimized code, and new hardware capabilities (such as AltiVec available on PowerPC G4 and G5 processors).
In particular, John the Ripper 1.7 is a lot faster at Windows LM hashes than version 1.6 used to be. (Since JtR is primarily a Unix password cracker, optimizing the Windows LM hash support was not a priority and hence it was not done in time for the 1.6 release.) John's "raw" performance at LM hashes is now similar to or slightly better than that of commercial Windows password crackers such as LC5 - and that's despite John trying candidate passwords in a more sophisticated order based on statistical information (resulting in typical passwords getting cracked earlier).
John the Ripper 1.7 also improves on the use of MMX on x86 and starts to use AltiVec on PowerPC processors when cracking DES-based hashes (that is, both Unix crypt(3) and Windows LM hashes). To my knowledge, John 1.7 (or rather, one of the development snapshots leading to this release) is the first program to cross the 1 million Unix crypts per second (c/s) boundary on a general-purpose CPU. Currently, John 1.7 achieves up to 1.6M c/s raw performance (that is, with no matching salts) on a PowerPC G5 at 2.7 GHz (or 1.1M c/s on a 1.8 GHz) and touches 1M c/s on the fastest AMD CPUs currently available. Intel P4s reach up to 800k c/s. (A non-public development version making use of SSE also reaches 1M c/s on an Intel P4 at 3.4 and 3.6 GHz. I intend to include that code into a post-1.7 version.)
Additionally, John 1.7 makes an attempt at generic vectorization support for bitslice DES (would anyone try to set DES_BS_VECTOR high and compile this on a real vector computer, with compiler vectorizations enabled?), will do two MD5 hashes at a time on RISC architectures (with mixed instructions, allowing more instructions to be issued each cycle), and includes some Blowfish x86 assembly code optimizations for older x86 processors (the Pentium Pro family, up to and including Pentium 3) with no impact on newer ones due to runtime CPU type detection.
Speaking of the actual features, John 1.7 adds an event logging framework (John will now log how it proceeds through stages of each of its cracking modes - word mangling rules being tried, etc.), better idle priority emulation with POSIX scheduling calls (once enabled, this almost eliminates any impact John has on performance of other applications on the system), system-wide installation support for use by *BSD ports and Linux distributions, and support for AIX, DU/Tru64 C2, and HP-UX tcb files in the "unshadow" utility.
Finally, there are plenty of added pre-configured make targets with optimal settings, including ones for popular platforms such as Linux/x86-64, Linux/PowerPC (including ppc64 and AltiVec), Mac OS X (PowerPC and x86), Solaris/sparc64, OpenBSD on almost anything 32-bit and 64-bit, and more.
Of course, all platforms supported by John 1.6 (including plain x86 running most Unix-like systems, Win32, or DOS) are still supported. Similarly, pre-compiled binary distributions of John 1.7 for Win32 and DOS are made available.
Did you do any tests with projects such as BrookGPU and a modern GPU? Do you plan to try general-purpose computation using graphics hardware?
Solar Designer: No. I haven't seriously looked into this, but I don't expect GPUs to be very efficient at bitwise operations - which is what we need for John. If John would ever officially support algorithms involving floating-point operations, things could be different.
FPGAs are far more promising for this application (in fact, they're a guaranteed success).
Buying a 64bit cpu is now easy and cheap. How much does the availability of x86-64 CPUs affect the time needed to crack passwords?
Solar Designer: I am sorry to disappoint you, but this is not a major change for John.
As far as John is concerned, Intel's MMX was already 64-bit. It was not a true 64-bit architecture (most importantly, there was no 64-bit addressing), but in order to implement bitslice DES, only bitwise operations were needed - and those were available. The only things which change for John the Ripper on x86 with the availability of x86-64 CPUs are the ability to generate 64-bit code from C source (MMX code had to be hand-written or generated with self-made scripts), the availability of more 64-bit registers (15 usable instead of just 8), and the lack of an AND-NOT operation with x86-64. While the extra registers provide some speedup for bitslice DES, the existing MMX code is hand-optimized whereas the x86-64 code is currently being generated by C compilers. Overall, x86/MMX and x86-64 builds of John deliver similar performance, with differences for most hash types being within 20% (on the same CPU). As of this writing, the c/s rate for traditional crypt(3) is between 600k and 1 million for all modern x86 and x86-64 CPUs.
John is not new to 64-bit architectures. It was made to run on Alphas taking advantage of their 64-bitness back in 1997. In 1998, John 1.5 reached 200k c/s at traditional crypt(3) on an Alpha 21164A 600 MHz with pure C code, whereas a Pentium Pro 200 MHz (no MMX) would only do 20k c/s. With the initial MMX support, John would do 50k c/s on a Pentium 2 at 350 MHz (the fastest available) - still 4 times slower than the Alpha. Due to further improvements, John 1.7, if it were around at the time, would have achieved 250k c/s on that same old Alpha and over 100k c/s on that same old Pentium 2 (or 50k c/s on something as slow as Pentium MMX 166 MHz).
Now John 1.7 supports AltiVec on PowerPCs - welcome to 128-bit vectors and c/s rates in excess of 1 million. :-)
For a comparison against some historical 32-bit CPUs, a 386DX 40 MHz used to do around 1k c/s with Cracker Jack (a DOS program specifically optimized for 386s) and less than that with Crack. A MicroVAX 3100-80 (KA47 50 MHz) does a little below 1k c/s with the current John. Apparently, the original VAX-11/780 could do around 4 c/s. So with the newest PowerPCs and with the new John the Ripper we've got roughly 400,000 times better password cracking speed these days.
We have been using passwords for decades. What do you suggest in choosing a good one that is hard to crack?
Solar Designer: This is a seemingly simple question, but the answer depends on the specific circumstances and the kind of attacks the password is meant to resist.
Some people would say that passwords are obsolete. But we're continuing to use passwords anyway, for a variety of reasons. In fact, even many authentication systems designed to replace the old-fashioned password authentication do nevertheless use passwords (or passphrases). For example, the private keys used with SSH RSA or DSA authentication are encrypted using a passphrase as the encryption key. S/Key uses a passphrase to generate a sequence of one-time passwords (and Dug Song has contributed a patch to John the Ripper to crack those passphrases).
With some vendors re-inventing password hashing and doing it wrongly (or trying to be compatible with something ancient), and with increasing CPU performance, it is not possible to have passwords that are stored using certain hash types withstand offline attacks, even if the most stringent password policy is followed. That is, if someone would steal LM hashes from a Windows system (or capture them on the wire), those passwords would be relatively easily cracked, no matter what. The entire printable US-ASCII keyspace (that is, all possible passwords consisting of the 95 printable US-ASCII characters only) can be searched against any number of LM hashes within a couple of weeks on a single modern CPU, and most passwords would fall within the first hour. Of course, John takes advantage of the fact that LM hashes are case-insensitive and that the first 7 characters of passwords are processed separately from characters 8-14. (So-called rainbow tables can be even more effective against LM hashes, but John does not implement them.)
Why crack LM hashes with the purpose of detecting and eliminating "weak" passwords at all, then?
One possible reason would be to ensure that the passwords are not as weak as to be easy to guess from the remote [perspective] (or from a local login prompt, for that matter). Another reason would be to ensure that the not-so-weak NTLM hashes of the same passwords (that Windows systems use along with or instead of LM hashes) would be strong enough to withstand certain offline attacks. Someone who is into Windows security (I am not) could explain those subtle reasons better.
What is the situation in the Unix world?
Speaking of Unix passwords, even the ancient traditional crypt(3) hashes can withstand John runs on a single CPU if extremely complicated passwords are chosen. Although it would be taking over 100 years to exhaustively search the printable US-ASCII keyspace against traditional crypt(3) hashes on a single CPU (that is currently available), in practice it is common to crack 20% to 60% of such hashes within a reasonable time (days, weeks, or months). When attacking individual password hashes (e.g., root's), the chances of success can be much higher (90% is a reasonable estimate) since all processing power can be directed against that one salt.
The newer crypt(3) hashing methods are generally better, resulting in password hashes that are stronger (given the same passwords), and they also don't have the 8-character limitation of traditional crypt(3).
The FreeBSD-style MD5-based hashes that are so popular nowadays (they're used on FreeBSD, on many (most?) Linux systems, and on Cisco IOS for "enable" passwords) are significantly better, but they aren't quite state of the art. The OpenBSD-style Blowfish-based (bcrypt) hashes are a whole lot better, adding variable iteration counts (such that a system administrator can proceed to adjust the processing cost for hashes that would be used for newly set or changed passwords as CPUs become faster).
Those multiple iterations of an underlying cryptographic primitive (such as modified DES, MD5, or Blowfish) are used to implement so-called "password stretching". bcrypt hashes can reasonably be configured to be, say, 15,000 times slower than traditional crypt(3) hashing on a given CPU. This is equivalent to passwords (or passphrases) containing 14 bits of additional entropy compared to what one has to actually remember and type in at a login prompt. That's roughly two words less to type in a passphrase.
So, do you suggest to use passphrases instead?
Yes, for operating systems, applications, etc. which do not have a low limit on the length of passwords they accept, I recommend the use of passphrases instead of passwords. For even better security and/or to have fewer characters to type, both approaches can be combined: separate some words with punctuation rather than spaces, embed numbers and other characters, etc. Ideally, the passphrase should be something you can remember or derive again, but it must not be based on information that is known to others (e.g., your name, a quotation, a piece of the output of a Unix shell command, etc. - those are all to be avoided).
The shortest reasonable "passphrase" consists of a cryptographically random combination of three words (picked from a list of a few thousand) separated by unusual punctuation, and its length is no less than, say, 12 characters. This corresponds to roughly 40 bits of entropy, which, combined with a decent password hashing method such as bcrypt, gives a fairly strong password hash. Since a human cannot be expected to truly pick words at random, a passphrase you might think up would need to be longer than that. Older/weaker password hashing methods will require longer passphrases, too.
Care should be taken to see if long "passwords" are indeed fully processed by the target system rather than silently truncated at a certain length. For the traditional Unix crypt(3), that length would be 8 characters - so only those first 8 characters would need to be guessed by an attacker. A way to test for this is to set your password to something longer, then try to login to the system using only the first 8 characters.
On those older systems, in order for your password hash to be hard to crack, you have to use an unusual combination of lowercase and uppercase letters, digits, and other characters - making use of the maximum supported length (usually 8 characters). And I really mean "unusual" - just starting with a capital letter and/or ending with a number doesn't count. Needless to say, the password must not be based on your personally identifiable information or a dictionary word in any known language. (Some older papers on password security recommended picking the first letter of each word of a phrase to form short and easy to remember, yet unusual passwords. Unfortunately, this results in a highly non-uniform distribution of characters used - which John is able to take advantage of. So I do not recommend it.)
“ With some vendors re-inventing password hashing and doing it wrongly (or trying to be compatible with something ancient), and with increasing CPU performance, it is not possible to have passwords that are stored using certain hash types withstand offline attacks, even if the most stringent password policy is followed. That is, if someone would steal LM hashes from a Windows system (or capture them on the wire), those passwords would be relatively easily cracked, no matter what. ”
Solar Designer
Should we use password generators?
There exist password generator programs which would produce both random passphrases and random mixes of weird characters for use as short passwords. Unfortunately, many if not most of them do not use cryptographically secure sources of randomness and/or have other weaknesses. In fact, John the Ripper includes an external "cracking mode" (defined in a C-like language available for use from the configuration file) to demonstrate this kind of weakness of one such password generator ("Strip", which is short for "Secure Tool for Recalling Important Passwords"). In this cracking mode, John will try all passwords [that] certain versions of Strip could possibly generate. Although the passwords look like they are strong (weird mixes of characters), there can only be a few million of them, so John can check them all quickly (for some hash types, in a matter of seconds).
Now, this may sound like there's almost no way for an average person to pick secure passwords and for a system administrator to enforce the use of strong passwords (or passphrases). Luckily, there's a tool I wrote to help the situation. It's pam_passwdqc, a password strength checking module for the PAM (Pluggable Authentication Modules) framework. pam_passwdqc works on Linux, FreeBSD 5+ (in fact, it's been integrated into FreeBSD), Solaris, HP-UX 11+, and reportedly on recent versions of IRIX. Additionally, Damien Miller has developed a plugin password strength checker for OpenBSD's /usr/bin/passwd that uses the password complexity checking code from pam_passwdqc.
pam_passwdqc will impose reasonable restrictions on passwords and passphrases. On systems which provide a cryptographically secure source of randomness, pam_passwdqc will also offer randomly-generated combinations of words separated by punctuation for use as "passphrases". The default settings of pam_passwdqc are adequate for bcrypt hashes. If used with other (weaker) password hashing methods, the settings may need to be tweaked. In particular, if used with the traditional crypt(3), the option "max=8" must be specified, telling pam_passwdqc that passwords are truncated at 8 characters.
In practice, you can expect almost no passwords to be cracked with John the Ripper on systems which use bcrypt for password hashing and have pam_passwdqc installed (with default settings). Of course, Openwall GNU/*/Linux uses bcrypt and pam_passwdqc for users' passwords by default.
And what would you recommend to developers writing the code that manages the passwords database? Which algorithm should they use? Any trick?
Solar Designer: For C and C++ applications, I recommend my implementation of bcrypt, crypt_blowfish. When setting new passwords, the iteration counts passed into crypt_gensalt*() functions provided by crypt_blowfish should be made configurable (by the administrator, if applicable).
For PHP applications, I recommend my PHP password hashing framework, phpass. This will use a variable iteration count password hashing method that the system or the PHP interpreter might support natively (if available), with a fallback to a hashing method implemented in phpass itself (in PHP). The latter is not so great because of the slowness of PHP code. To ensure that the fallback will never occur, the PHP Hardening-Patch may be used. The Hardening-Patch integrates crypt_blowfish into the PHP interpreter such that bcrypt is available for use by PHP scripts even if the host system lacks support for it. Hopefully, future versions of PHP will do the same.
Both crypt_blowfish and phpass are in the public domain, so there are no copyrights or licensing restrictions to worry about (there can be none).
Of course, in addition to using a good password hashing method, strong passwords need to be enforced. I do not currently have a generic library for it, but the password strength checking code found in pam_passwdqc is trivial to re-use in other applications. The license for pam_passwdqc is very liberal (it is BSD and (L)GPL-compatible).
I do not currently have code for other programming languages.
I wish I could recommend something which does not include code I've written, but the very reason I did my own implementations is that I was not satisfied with whatever was available previously. For example, CrackLib and Linux-PAM pam_cracklib (with default settings) will allow most all-numeric passwords to be set (don't believe? try setting your password to "13579135"). Obviously, those passwords are easily cracked...
Federico Biancuzzi is freelancer; in addition to SecurityFocus he also writes for ONLamp, LinuxDevCenter, and NewsForge.
页:
[1]