John the Ripper を使って、パスワードクラック

John the Ripper(通称john)は、強力なパスワード探索プログラムです。対応アルゴリズムは、DES、BSDI、MD5(FreeBSD)、Blowfish(OpenBSD)、Kerberos AFS、RC4(Windows2000)と多岐にわたります。そして、非常に高速です。8文字程度のパスワードは容易に探索することが可能です。


こういうツールの存在、その性能を知り、脅威と感じるならば十分な対策を練るようにしましょう。そのためにもまず、知ることが大切です。



環境

インストール
RPMforgeにはJohn the RipperRPMパッケージが用意されています。

# yum --enablerepo=rpmforge search john
(略)
john.i386 : John the Ripper password cracker

だから、インストールは簡単。yumで一発。

# yum --enablerepo=rpmforge install john

確認。

# which john
/usr/bin/john
# john
John the Ripper password cracker, ver: 1.7.9-jumbo-5 [linux-x86-sse2]
Copyright (c) 1996-2011 by Solar Designer and others
Homepage: http://www.openwall.com/john/

Usage: john [OPTIONS] [PASSWORD-FILES]
--config=FILE             use FILE instead of john.conf or john.ini
--single[=SECTION]        "single crack" mode
--wordlist=FILE --stdin   wordlist mode, read words from FILE or stdin
                --pipe    like --stdin, but bulk reads, and allows rules
--encoding=NAME           the input data is in a 'non-standard' character.
                          encoding. NAME = utf-8, koi8-r, and others. For a
                          full list, use --encoding=LIST
--rules[=SECTION]         enable word mangling rules for wordlist mode
--incremental[=MODE]      "incremental" mode [using section MODE]
--markov[=LEVEL[:opts]]   "Markov" mode (see documentation)
--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. It will be overwritten
--show[=LEFT]             show cracked passwords [if =LEFT, then uncracked]
--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[:MAX]    load salts with[out] COUNT [to MAX] hashes
--pot=NAME                pot file to use
--format=NAME             force hash type NAME: des/bsdi/md5/bf/afs/lm/
                          dynamic_n/bfegg/dmd5/dominosec/epi/hdaa/ipb2/krb4/
                          krb5/mschapv2/mysql-fast/mysql/netlm/netlmv2/netntlm/
                          netntlmv2/nethalflm/md5ns/nt/phps/po/xsha/crc32/
                          hmac-md5/lotus5/md4-gen/mediawiki/mscash/mscash2/
                          mskrb5/mssql/mssql05/mysql-sha1/nsldap/nt2/oracle11/
                          oracle/phpass-md5/pix-md5/pkzip/raw-md4/raw-md5thick/
                          raw-md5/raw-sha1/raw-sha/raw-md5u/salted-sha1/sapb/
                          sapg/sha1-gen/raw-sha224/raw-sha256/raw-sha384/
                          raw-sha512/xsha512/hmailserver/sybasease/crypt/trip/
                          ssh/pdf/rar/zip/dummy
--subformat=LIST          get a listing of all 'dynamic_n' formats
--save-memory=LEVEL       enable memory saving, at LEVEL 1..3
--mem-file-size=SIZE      size threshold for wordlist preload (default 5 MB)
--field-separator-char=C  use 'C' instead of the ':' in input and pot files
--fix-state-delay=N       performance tweak, see documentation
--nolog                   disables creation and writing to john.log file
--crack-status            emit a status line whenever a password is cracked
--plugin=NAME[,..]        load this (these) dynamic plugin(s)

テストユーザを準備
ユーザID: testuser1、パスワード: testuser1123というテストユーザを作成します。

# useradd testuser1
# passwd testuser1
Changing password for user testuser1.
New UNIX password: testuser1123
Retype new UNIX password: testuser1123

/etc/passwordと/etc/shadowから、解析するパスワードファイルを生成します。

# unshadow /etc/passwd /etc/shadow > /tmp/password.txt

忘れないうちにテストユーザを削除しておきましょう。うっかり削除を忘れるとセキュリティリスクとなります。

# userdel -r testuser1

設定ファイルjohn.confを用意する
さっそく実行!

# john -users:testuser1 password.txt
fopen: $JOHN/dynamic.conf: No such file or directory

あれ!?
標準の設定ファイル /etc/john.conf の最後の行

.include 

これが原因のようなので...。これが何なのか理解していないのだけど...、
設定ファイルをコピーして、

# cp /etc/john.conf  /tmp/john.conf

最後の行をコメントアウトする。

#.include <dynamic.conf>

以降、実行時には、--config=/tmp/john.conf オプションをつけて、修正済み設定ファイルを使うようにしましょう。



パスワード探索開始!
上で用意したテストユーザ、こんな簡単なパスワード(ユーザID+"123")だと、パスワードは一瞬で発見されます。

# cd /tmp
# john --config=john.conf -users:testuser1 password.txt
Loaded 1 password hash (FreeBSD MD5 [32/32])
testuser1123     (testuser1)
guesses: 1  time: 0:00:00:00 DONE (Wed Jul  4 22:13:58 2012)  c/s: 1896  trying: testuser1123
Use the "--show" option to display all of the cracked passwords reliably

最後の行にある通り、--showオプションで結果表示ってことなので実行。
見事に、パスワードがtestuser1123だということが表示されます。

# john --config=john.conf --show password.txt
testuser1:testuser1123:502:502::/home/testuser1:/bin/bash

1 password hash cracked, 2 left

オプション
最も簡単な実行は、単にパスワードファイルを指定するだけです。

$ john password.txt

こうすると、パスワードファイルに含まれるすべてのユーザを対象にすべての方法で探索を実行します。これは非常に時間が掛かるので、オプションを有効に活用しましょう。


探索対象ユーザを指定する

$ john --users:testuser1,grgrjnjn,hogeuser,foouser,baruser password.txt

暗号アルゴリズムを指定する
オプション --format を使います。指定可能なアルゴリズムは、上記のjohn実行結果(ヘルプ)を参照してください。

Linuxの場合、/etc/shadowのパスワードを見ると、先頭が$1$となっているだろう。これは、MD5が使われていることを示してる。だから、--format=MD5 を使用すると探索が早くなるんじゃないかなぁと思う。

先頭の$1$がない(古いLinuxの)場合は、DESが使われている。



モード
シングルル・ラックモード --single
ユーザ名をもとにパスワードを推測。今回試したような安易なパスワードはこのモードで一瞬で探索されてしまいます。

ワードリストモード --wordfile:mydictionary.txt
辞書攻撃を行います。標準で用意された辞書もあります(/usr/share/john/password.lst)が、貧弱(3500件程度)なので、別途用意したほうが良いでしょう。

インクリメンタルモード --incremental:All
すべての組み合わせのパスワードを総当りで試します。
ルールは指定することも可能です。--incremental:Alpha --incremental:LenMan



その他
実行中に何かキー入力すると、進捗状況が表示されます。

# john --config=john.conf -users:root password.txt
Loaded 1 password hash (FreeBSD MD5 [32/32])
guesses: 0  time: 0:00:00:07 8.00% (2) (ETA: Wed Jul  4 22:44:24 2012)  c/s: 1808  trying: single1
guesses: 0  time: 0:00:00:19 20.93% (2) (ETA: Wed Jul  4 22:44:27 2012)  c/s: 1811  trying: geronimo!
...

以上