「John the Ripper」と「cracklib」でパスワードの脆弱性をチェック

■「John the Ripper」と「cracklib」でパスワードの脆弱性をチェックする
 カスタム辞書を用意することで、個人的な、あるいはローカルな単純パスワードを効率的に発見できます。
 勿論、パスワード強度の高いパスワードを設定するよう促す為の検査です。

■環境は、debian Wheezy。
 ユーザ名だけでなく、ユーザ名+生年月日を辞書化することで、
 安易なパスワードを設定していないかチェックできます。

 また、後片付けとして、パスワードは最後に変更しましょう。

■johnの導入

$ sudo apt-get install -y john
$ apropos john
john (8)             - a tool to find weak passwords of your users

■ディレクトリ作成とオプションの表示

$ sudo john
Created directory: /root/.john
John the Ripper password cracker, version 1.7.8
Copyright (c) 1996-2011 by Solar Designer
Homepage: http://www.openwall.com/john/

Usage: john [OPTIONS] [PASSWORD-FILES]
--single                   "single crack" mode
--wordlist=FILE --stdin    wordlist mode, read words from FILE or stdin
--rules                    enable word mangling rules for wordlist mode
--incremental[=MODE]       "incremental" mode [using section MODE]
--external=MODE            external mode or word filter
--stdout[=LENGTH]          just output candidate passwords [cut at LENGTH]
--restore[=NAME]           restore an interrupted session [called NAME]
--session=NAME             give a new session the NAME
--status[=NAME]            print status of a session [called NAME]
--make-charset=FILE        make a charset, FILE will be overwritten
--show                     show cracked passwords
--test[=TIME]              run tests and benchmarks for TIME seconds each
--users=[-]LOGIN|UID[,..]  [do not] load this (these) user(s) only
--groups=[-]GID[,..]       load users [not] of this (these) group(s) only
--shells=[-]SHELL[,..]     load users with[out] this (these) shell(s) only
--salts=[-]COUNT           load salts with[out] at least COUNT passwords only
--format=NAME              force hash type NAME: DES/BSDI/MD5/BF/AFS/LM/crypt
--save-memory=LEVEL        enable memory saving, at LEVEL 1..3

$ sudo ls -lda /root/.john
drwx------ 2 root root 4096  517 23:11 /root/.john

■ユーザ名をパスワードに設定する

$ (echo "labunix";echo "labunix") | sudo passwd labunix
新しいUNIXパスワードを入力してください:新しいUNIX パスワードを再入力してください:passwd: パスワードは正しく更新されました

■ユーザパスワードの一覧の取得
 ※rootは除く。

$ sudo unshadow /etc/passwd /etc/shadow | grep -v root | \
  sudo tee /tmp/.passwd > /dev/null; \
  sudo chown root:root /tmp/.passwd; \
  sudo chmod 400 /tmp/.passwd

$ ls -l /tmp/.passwd
-r-------- 1 root root 1400  517 23:14 /tmp/.passwd

■ユーザ数の確認。

$ su root -c 'wc -l /tmp/.passwd'
パスワード:
29 /tmp/.passwd

■29ユーザのうち、ハッシュ化されたパスワードを持っているユーザの確認

$ sudo awk -F\: '(length($2)>1){print $1}' /tmp/.passwd
labunix

■パスワードの検査
 あっという間に解読される。

$ sudo john /tmp/.passwd
Loaded 1 password hash (generic crypt(3) [?/64])
labunix          (labunix)
guesses: 1  time: 0:00:00:00 100% (1)  c/s: 234  trying: labunix - labunix}
Use the "--show" option to display all of the cracked passwords reliably

$ sudo john -show /tmp/.passwd
labunix:labunix:1000:1000:labunix,,,:/home/labunix:/bin/bash

1 password hash cracked, 0 left

■解読された情報やログは以下に保存される。

$ sudo ls -la /root/.john
合計 20
drwx------ 2 root root 4096  517 23:17 .
drwx------ 4 root root 4096  517 23:11 ..
-rw------- 1 root root 8051  517 23:17 john.log
-rw------- 1 root root  107  517 23:17 john.pot

