2019 年度 OSS リテラシー 3 : Linux におけるパスワード管理
パスワードの保管方法
登録されたユーザ情報は, /etc/passwd と /etc/shadow に登録される. /etc/shadow に暗号化されたパスワードが, それ以外の情報は /etc/passwd に 書かれる.
これらのファイルを確認してみよう. grep コマンドを使うことで, 第一引数に 与えた文字列が含まれている行だけを抜き出すことができる.
$ sudo -s # less /etc/passwd ...(略)... # grep hogehoge /etc/passwd hogehoge:x:1001:1001:SUGIYAMA Ko-ichiro,,,:/home/hogehoge:/bin/bash # less /etc/shadow ...(略)... # grep hogehoge /etc/shadow hogehoge:$6$AAAAAA$XXXXXXXXXXXXXXXXXXXXXXXXX:17439:0:99999:7::: # less /etc/group ...(略)... # grep hogehoge /etc/group hogehoge:x:1001:
/etc/shadow はパスワード情報が含まれているので, 一般ユーザには読めない ファイルパーミッションになっている. /etc/passwd や /etc/group は一般ユー ザでも読める.
# ls -l /etc/passwd /etc/group /etc/shadow -rw-r--r-- 1 root root 814 10月 19 09:33 /etc/group -rw-r--r-- 1 root root 1718 10月 19 09:34 /etc/passwd -rw-r----- 1 root shadow 1097 10月 19 09:33 /etc/shadow # exit $
パスワードの暗号化に対する理解を深める
/etc/shadow に保存されている暗号化されたパスワードに対する理解を深めよう. /etc/shadow の 1 行 1 行は : (コロン) 区切りのフィールドに分けられているが, この第 2 フィールドにパスワードのハッシュとソルトが保管されている.
# grep hogehoge /etc/shadow hogehoge:$6$AAAAAA$XXXXXXXXXXXXXXXXXXXXXXXXX:17439:0:99999:7:::
第 2 フィールドだけ取り出すと
$6$AAAAAA$XXXXXXXXXXXXXXXXXXXXXXXXX
であるが, このフィールドはさらに $ 区切りのフィールドに分かれていることが分かる. $ 区切りのフィールドにはそれぞれ意味があり,
6 : ハッシュを求めるのに SHA-512 (一方向ハッシュ関数) を使用していることを示す AAAAAA: ソルト (ランダムに決められた文字列) XXXXXXXXXXXXXXXX : パスワードのハッシュ
である. 文字列を SHA-512 (一方向ハッシュ関数) でハッシュ化することはターミナル上で簡単に行える. 例えば "hogehoge" という文字列を AAAAAA というソルトを使って SHA-512 でハッシュ化するには以下のように実行すれば良い. 引数として, "$6$AAAAAA" というように「$6$ + ソルト」を与えることに注意せよ.
$ ruby -e 'p "herohero".crypt("$6$AAAAAA")' "$6$AAAAAA$WN3XG2F1dWl1l5rnj5WVge2NEh3MW7e2YeX.kzSDLcNW9krIckh7UyAamSdbyHEDCDr7QGiN00/35Kz882Abn0"
ハッシュ化のアルゴリズムとソルトが同じなら, 同じハッシュ値が得られる. そのため, /etc/shadow が外部に流出するとクラッカーの餌食となってしまう.
課題
- 以下のファイルの書式を wbt のオンラインテキストにまとめよ.
- /etc/passwd
- /etc/group
- /etc/shadow
- /etc/sudoers
- "%sudo ALL=(ALL:ALL) ALL" という記述があるが, 各 ALL の意味を調べなさい.
- 自分のパスワードを前述の方法でハッシュ化してみよ. その際, ソルトは自分のラズパイの
/etc/shadow から得ること. コマンドライン上で得られたハッシュと /etc/shadow に保存
されたハッシュが一致することを確認せよ.
- パスワードがからむので wbt には何も提出しなくて良いが必ず行うこと.
作業後, 必ず history コマンドで履歴を消去すること. history コマンドを実行すると今までに打ったコマンドが通し番号付きで表示される. history コマンドに -d オプションで通し番号を与えると, 履歴を消すことができる. なお, コマンド履歴は ~/.bash_history ファイルに記録されているので, 直接ファイルを編集して該当行を削除しても良い.
$ history ...(中略)... NN ruby -e 'p "herohero".crypt("$6$AAAAAA")' (NN は通し番号) ...(攻略)... $ history -d NN (NN は smbencrypt の通し番号) $ histoty ...(略).... (コマンド履歴が消去されたことを確認)