Previously in FreeBSD Basics:
In last week's article, we looked at which parts of a password policy could be implemented by editing the
/etc/login.conf file on your FreeBSD system. This week, I want to look at some techniques that can be used to implement the rest of our sample policy.
/etc/login.conf, we were able to enforce a minimum password length and set an expiry date on passwords. While it does not enforce password lockout per se, your FreeBSD system does come with some built-in mechanisms that make it harder for a person to try to guess a password by repeatedly typing in different passwords.
Use your ALT Function keys to find a terminal with a login prompt. Let's log in as a user, but type in an incorrect password:
login: bogus Password: Login incorrect login:
Notice what happened here. When you typed in the password, none of your keystrokes were displayed to your screen; this is to help prevent passersby from noticing what password you are typing. Also, the "login incorrect" error message doesn't specify what is incorrect. That is, it won't tell you if the problem is an incorrect username or an incorrect password.
Since we were just given the login prompt back after the error message, let's keep trying to use an incorrect password. At your fourth bad attempt, you'll notice something different: it took a few seconds to get the login prompt back. At your fifth bad attempt, it should take about 6 seconds before you get your prompt back; at your sixth bad attempt, it should take about 9 seconds, and so on. This cycle will continue until you either have 10 bad attempts or you use up 300 seconds. At that point, your screen should look something like this:
FreeBSD/i386 (hostname) (ttyv4) login:
and the cycle starts all over again.
While you were making your bad password attempts, your FreeBSD system was keeping track of your actions. Use your ALT F1 keys to go to the console terminal; you should see messages similar to this:
Jan 14 9:43:23 hostname login: 8 LOGIN FAILURES ON ttyv4 Jan 14 9:44:52 hostname login: 2 LOGIN FAILURES ON ttyv4
To implement the rest of our sample password policy, we'll have to be a bit more creative. We wanted users to have at least one non-letter character in their password, not be allowed to use their username as their password, and not reuse any of their last ten passwords.
One way to accomplish this is to make users aware of the password policy, then use a utility that will tell you which users are selecting poor passwords. This method makes the users responsible for choosing passwords that follow the policy, and makes the administrator responsible for ensuring that the policy is being enforced.
But how can a utility view a user's password? Remember that passwords are not stored anywhere on your FreeBSD system. Instead, a hash is stored in the password database, and these hashes are in an encrypted format. Let's take a minute to define what a hash is and how it is created.
A hash is a string of characters, like a password, that has been scrambled by an encryption algorithm. That is, some form of complicated math was done on the string of characters to make it very hard to guess what the original string of characters was. As an example, one could apply an algorithm to the word "password" and end up with something like "$1$hnH/w50a$tPdv5HZRsDP46FtsW8eXH."
Good hashes contain something called a "salt." A salt is a set of random characters that are added to the original string of characters before they are encrypted. A simple example of a salt would be to add the time of day; for example, if I log in at 8:45 using the password "password," the string that would be encrypted could be "8pass45word." By adding this bit of randomness to the password, my hash will actually be different every time I log in, unless the only time I ever log in is at 8:45.
Whether a salt is used and what the salt actually is depends upon the operating system and the encryption algorithm being used. On your FreeBSD system, there is a function called
crypt that uses either the "DES" or the "MD5" encryption algorithms to encrypt passwords. If you're curious to see the technical details on how
crypt works, read
man 3 crypt. Don't be dismayed if you can't understand everything in this manpage; encryption is supposed to be cryptic. Also, don't confuse the utility
crypt(1) with the function
crypt(3). The utility is a very primitive way to encrypt data files, while the function is an elaborate mechanism used to create password hashes.
By definition, password hashes are "one-way" hashes. This means that if I apply the same encryption algorithm to the hash, I won't end up with the original password; instead, I'll just end up with a more scrambled hash. The only way to find the original password is to type in a password, encrypt it with the same algorithm, and compare the resultant hash. If the hash is different, I must have used the wrong password; if the hash is the same, I can assume that I've typed in the correct password.
Which brings us to password crackers. These are utilities that encrypt hundreds of thousands of passwords in order to compare the resulting hashes with the hashes in your password database. Password crackers do follow a certain logic as they'll try the most common passwords first; for example, they'll try the user's name forwards, backwards, and with a number, they'll try information in the user's GECOS field, and they'll try a list of common passwords such as "password" and "pass." Then they'll go through all of the words in the dictionary. Not surprisingly, these types of crackers are called "dictionary" password crackers. Some password crackers are called "brute-force" password crackers as they add a third step: they'll patiently try every keystroke combination possible until all the passwords have been cracked.
Let's demonstrate using a dictionary password cracker to determine if the passwords your users are selecting conform to your password policy. We'll build and use the port called "Crack." As the superuser and while connected to the Internet, type:
cd /usr/ports/security/crack make install clean
Once the port is installed, remain as the superuser; cracking the contents of the password database is definitely an exercise that requires superuser privileges.
cd /usr/local/crack ls -l total 95 drwx------ 9 root wheel 512 Jan 13 15:45 ./ drwxr-xr-x 23 root wheel 512 Jan 13 20:26 ../ -rwx------ 1 root wheel 10788 Dec 20 1996 Crack* -rw------- 1 root wheel 6415 Dec 20 1996 LICENCE -rw------- 1 root wheel 1444 Dec 20 1996 Makefile -rwx------ 1 root wheel 1792 Dec 13 1996 Reporter* drwx------ 2 root wheel 1024 Jan 13 15:45 conf/ drwx------ 5 root wheel 512 Nov 4 1996 dict/ drwx------ 2 root wheel 512 Dec 20 1996 doc/ drwx------ 2 root wheel 512 Dec 19 1996 extra/ -rw------- 1 root wheel 33251 Dec 20 1996 manual.html -rw------- 1 root wheel 31320 Dec 20 1996 manual.txt drwx------ 4 root wheel 512 Jan 13 15:53 run/ drwx------ 2 root wheel 512 Dec 20 1996 scripts/ drwx------ 5 root wheel 512 Jan 13 15:45 src/
Notice the restrictive set of permissions given to this directory and its contents; regular users won't be able to even
cd into or view the contents of this directory.
To run the password cracker, type:
./Crack -fmt bsd /etc/master.passwd
and you should see something similar to this:
Crack 5.0a: The Password Cracker.
(c) Alec Muffett, 1991, 1992, 1993, 1994, 1995, 1996
System: FreeBSD genisis 4.2-RELEASE FreeBSD 4.2-RELEASE #0: Tue Dec 12 20:01:29 EST 2000 genisis@genisis:/usr/src/sys/compile/SOUND i386
Invoked: ./Crack -fmt bsd /etc/master.passwd
Crack: making utilities in run/bin/freebsd-4-i386_
find . -name "*~" -print | xargs -n50 rm -f
( cd src; for dir in * ; do ( cd $dir ; make clean ) ; done )
rm -f dawglib.o debug.o rules.o stringlib.o *~
/bin/rm -f *.o tags core rpw destest des speed libdes.a .nfs* *.old *.bak destest rpw des speed
rm -f *.o *~
`../../run/bin/freebsd-4-i386_/libc5.a' is up to date.
all made in util
Crack: The dictionaries seem up to date...
Crack: Sorting out and merging feedback, please be patient...
Crack: Merging password files...
cat: run/F-merged: No such file or directory
Crack: Creating gecos-derived dictionaries
mkgecosd: making non-permuted words dictionary
mkgecosd: making permuted words dictionary
Crack: launching: cracker -kill run/Kgenisis.22226
On my system, the entire exercise was finished within 5 seconds. Now, let's take a look at the results:
---- passwords cracked as of Sun Jan 14 12:17:41 EST 2001 ----
979492604:Guessed dlavigne [dlavigne] Dru Lavigne,,123-4567 [/etc/master.passwd /bin/tcsh]
979492611:Guessed genisis [genisisgenisis] User & [/etc/master.passwd /bin/csh]
---- done ----
Hmmmm. Looks like I'll be having a talk with the users dlavigne and genisis to remind them of our password policy. The password for "dlavigne" is the same as the username [dlavigne]. The user "genisis" picked a nice long password, but it is only the username twice: [genisisgenisis].
I'll have the user dlavigne change her password. One method of creating nonsense passwords is to use the first letter of each word in a song and throw some symbols or numbers into the mix; just remember not to hum the song while you are typing it in. Using the song "We All Live in a Yellow Submarine," dlavigne created the password "waliays87." Let's see what happens when I rerun the Crack utility:
./Crack -fmt bsd /etc/master.passwd
---- passwords cracked as of Sun Jan 14 12:23:42 EST 2001 ----
979492611:Guessed genisis [genisisgenisis] User & [/etc/master.passwd /bin/csh]
---- done ----
It looks like the new password for "dlavigne" survived the dictionary crack, as it no longer shows up in the output. If you run the Crack utility and don't receive any output in the report, you can assume that your users are choosing passwords that aren't simply some combination of their name or a word that can be found in a dictionary; that is, they must be choosing some random combination of numbers, letters, and symbols.
When Crack is run, it places its working files in the run directory; these files will end with an extension that was the PID of the Crack process. After you are finished using Crack, you should clean up this working directory by typing:
/usr/local/crack directory. It is also a good idea to manually delete the
run/F-merged file, as it contains the results that were read by the Reporter utility:
more run/F-merged F:$1$ZQQGAmIW$jCPUT9KjRGbXR/IpF0M/E0:genisisgenisis F:pZV8Ju.2sEqsY:dlavigne
Notice that it shows the encrypted hash followed by the cracked password, which is pretty sensitive information to leave on hard disk.
One last note on running Crack: NEVER run any type of password cracker on any computer that is not in a network that you are responsible for. It is perfectly acceptable to enforce password policy on your network; it is illegal to try to discover the passwords in use on another person's network.
Let's compare the dictionary cracker to a brute-force cracker. As the superuser and while connected to the Internet, type:
cd /usr/ports/security/john make install clean
Once it's finished building:
cd /usr/local/share/john unshadow /etc/passwd /etc/master.passwd > passwd.1 john passwd.1
At this point, you'll lose your prompt for a long period of time; if you use the
top command to see what your CPU is doing, you'll notice that most of your cpu cycles are being used by the brute-force cracker. Given enough time, "john" will be able to crack every single hash in the password database.
last pid: 94308; load averages: 5.72, 5.82, 5.52 up 9+20:40:37 13:54:35
35 processes: 6 running, 25 sleeping, 4 zombie
Mem: 61M Active, 11M Inact, 22M Wired, 4380K Cache, 22M Buf, 23M Free
Swap: 260M Total, 260M Free
PID USERNAME PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND
94228 root 62 0 1276K 836K RUN 1:31 18.65% 18.65% john
78070 root 63 0 9120K 8748K RUN 13:53 18.55% 18.55% cracker
36951 root 63 0 9160K 8776K RUN 17:25 17.72% 17.72% cracker
15408 root 64 0 9160K 8776K RUN 18:54 17.53% 17.53% cracker
22467 root 62 0 9160K 8776K RUN 18:10 16.65% 16.65% cracker
47788 root 2 0 884K 440K select 0:30 0.00% 0.00% moused
14767 root 2 0 2196K 1232K select 0:08 0.00% 0.00% fetchmail
47768 root 2 0 2496K 1432K select 0:08 0.00% 0.00% sendmail
71556 root 2 0 5200K 3888K select 0:07 0.00% 0.00% perl
47767 root 10 0 924K 540K nanslp 0:05 0.00% 0.00% lpd
47761 root 10 0 964K 620K nanslp 0:04 0.00% 0.00% cron
47736 root 2 0 916K 540K select 0:04 0.00% 0.00% syslogd
47712 root 2 0 532K 220K select 0:03 0.00% 0.00% dhclient
47772 root 2 0 2092K 984K select 0:01 0.00% 0.00% sshd
47759 root 2 0 1048K 660K select 0:01 0.00% 0.00% inetd
47812 genisis 18 0 1328K 632K pause 0:01 0.00% 0.00% csh
14573 root 18 0 1348K 840K pause 0:01 0.00% 0.00% csh
47814 genisis 18 0 1340K 736K pause 0:01 0.00% 0.00% csh
We've stumbled upon some interesting points in this exercise. First, there is no ethical reason to run a brute-force cracker on your FreeBSD machine. The administrator's job is to enforce sensible passwords, not to know the passwords used by his users. A utility such as Crack is sufficient to let the administrator know which users are using passwords that can be guessed within a few seconds by a dictionary password cracker.
However, the administrator does need to be aware that brute-force crackers are easily and freely available on the Internet. Fortunately, before a user can use a brute-force cracker, they need to have physical access to the password databases; notice that we had to
unshadow both password databases into a file before we could run the
john utility. It is the responsibility of the system administrator to ensure that only authorized, trusted users have access to the actual password database files and any backups that contain the password databases.
Let's summarize what we've learned so far about password policies. Ensuring that users use a lengthy password containing a random mix of characters should prevent other users from guessing each other's passwords and gaining access to resources they shouldn't have access to. Physically securing access to the password databases should prevent unauthorized users from using a brute-force cracking utility to obtain the passwords in use on your FreeBSD system.
What we haven't looked at yet is restricting how users actually connect to your FreeBSD system in order to receive a login prompt and attempt to use a username and password. Let's make that the focus of next week's article.
Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.
Read more FreeBSD Basics columns.
Discuss this article in the Operating Systems Forum.
Return to the BSD DevCenter.
Copyright © 2009 O'Reilly Media, Inc.