$ sudo cat /root/.john/john.pot
$6$8wxk6sDD$92IhiFxt61Uu6swWmjqw7IDpOELw7RLNyW7H2mz4dOWZGTbS/oTeb6ASUVxk.ArCReaqtKZbpD.C1RglOU.pX.:labunix

$ sudo awk -F\: '(length($2)>1){print $2":"$1}' /tmp/.passwd
$6$8wxk6sDD$92IhiFxt61Uu6swWmjqw7IDpOELw7RLNyW7H2mz4dOWZGTbS/oTeb6ASUVxk.ArCReaqtKZbpD.C1RglOU.pX.:labunix

■解読した情報をクリア

$ sudo rm /root/.john/john.pot

■パスワードをユーザ名と数値に変更
 ユーザ情報の再取得、再検査。これだけで強度が上がったように見える。

$ (echo "labunix0010";echo "labunix0010") | sudo passwd labunix
新しいUNIXパスワードを入力してください:新しいUNIX パスワードを再入力してください:passwd: パスワードは正しく更新されました

$ sudo unshadow /etc/passwd /etc/shadow | grep -v root | \
  sudo tee /tmp/.passwd > /dev/null; \
  sudo chown root:root /tmp/.passwd; \
  sudo chmod 400 /tmp/.passwd

$ sudo john --single /tmp/.passwd
Loaded 1 password hash (generic crypt(3) [?/64])
guesses: 0  time: 0:00:00:03 100%  c/s: 236  trying: labunix1920 - labunix1900

$ sudo john --show /tmp/.passwd
0 password hashes cracked, 1 left

■総当たりで検査
 10分以上待っても結果が出ないので中断。

$ sudo john --user:labunix --incremental /tmp/.passwd
Loaded 1 password hash (generic crypt(3) [?/64])
 ^C

■辞書を用意するとあっという間に解読される。

$ for n in `seq -w 0 2013`;do echo "labunix$n";done | sudo tee /tmp/.userword > /dev/null
$ head -5 /tmp/.userword
labunix0000
labunix0001
labunix0002
labunix0003
labunix0004

$ sudo john --user:labunix --wordlist=/tmp/.userword /tmp/.passwd
Loaded 1 password hash (generic crypt(3) [?/64])
labunix0010      (labunix)
guesses: 1  time: 0:00:00:00 100%  c/s: 234  trying: labunix0000 - labunix0095
Use the "--show" option to display all of the cracked passwords reliably

■cracklibの導入とチェック
 数字を入れただけで「OK」でパスワード強度が高いという判定が出てしまいます。

$ sudo apt-get install -y libcrack2
$ echo "labunix0010" | sudo cracklib-check
labunix0010: OK

■勿論ユーザ名だけだと「辞書の単語に基づいています」と
 脆弱であることを報告します。

$ echo "labunix" | sudo cracklib-check
labunix: 辞書の単語に基づいています

■辞書を準備すると、脆弱であることが報告されます。

$ sudo create-cracklib-dict /tmp/.userword
2014 2014

$ echo "labunix0010" | sudo cracklib-check
labunix0010: 辞書の単語に基づいています

■シェルスクリプトなので、「/var/cache/cracklib」に保存されていることが分かります。

$ grep "bin\|output" /usr/sbin/create-cracklib-dict
#!/bin/sh
          -o, --output <file>   Alternative output file for cracklib-packer
          -h, --help            This help output
output=""
                -o|--output) output=$2; shift;;
exec cracklib-format "$@" | cracklib-packer ${output}

$ man cracklib-packer | grep "/.*dict"
       is  located  in  the directory /var/cache/cracklib/cracklib_dict and is
       /var/cache/cracklib/cracklib_dict.[hwm|pwd|pwi]

■下記のうち「.pwi」にバイナリで辞書を保存しています。

$ ls /var/cache/cracklib/cracklib_dict.*
/var/cache/cracklib/cracklib_dict.hwm  /var/cache/cracklib/cracklib_dict.pwi

$ sudo apt-get install -y binutils
$ strings /var/cache/cracklib/cracklib_dict.pwd | head -5
labunix0000
labunix0016
labunix0032
labunix0048
labunix0064