パスワード解読と漏洩の危険性

以下のテキストは、執筆時当時の情報を元に書いたものであり、 現在の情勢にそぐわないことを含む場合があるので注意されたい。 また、テキストは最終提出原稿で校正を経る前のものなので、実際にOSM 本誌に記載されたものとは異なる。誤字脱字等そのままである。

致命的な誤り以外は加筆修正等は行なわないので情報の鮮度に気をつけつつ 利用して欲しい。

目次


======================================================================
Part 3 パスワード解読と漏洩の危険性
======================================================================

■
■ユーザアカウントとパスワードファイル
■


●暗号化パスワード

パスワードファイルには暗号化されたパスワードが格納されている。暗号化に利
用できるアルゴリズムは主としてDESで、それに加え多くのPC-UnixではMD5ハッシュ
アルゴリズムも利用できるようになっている。それぞれがパスワードファイルに
どのように格納されているか見てみよう。

・暗号化パスワードとsalt

【リスト と(1)】にDESによるパスワードエントリの例を示した。コロンで区切
られた各フィールドの2番目が暗号化されたパスワードである。

	UUCbbnGZajVFM

この文字列の最初の2文字は「salt」といい、パスワードの暗号化処理のときに付
け加えられるランダムな文字列である。パスワードをそのまま暗号化すると、暗
号化文字列は必ず同じになってしまうので、暗号化後の文字列同士を比較するこ
とで元のパスワードが同じ人が分かってしまう。saltを入れることで、仮に元が
同じ単語でも、暗号化後の文字列が異なるようになっている。

【リスト と(2)】は同じパスワードをMD5アルゴリズムを利用して暗号化したも
のである。

	$1$cw5G3XZK$PkX/qp8oJQPvJRSIzGv4D1

最初の$1は、暗号化ライブラリにMD5アルゴリズムを使うことを指示する接頭辞
で、その後ろの$から$に挟まれた部分(cw5G3XZK)がsaltである。

---[リスト と]--------------------------------------------------------------
(1)DESによるパスワードエントリの例
open:UUCbbnGZajVFM:2006:4:OpenSourceMag.:/sbc:/bin/sh


(2)MD5によるパスワードエントリの例
open:$1$cw5G3XZK$PkX/qp8oJQPvJRSIzGv4D1:2006:4:OpenSourceMag.:/sbc:/bin/sh
----------------------------------------------------------------------------

・DESパスワードは8文字まで

現在でも利用されているDESパスワードだが、元となるパスワード長は8文字(8バ
イト)までという制限がある。実際に【リスト ち】を ctest.c という名前で保
存し、
	% gcc -o ctest ctest.c -lcrypt
	% ./ctest

として実行してみてほしい。DESによる暗号化文字列は8文字以上はどれも同じ結
果を返しているのが分かるはずである。


---[リスト ち]--------------------------------------------------------------
【ctest.c】
#include 
#include 
#include 
#define SIZE 27

