はじめに
悪用厳禁です。
必ず合法的かつ組織的な合意を取った上で実行してください。
またパスワードを解析することが主目的ではなく、「(平易な)パスワードの解析は容易である」ということを明らかにするためのデモンストレーションとして利用してください。
John the Ripperをインストールする
まずはインストールから。手元ではKali Linuxで実行したので最初からインストール済み、Debian系ならパッケージが提供されているのでapt-getでサクッとインストールできます。
$ sudo apt-get install john
なおMacの場合は
$ brew install john
でインストール可能です。
CentOSとかのRedHat系は試してませんが、標準のレポジトリには入ってないらしいので、EPEL辺りから探してこないといけないようです。
暗号化されたパスワードを入手する
データベースの中に暗号化されて保存されている場合は、それをそのまま持ってくればOKでしょう。フォーマットとしては「ユーザ名:暗号化されたパスワード」の形式で整形します。
ソルト付きの暗号方式の場合は、ソルトもセットでわからないと解析は実質不可能です。まあだからこそソルトの有用性が叫ばれるわけですが。
LDAPのuserPasswordを使う
ここではLDAPサーバからパスワードだけぶっこ抜きます。ワンライナーで書くとこんな具合。パスワードはハッシュ化した上でさらにBASE64でエンコードされてるので、これをデコードして整形します。
# slapcat | awk 'BEGIN{uidFound=0};$1 ~ /^uid:/{uid=$2;uidFound=1};$1 ~ /^userPassword::/ && uidFound == 1{printf uid":";system("echo " $2 "|base64 -d"); print "";uidFound=0};$0 == ""{uidFound=0}' > password.txt
中身はこのような感じになります。この場合はsalted-sha1ですね。
hogefuga:{SSHA}OyxsENDngHLRTgLMTFh4FNDxDzo=
LDAPのsambaNTPasswordを使う
Sambaサーバの認証をLDAPで行っている環境の場合、userPasswordではなくsambaNTPasswordを使うという手もあります。
# slapcat | awk 'BEGIN{uidFound=0};$1 ~ /^uid:/{uid=$2;uidFound=1};$1 ~ /^sambaNTPassword:/ && uidFound == 1{printf uid":";system("echo " $2 ""); print "";uidFound=0};$0 == ""{uidFound=0}' | sed 's/:/:$NT$/g' | sed '/^$/d' > sambant_password.txt
中身はこのようになります。
hogefuga:$NT$480F97CE40A2C72826C293D71BA565E0
いざ、実行!
公式のオプションなどはこちらを参照。
$ /usr/sbin/john --fork=4 --format=salted-sha1 password.txt
--formatオプションは指定しなくても自動判別して上手いことやってくれます。暗号化方式によってはプレフィックスの部分を調整・整形しないといけない場合があります。
--forkは解析に同時実行するプロセス数を指定できます。利用するマシンのコア数などに併せて適宜指定すると、解析速度に影響します。
モードの指定をしない場合は、singleモード・wordlistモード・incrementalモードの順に実行されます。最終的に総当りを試みるため、複雑なパスワードの場合はとんでもなく無制限に時間がかかりますので、バックグラウンドで実行するとかscreenを起動してから実行するとかした方がよいです。実行するマシンのスペックと暇さにもよりますが、1週間実行しても完走しなかったら挫折するかな。
実行のログと解析に成功した文字列については
~/.john/john.log ~/.john/john.pot
にそれぞれ記録されます。
$ /usr/sbin/john --show password.txt
と実行すれば解析済みのパスワードを再確認できます。
辞書の設定
/etc/john/john.confである程度の設定ができます。と言ってもあまり設定のしがいのある項目はありません。
wordlistモードで辞書ファイルを指定しない場合は、john.confの設定に従うようで、デフォルトでは/usr/share/john/password.lstが指定されますが、これは3559行しかないのでこの辞書にヒットするようなら噴飯モノです。
開発元のOpenWallからは4000万語のリストが27.95ドルで販売されてるので、これを買ってみるというのもまた一興かも。ただし英語由来の単語が大半で、日本語由来のものも10万ほど含まれていますが、まあ微妙と言えば微妙です。
なおwordlistモードの場合、辞書にある単語との完全一致しかヒットしない模様。incrementalモードの時に「辞書単語+1文字」とかはヒットするけど、辞書を参照した総当りをしているのかはよくわからん。
最後に
実行するパスワードリストの「意識の高さ」によりますが、一定の条件下で時間をかけさえすればだいたい解析できます。具体的には、ランダム文字列でも文字種が少ない(小文字と数字だけ)とか、そもそも文字数が8文字以下とかですね。もちろん理論的には果てしない時間をかければ解析はできるんでしょうけど、どの辺りを解析が非現実的だとするのかは難しいところです。手元で実行した範囲では、一般的にボーダーラインと言われる8文字でもそこそこの時間で解析できるものはできます。
なので、よく情報漏洩のニュースで「パスワードも流出しましたが暗号化されています」と言われても、単なるハッシュ化程度では解析可能なので、実質無意味です。
暗号化されたパスワードですら、平易なら現実的な実行時間で解析できてしまうという事実を前にどうするかというのは、それぞれの人次第。せめて自衛として自分の使うパスワードは長くて複雑なものにするというのも良し、組織内での啓蒙活動を行うも良し、関わっているサービスで強力なパスワードを強いるようにするのも良し。いずれにせよ、この解析の簡単さはもうちょっと世に知らしめてもいいと思います。
サービス実装の観点からは、そもそも漏洩しないような対策をすることはもちろんですが、ソルトを付けるとかストレッチングをするというのはそれなりに有効でしょう。