int main()
{
  char pass[SIZE];
  int i;
  memset(pass, 0, SIZE);
  for (i=0; i
#include 

int doit(char *salt)
{
  time_t t;
  char pass[9] = "abcdefgh";
  int n;
  t = time(NULL);
  while (t==time(NULL)) ;
  for (n=0, t=time(NULL); t==time(NULL); n++) {
    pass[n%8] = 'A'+n%26;
    crypt(pass, salt);
  }
  return n;
    
}
int main()
{
  printf("DES: %7dtimes\n", doit("xx"));
  printf("MD5: %7dtimes\n", doit("$1$xx$"));
}
----------------------------------------------------------------------------

筆者の手元のマシン【註 を】では

	DES:   60004times
	MD5:    1875times

という結果が得られた。これは、1秒間にDES/MD5暗号化がそれぞれ何回計算でき
るかを測るプログラムである。仮にDESの比較処理が1秒当たり60000回できるも
のとして、各文字種の組み合わせを総当たり検査するのに要する時間(日数)を求
めたものが【表 を】である。

---[註 を]------------------------------------------------------------------
Athlon XP 2600+(2088.23 MHz) 上の NetBSD 3.0_STABLE で行なった。特別に速い
計算機を使ったわけでもない結果であることに注目してほしい。
----------------------------------------------------------------------------


---[表 を]------------------------------------------------------------------
【{表 る} を総当たりするのにかかる日数】


					→ 文字列の長さ
                  5         6        7          8         9        10
--------------+---------+--------+---------+---------+----------+----
数字だけ          0         0        0       0.02      0.19      1.93
(10字)
小文字だけ        0      0.06     1.55      40.28   1047.36  27231.31
(26字)
小文字+数字    0.01      0.42    15.12      544.2  19591.04 705277.48
(36字)
全英字         0.07      3.81   198.32   10312.45 536247.28  2.79E+07
(52字)	    
全英字+数字    0.18     10.96   679.32   42118.08  2.61E+06  1.62E+08 
(62字)
英数記号       0.72     58.64  4808.75   394317.3  3.23E+07  2.65E+09
(82字)      
----------------------------------------------------------------------------

小文字だけで構成された8文字のパスワードは、40日程度で総当たりできてしまう
ことが分かる。仮に、プログラムのアルゴリズムの工夫で10倍、CPUの進化で10倍、
クラスタリングすることで10倍速くなったとすると、英大文字小文字だけの8字
パスワードも10日程度で総当たりできてしまう。そしてそれは容易に起こり得る
進化である。あらためて【表 を】の数字を1000〜10000で割った値を想起してみ
てほしい。得られる結論は、

	* パスワードが8文字までのシステムなら英数記号を全て交ぜるべし
	* 9字以上使えるなら少なくとも大文字小文字を交ぜて10字以上にすべし

あたりだろう。暗号化方式にMD5が使えるのであれば、その方が望ましいのはいう
までもない。

■
■パスワード強度の検証
■

以上の数値を見るとなんだか恐くなってくるかもしれない。しかし、実際に行わ
れるパスワードクラック攻撃のほとんどはネットワークごしに行われるので、上
記のものほど高速には進まない。そもそも、現状では暗号化パスワード文字列は
シャドーパスワードに分かれて格納されているシステムがほとんどで、それが読
めるということはroot権限が取れているということにほかならず、パスワードを
解析する意味もないからである。

では、どういうときに危険なのかというと、ネットワークごしに行われる「少し
低速な」攻撃でも破られてしまうほど「弱い」パスワードを付けているユーザが
一人でもいる場合である。仮にそのユーザでログインできれば、そのシステムの
たいていの様子が把握できるので、次の攻撃活動に大きな情報を与えることにな
る。

実際のところ、現在繰り返されているほとんどのパスワードクラック攻撃は、ス
クリプトキディ【註 わ】による悪質な悪戯としてしかけられたものや、ウィル
ス感染PCなどによって自動的に動いているクラッキングツールによるものなので、
「1つのユーザのパスワードをゆっくりと解析」したりせず、放置されやすい典
型的なユーザ名を流して調べていくケースが多い。

---[註 わ]------------------------------------------------------------------
とくに強い動機や高い知識をもって攻撃するわけではなく、
流通しているクラッキングツールを利用して面白半分で攻撃や侵入を繰り返す者達。
----------------------------------------------------------------------------

もし、インターネットに接続していて外部からのSSHログインを許可しているマシ
ンがあれば、認証関係のログを見てみるとよい。FreeBSD/NetBSDであれば
/var/log/auth*log に、FedoraCore では /var/log/secure にSSHログインを試
みた接続のログが書かれている。たとえば、筆者の管理するホストでは【図 か】
のようなログが大量に吐かれている。

---[図 か]------------------------------------------------------------------
Feb 14 01:32:40 firestorm sshd[19141]: Invalid user andrew from 69.110.112.188
Feb 14 01:32:40 firestorm sshd[19141]: Failed password for invalid user andrew from 69.110.112.188 port 58104 ssh2
Feb 14 01:32:44 firestorm sshd[787]: Failed password for root from 69.110.112.188 port 58197 ssh2
Feb 14 01:32:48 firestorm sshd[2559]: Invalid user newsroom from 69.110.112.188
Feb 14 01:32:48 firestorm sshd[2559]: Failed password for invalid user newsroom from 69.110.112.188 port 58301 ssh2
Feb 14 01:32:52 firestorm sshd[218]: Failed password for root from 69.110.112.188 port 58400 ssh2
Feb 14 01:32:56 firestorm sshd[1755]: Invalid user magazine from 69.110.112.188
Feb 14 01:32:56 firestorm sshd[1755]: Failed password for invalid user magazine from 69.110.112.188 port 58507 ssh2
Feb 14 01:33:00 firestorm sshd[5566]: Failed password for root from 69.110.112.188 port 58616 ssh2
Feb 14 01:33:04 firestorm sshd[27823]: Invalid user research from 69.110.112.188
Feb 14 01:33:04 firestorm sshd[27823]: Failed password for invalid user research from 69.110.112.188 port 58716 ssh2
Feb 14 01:33:08 firestorm sshd[6503]: Failed password for root from 69.110.112.188 port 58822 ssh2
Feb 14 01:33:12 firestorm sshd[9719]: Invalid user cjohnson from 69.110.112.188
Feb 14 01:33:13 firestorm sshd[9719]: Failed password for invalid user cjohnson from 69.110.112.188 port 58926 ssh2
Feb 14 01:33:17 firestorm sshd[6334]: Failed password for root from 69.110.112.188 port 59031 ssh2
Feb 14 01:33:21 firestorm sshd[28873]: Invalid user export from 69.110.112.188
   :
   :
----------------------------------------------------------------------------

秒刻みで執拗なパスワードアタックが繰り返されている。よく見ると、rootユー
ザと、ありがちなユーザ名でのログイン試行がある。このようなアタックが長い
ときには4〜5時間続くこともある。この例では欧米人の付けそうなユーザ名での
試行しか見られないが、実際にはローマ字の日本人名による試行も散見される。
もし、利用者の一人でも「甘い」パスワードを付けていたら……と考えると、そ
の先の深刻さは理解できるだろう。

簡単な辞書攻撃、総当たり攻撃で破られてしまうパスワードを持つユーザには、
一刻も早く改善してもらわねばならない。

■
■パスワード強度検証システム
■

システムセキュリティを鑑査するツールはいくつかあるが、今回はユーザのパス
ワードの強度を検証するものに焦点を当てよう。

●COPS

Unixシステムのセキュリティチェックを総合的に行うツールの集合体である。
主なところでは、以下のような検査を行う。

	* ファイル/ディレクトリ/デバイスファイルの属性
	* パスワード強度
	* passwd/group ファイルの整合性/安全性
	* rcファイルやcronジョブ
	* root setuid ファイルの確認
	* 重要ファイルのCRC
	* ユーザのホームディレクトリ/初期化ファイルの属性

どちらかといえばCOPSは既に役割を終えつつある古いツールであり、
最近では各トピックごとに、より高度な検査を行なうツールが出ている。たとえ
ば、重要ファイルの改ざん検査を行なうTripwireなどは有名である。

COPS付属のパスワード強度検査プログラムは比較的簡易なものであるが、逆にそ
れが「あまり深追いしない」という作業の本質にかなっているともいえる。

----[[[コラム COPS付属ツールによる検査]]]-----------------------------

COPSに付属しているパスワードチェッカも簡単に利用できる。shadowパスワード
を利用しているシステムであれば以下のようにして検査ができる。

# sh
# umask 077
# sort /etc/passwd > a
# sort /etc/shadow \
	| awk -F: '$2 != "!!" && $2 != "*"{print}' \
	| join -t : -o 1.1,2.2,1.3,1.4,1.5,1.6,1.7 a - \
	> b
# exit

# cc -O -o pass.chk pass.c -lcrypt
# ./pass.chk -P b -w ./pass.words -b -g -s -c -d -n

pass.chk プログラムはいくつかの起動オプションで挙動を制御できる。

	-v	推測された結果を出力する
	-u	検査中のユーザ名を出力する
	-w file 辞書ファイルとして <file> を利用する
	-b	単語を逆順にしたものも試行する
	-g	gecosフィールドも推測用単語として利用する
	-s	a〜z、A〜Z、0〜9の1字のパスワードも検査する
	-c	全大文字化、全小文字化した単語も試行する
	-d	ユーザ名を2つ続けた単語も試行する
	-n	空パスワードを警告する
	-p	推測されたパスワードを出力する
	-P file	パスワードファイルとして <file> を検査対象とする

これらを組み合わせて利用することで、「ほんとうに推測されやすいパスワード」
の存在を検査できる。
----------------------------------------------------------------------


●Crack

パスワード検査に特化したものがCrackで、様々なロジックを組み合わせて人間が
考えそうなパスワードを推測する。辞書の追加等、色々なカスタマイズが可能な
ので、日本語圏ユーザに対する検証作業もしっかりとできる点が特徴である。

今回はCrackを利用した検証作業例を紹介しよう。


■
■Crackによるパスワード強度の検証
■

まず最初に警告を。

	+------------------------------------------------------
	| パスワード強度検証作業は手順を誤ると、
	|
	| ・予期せぬパスワード漏洩
	| ・内部クラッカー発生の助長
	| ・侵入(試行)者への情報提供
	| ・管理者自身の倫理観崩壊
	| ・作業傍観者の誤解に起因する社会的立場の喪失
	|
	| などを引き起こす可能性がある。必ず事前事後を含めた
	| 手順を遵守して行なってほしい。
	+------------------------------------------------------

パスワード強度検証は、表面的に見ると「パスワード破り」と変わりがない。そ
のため、第三者へのしっかりした事前事後の説明がなければ他者からは区別が付
かない。また、作業中は推測されたパスワードが平文でファイルに書かれること
になるので、危険度も増す。実際に本稼働しているシステムのパスワードファイ
ルに適用するときには事前に利用者や、他の管理責任者に作業予定を目的ととも
に周知し、作業ディレクトリのパーミッションなどに細心の注意を払って進める
よう注意されたい。

●Crack5.0の導入

Crackは「誰でもカンタンに使える」べき性格のものではないので「configure&&
make一発」にはなっていない。基本的にはドキュメント、スクリプト、ソースプ
ログラムに書かれている説明を熟読しながら慎重に作業を進めることになる。

まず、ソースパッケージである crack5.0.tar.gz を入手し、展開する。

  # wget ftp.ring.gr.jp:/pub/NetBSD/packages/distfiles/crack5.0.tar.gz
  # tar zxpf crack5.0.tar.gz
  # cd c50a
  # less manual.txt

manual.txt にはコンパイルと実行までの手順が書いてある。

まず、プログラムのコンパイルが必要なのだが、パスワードファイルのパスワー
ドフィールドがどのアルゴリズムで暗号化されているかによってリンクするライ
ブラリを変える必要がある。アルゴリズムがDESであれば、パッケージ付属の
libdes ライブラリを使うのが良いが、今回想定する FreeBSD/Linux/NetBSD では
MD5もサポートしているので、システム標準の crypt() 関数を使うものとして説
明を進める。manual.txt の279行目付近にMD5ベースのパスワードを処理する場
合に必要な手順が書いてある。manual.txt ではFreeBSDを例に説明してあるが、
Linux(FedoraCore4)もMD5ベースのパスワードなので同様の手順で良い。

libdesを使わないように src/libdes/ のディレクトリ名を変えておく。

	# mv src/libdes{,.unused}

MD5での暗号化文字列も正しい書式と認識するよう、src/util/elcid.c,bsd を
src/util/elcid.c に上書きコピーする。

	# cp src/util/elcid.c{\,bsd,}

次に、システム標準の crypt() 関数を使うようにリンカフラグに -lcrypt を足
す。これは、Crackスクリプトの533行目付近にあるコメントを外すことで定義で
きる。

	# vi +533 Crack

	(533行目付近)
	#LIBS=-lcrypt # uncomment only if necessary ....
	↓
	LIBS=-lcrypt # uncomment only if necessary ....



コンパイルする。コンパイルもCrackスクリプト経由で行なう。

	# ./Crack -makeonly

エラーがなくコンパイルが完了すると、run/bin/<アーキテクチャ名> ディレク
トリの下に実行バイナリができているはずである。正しく libcrypt ライブラリ
がリンクされているか確かめる(DESのみのシステムではこの確認は不要)。

	# ldd run/bin/*/cracker
        linux-gate.so.1 =>  (0x00ccf000)
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x0052e000)  ← これ
        libc.so.6 => /lib/libc.so.6 (0x003ad000)
        /lib/ld-linux.so.2 (0x0038f000)


実行プログラムの次は、辞書を作成する。デフォルトでは英単語用の辞書として、
/usr/dict/words* を探すようになっているが、PC-Unixの多くは
/usr/share/dict/words* となっているので、辞書パス定義ファイルである
./conf/dictgrps.conf を修正する。

	# vi +/1: conf/dictgrps.conf
	(以下のようになっている行を)
	1:/usr/dict/*words* dict/1/*

	(↓以下のように修正する)
	1:/usr/share/dict/*words* dict/1/*

修正後、辞書を作成する。

	# ./Crack -makedict

./run/dict ディレクトリに固有フォーマットに変換された辞書が格納される。

	# ls -l run/dict
	total 3080
	-rw-------  1 yuuji yuuji 1392531 Feb 19 14:04 1.dwg.gz
	-rw-------  1 yuuji yuuji  359527 Feb 19 14:04 2.dwg.gz
	-rw-------  1 yuuji yuuji 1387759 Feb 19 14:04 3.dwg.gz



●パスワードファイル形式の確認と実行


Crackはデフォルトではパスワードファイルのフォーマットとして、
SPF(Standard Password Format)を認識するようになっているが、現在では
/etc/passwd とは別のシャドーパスワードファイルに分かれていることが多い。
その場合は、一時的にSPFに変換したファイルを作成する必要がある。

・Linux(SysV /etc/shadow形式)の場合

/etc/passwd と /etc/shadow を合成してSPFに変換するスクリプトが
./scripts/shadmrg.sv にあるので、これを利用する。

	# umask 077
	# sh scripts/shadmrg.sv |egrep -vw '!!|\*' > hoge

一時ファイルを引数に与えて Crack スクリプトを起動する。

	# ./Crack hoge


・FreeBSD/NetBSDの場合

/etc/master.passwd はSPFを生成するのに十分な情報を包含しているので、
Crackスクリプトに与える引数で、解析プログラム実行時に自動的に変換しなが
ら処理するよう指示する。

	# ./Crack -fmt bsd /etc/master.masswd

これで実行時に master.passwd のエントリを scripts/bsd2spf スクリプトで変
換しながら解析するようになる。


●結果の吟味

./run/ ディレクトリにログが吐かれつつ解析が進む。これを人間に分かりやす
い書式で出力するのが Reporter スクリプトである。

	# ./Reporter


●カスタマイズ(辞書の追加)

Crackは辞書と文字変換ルールを与えることでパスワード検査を行なう。標準で
利用する辞書はOSに付属している英語辞書の他に、Crackパッケージに付いてく
るjargon辞書(dict/1/jargon.dwg)や、日本語辞書(dict/3/words.japanese.dwg)
などがある。文字変換ルールは conf/rules* ファイルにあり、たとえば、「oが
あったら0(ゼロ)に変えてみる」、とか「全部大文字にしてみる」などのルール
が用意されている。

ここでは、利用者の良く使いそうな単語が含まれた辞書を追加する方法を示す。
たとえば、なんらかの辞書がからひらがなの「読み」だけ抜き出したものを用意
する。以下の例はpubdic+(※)に含まれる日本語辞書 kihon.u からの抜き出しを
示したものである。

※ http://www.remus.dti.ne.jp/~endo-h/wnn/

	(例)
	% cut -d ' ' -f 1 kihon.u | sort -u > hiragana.txt

ひらがなをローマ字に直すツールを利用してローマ字辞書にする。以下の例では
KAKASIを利用している。

	% nkf -e hiragana.txt | kakasi -Ha -Ka \
		sed 's/\^/-/g' | sort -u > roman.dic

出来上がった辞書を Crack の辞書情報ファイルに登録する。

	(Crackの作業ディレクトリに移動)
	# vi conf/dictgrps.conf
	(以下のような3行の次に…)
	1:/usr/share/dict/*words* dict/1/*
	2:dict/2/*
	3:dict/3/*

	(以下の内容を追加)
	4:<roman.dicのあるディレクトリ>/roman.dic

最後に、辞書を作り直す。

	# rm -rf run
	# ./Crack -makedict

./run/dict に辞書分類「4」の辞書ができているはずである。

	# ls -l run/dict
	-rw-------  1 yuuji  yuuji   752564 Feb 19 16:01 1.dwg.gz
	-rw-------  1 yuuji  yuuji   427480 Feb 19 16:01 2.dwg.gz
	-rw-------  1 yuuji  yuuji  1250033 Feb 19 16:01 3.dwg.gz
	-rw-------  1 yuuji  yuuji    13177 Feb 19 16:01 4.dwg.gz ←これ

あとは、デフォルト辞書だけのときと同様に Crack スクリプトを起動するだけで
よい。ただし、日本語の一般的な単語はデフォルト辞書に含まれているので、上
記で示したpubdic+の追加ではあまり精度は変わらないだろう。筆者の経験では、
安易なパスワードの代表格は地名で、それが良く含まれているものは鉄道辞書で
あった。


■
■推測されたパスワードがあった場合の対処
■

「甘い」パスワードを付けていたユーザが見つかった場合、管理者としてはすぐ
に改善するよう連絡をしたくなる。しかし、安易に連絡しては却って危険で、そ
のアカウントに対して電子メールを送るなどもってのほかである。もしかしたら、
甘いパスワードが侵入者によって既に破られている危険性もある。もしそうだと
したら、侵入者に対して「パスワードを変えて下さい」と親切に教えることにな
り、笑い話にもならない。

また、甘いパスワードにしているユーザは、滅多にログインしないか、使わなく
なったアカウントであることも多く、電子メールを送ること自体が有効な連絡手
段とならないこともある。推測されたパスワードが見つかった場合は、以下のよ
うに対処する。

	・直接会うか、電話など別手段で連絡する
	・システムとは別のメイルアカウントに送る

上記いずれでもダメなら、じっと待つしかない。もしログインできなくなって本
当に困ったら本人から連絡が来るはずである。アカウントのロックと解除をする
には以下のようにする。

  (1)アカウントのロック
  vipw などパスワードファイルを直接編集するためのユーティリティを起動し、
  元々あるパスワードフィールドに余計な文字(*)を追加する。

	# vipw
	(マスターパスワードファイルを開く)
	(例えば以下のようなエントリの場合)
	taro:$1$xxx$uKStHT7az8bAkhzbLDrJ00:2000:10::0:0::/home/taro:/bin/zsh

	(*を追加する)
	taro:*$1$xxx$uKStHT7az8bAkhzbLDrJ00:2000:10::0:0::/home/taro:/bin/zsh

  (2)解除
  すぐ横に来てもらってパスワードを変えてもらうのが望ましいが、それができ
  ない場合も多い。電話や別アカウントのメイルなどで直ちにパスワードを変
  更できる状態であることを確認後、パスワードフィールドを元に戻し、すぐロ
  グインして変えてもらう。


管理者が新しい仮パスワードを勝手に付けてしまうのも一つの方法だが、それを
安全に伝える手段の確保が難しい。


■
■良いパスワードの付け方
■

「安易すぎるのでパスワードを変えて下さい」といっても、どういう風に変えれ
ばよいのか伝えなければ、また安易なパスワードを付けられてしまう。良いパス
ワードとは、推測されにくい、つまり辞書攻撃にも総当たり攻撃にも強いパスワー
ドのことで、

	* 大文字小文字、記号の混在したもの
	* 10字程度以上のもの

である、なお、読者が一般ユーザだとして、利用しているシステムが8字を超える
パスワードを区別するか良く分からない場合は、仮に8字までのシステムである可
能性を考えて記号を含めるなら8字以内に登場するようにする。

これらの性質を考えると、「パスワード発生器」によってランダムなものを作っ
てもらうのが一番安全なものが作れるのだが、本当にランダムだと、ユーザは覚
えていられずどこかにメモを取ったりするようになる。それでは却って危険であ
る。もう一つの「良いパスワードの条件」として

	* 覚えやすいものにする

がある。「日本人しか分からない」、「自分だけしか分からない」規則で生成す
ると比較的安全である。

●覚えやすく推測されにくいパスワードの考え方

色々な方法が考えられるが、参考までに以下のような方法を試してみてほしい。

	(1)自分しか知らない短文を考える
	「俺の隼は一番だぜ!」

	(2)日本語の段階で省略形にしてみる
	「俺ブサは一番!」

	(3)ローマ字に直す
	「Orebusa ha 1ban!」

	(4)10字程度になるよう適当に間引く
	「ORbs ha1ban!」

	(5)ごろ合せなどで途中の文字を数字などに変えてみる
	「OR2s 1ban!」

	(6)区切りを適当な記号に変えてみる
	「OR2s,1ban!」

考えたものは、実際にタイプしてみて素早くタイプできるか確認してみる。左右
の指がなるべく順番に動くように文字列を工夫すると打ちやすいパスワードが生
成できる。

■
■パスワード漏洩の危険性
■

どんなに注意深く覚えやすく・安全なパスワードを考えても、利用時の心構えが
低ければ、身近なところから漏洩する危険性が潜んでいる。例えば利用中の端末
を離れると、既に起動しているアプリケーションから漏洩する可能性もある。

●アプリケーションに覚えさせるな!

コンピュータを利用していると様々なところでパスワードを入力する機会がある。
面倒だ。ところが、アプリケーションによっては「パスワードを記憶する」機能
がある。便利だ。だが、実際にアプリケーションにパスワードを覚えさせた状態
で、誰かにその使用中マシンを触られたらどのようになるだろうか。

例として起動中Emacsにシグナルを送ってアボートさせたときにできるコアダンプ
ファイルの中を見た様子を【図 よ】に示す。michadameyon! の部分がパスワード
で、ばっちりと目で見てすぐ探せる形で見えてしまう。

---[図 よ]------------------------------------------------------------------
APOP password (yuuji@pop.gentei.org): ...........
............
%s%s
APOP password (yuuji@pop.gentei.org): ............
 p      
michadameyon!
     
.............
%s%s
...
APOP password (yuuji@pop.gentei.org): .............
chop
<4cf0.43f83375@pop.gentei.org>michadameyon!
----------------------------------------------------------------------------

もし、自分の利用しているアプリケーションがメモリ中にパスワードを保持して
いるか気になる場合は、

	% ulimit -c unlimited (sh/bashの場合)
	あるいは
	% unlimit coredumpsize (csh/tcsh/zshの場合)

としたあとで、アプリケーションを起動し、パスワードを入力してみる。その状
態で kill -QUIT あるいは kill -ABRT で落としてできたコアダンプファイルを
stringsコマンドで見てみよう。

	% strings <コアダンプファイル> | less

ほとんどの場合平文パスワードが見つかるはずである。すぐにコアダンプファイ
ルを消そう。

	% /bin/rm <コアダンプファイル>


●Emacsへのパスワード入力は特に危険

たとえば、OpenSSHのようなセキュリティを最重視して書かれたものはメモリダン
プからの漏洩の危険性を極限まで回避している【註 た】が、そうでない一般のア
プリケーションではその点において無防備である。メールパスワードのように知
られてもメールが読まれるだけの被害にとどまる【註 れ】ものはアプリケーショ
ンに覚えさせても構わないだろうが、ログインパスワードなどは漏洩による被害
が他人にも及ぶため、決して一般アプリケーションに覚えさせてはいけない。そ
してたいていの場合アプリケーションに覚えさせなくてもタイプするだけでもメ
モリに痕跡が残り、きわめて危険であることに留意してほしい【註 そ】。

たとえばEmacsの中でログインパスワードを入力した場合、ほとんどがメモリ中に
居座ることになる。【リスト つ】は eshell.el のパスワード入力関数だが読み
込んだパスワードを一時変数 str に入れてそのまま放置している。ここではたま
たま eshell を例に挙げたのだが、少し調べた範囲ではその他のEmacs-Lispプロ
グラムも「メモリに残るパスワード」のことは全く気にしていないものがほとん
どであった。

---[リスト つ]--------------------------------------------------------------
(defun eshell-send-invisible (str)
  "Read a string without echoing.
Then send it to the process running in the current buffer."
  (interactive "P")                     ; Defeat snooping via C-x ESC
  ESC
  (let ((str (read-passwd
              (format "%s Password: "
                      (process-name (eshell-interactive-process))))))
    (if (stringp str)
        (process-send-string (eshell-interactive-process)
                             (concat str "\n"))
      (message "Warning: text will be echoed"))))
----------------------------------------------------------------------------

---[註 た]------------------------------------------------------------------
興味があれば ssh-agent のソースなどを見てみると良いだろう。コアダンプを
作らせないためのコードがある。
----------------------------------------------------------------------------

---[註 れ]------------------------------------------------------------------
最近ではメールパスワードはチャレンジ&レスポンス方式にしてログインパ
スワードとは分離することが多い。
----------------------------------------------------------------------------

---[註 そ]------------------------------------------------------------------
プログラムから使用するメモリ内容の暗号化を行なうものもある。詳しくは
文献[2]を参照のこと。
----------------------------------------------------------------------------

特にEmacsは起動中常にインタプリタを動かしていることになるので、変数などに
保存された値をエンドユーザが簡単に取り出して「見る」ことができる。もちろ
んパスワードも例外ではない。筆者自身はEmacs-Lispを理解できるようになって
からは、Emacsで動くフロントエンドプログラムに重要なパスワードを入力するこ
とは決してしなくなった。簡単に取り出されることが分かってしまったからだ。

Emacs以外の場合でも、フロントエンドとしてパスワード入力を行なうようなアプ
リケーションを利用する場合は、作業中の端末が絶対に第三者には触れられない
ように最大限注意すべきである。


●ラップトップPCの固有の危険

メモリダンプは使用者本人がログイン中のところを横取りされなければ取られに
くいかもしれない。しかし、ラップトップPCは「盗難に遭いやすい」以外にさら
に危険がある。ハイバネーション領域である。最近でこそハイバネーション領域、
あるいはディスク全域を暗号化する機種が増えてきたがまだまだ高価だ。

何かのアプリケーションに重要なパスワードを一度でも入力した場合はハイバネー
ションを利用せず、シャットダウンして全て消し去る方が安全だろう。

●スワップ領域の危険

コアダンプが発生しなくても、メモリの内容がハードディスクに書かれることが
ある。スワップ領域である。スワップ領域に書かれた内容は、次回上書きされる
まで残るので、取り外したHDDのスワップ領域を見られたら過去にしていた作業
が分かってしまう。

もっとも、この対策は比較的簡単で、Part2で説明した暗号化ディスクドライバで
確保した領域をスワップに割り当てればよい。あるいは、暗号化パーティション
に確保したファイルをswaponコマンドでスワップとして利用させればよいだけで
ある。



■
■まとめ
■

トイレに頑丈なシリンダ錠は必要ない。鍵をかけていることが分かるだけで十分
だからである。いっぽう金庫には厳重な鍵が付いている。そしてその鍵をすぐに
分かる場所に置いたりはしない。日常生活では鍵の持つ価値の「重み」を使い分
けているが、パスワードはどうだろう。全て同じ席に座りながら入力するだけな
ので、重いパスワードも軽いパスワードも同じように気軽にパスワードキャッシュ
に任せていないだろうか。

	・メモリの内容がディスクに書き込まれることは普通に起こり得ること
	・プログラミングやOSの知識が少しでもあれば簡単に様々な値を取り
	  出せる可能性がある

という性質を理解し、「重い」パスワードを「防御の弱いアプリケーション」に
入力しないように気をつけることも重要である。どんな言語でもいいので一度で
も「パスワード入力処理を受け持つプログラム」を作ってみると、相当気をつけ
なければパスワードがいとも簡単に丸裸状態になることが実感できるだろう。

また、自分がどんなに気をつけていても、同一サイト内に甘いログインパスワー
ドを付けている人がいたらそのアカウントを拠点に様々な情報を盗まれ、最終的
にあらゆる情報を盗まれてしまうこともあり得る。

Part2で解説した対策を含め、システム側とユーザの意識の両面から情報漏洩対
策を進めていってほしい。


---[図 ね]------------------------------------------------------------------
----------------------------------------------------------------------------
---[図 な]------------------------------------------------------------------
----------------------------------------------------------------------------
---[図 ら]------------------------------------------------------------------
----------------------------------------------------------------------------


■
■参考文献
■
[1] http://eprint.iacr.org/2004/199.pdf

[2] 稲村雄、本郷節之: 暗号技術によるメモリデータ保護方式の提案、
    情報処理学会論文誌 Vol 45, No.8 pp1823-1832


yuuji@gentei.org
Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA
HIROSE Yuuji - ASTROLOGY / BIKE / EPO / GUEST BOOK / YaTeX [Tweet]