passwdの改変とか

最初に
管理者なら利用者のパスワードを取得する機会があるはず.
もしパスワードの使い回しとかしてたらとても危険なことになる.
では,管理者が利用者のパスワードを取得するにはどのような方法がある?

具体的な方法
いくつかの方法が考えられるが,基本的には入力された時点でパスワードを取得するのが一番楽かもしれない.以下にいくつかの方法を示す.
1.passwdやshadowファイルの解析を行う.
shadowファイルの閲覧にはrootが必要だが,手に入ればJohn the Ripperなどのツールを使って解析を行うことが可能となる.この方法はシステムに変更を加えることなく試すことができる.
2.passwdコマンドの改変
passwdを改変し,入力されたパスワードをファイルに保存する.passwdのソースコードを読む必要があり,少し面倒.また,passwdコマンドを使う頻度は少ないため,おそらく初回しか効果を発揮しない.
3.sudoコマンドの改変
利用者sudoersに入っている場合のみ使用可能.入力されたパスワードをファイルに保存し,あわよくば他のサービスのパスワードが獲れるかもしれない?人によって使用頻度が異なる点が欠点.
4.sshコマンドの改変
最も多くの機会がある方法.ソースコードを読む必要がある.サーバは基本的にリモートログインで使用するため最も確実な方法.
 
方法の選定
今回は 2.passwdコマンドの改変 を試してみることとする.理由としてはpasswd,shadowファイルの解析はパスワードの長さにより解析にかかる時間が変動すること,他のコマンドと比較して小規模なコマンドなためである.
 
実験環境
仮想マシン上にCentOS7を入れて実験を行った.
以下に環境を示す.
[ホスト]
OS:Windows 10 Education
プロセッサ:Intel Corei7-3632QM
実装メモリ:16.0[GB]
[ゲスト]
仮想化ソフト:Virtual Box 5.1.18
OS:CentOS Linux release 7.3.1611 (Core)
 
実験
wget,gcc,vim,yumdownloader,bzip2を入れる

 
passwdのソース付きパッケージをダウンロードする

 
パッケージの展開を行う

 
$HOME/rpmbuild/SOURCESにpasswd-0.79.tar.bz2とpasswd-0.79-translation-updates.patchとが展開されるので,tar.bz2を伸長する.

 
伸長したディレクトリの中にpasswd.cというファイルがあるので読み進めていく.読み進めた結果,パスワードの設定はPAMに丸投げしていることがわかった.

 
Linux-PAMとはLinuxにおける認証や暗号化を行うシステムである.これにより認証を共通化することでアプリケーション毎に認証機構を作成する必要がなくなる.公式サイトはLinux-PAMで,ソースはここにある.
また,Githubにも最新版のソースコードがある.ただしGithubのコードを使う場合autoconfなどを使って自分でconfigureを生成する必要があるなど,少し手間が増える.
そのため,今回は公式サイトからソースを落とすこととした.
 
Linux-PAMのソースを落とし,展開し,とりあえずコンパイルしてインストール.

 
無事に終了したらソースコードを読み進める.読み進めていくとpasswd.cに書いてあったpam_start関数はPAMのハンドラに登録するものであることがわかった.ハンドラの流れを辿るのは面倒なので,passwordなどで検索を行いながら読み進めていくと,pam_get_authtok.cのpam_get_authtok(pam_get_authtok_internal)関数とpam_get_authtok_verify関数が怪しいと分かった.
以下にそれぞれの関数を示す.
 

 

それぞれハイライトした部分は1回目のパスワードと2回目のパスワードを比較している.ただし,passwdコマンドを普通に実行した場合はpam_get_authtok_internal関数のif文は通らず,パスワードは1回目しか読み込んでいないことがわかった.一方で,pam_get_authtok_verify関数のif文では1回目と2回目のパスワードを比較していることが分かった.なお,確認にはif文の前にprintf関数を置いて出力されるかどうかを確認した.
 
pam_get_authtok_verify関数のif文の前では1回目と2回目に打ち込んだパスワードがそれぞれ*authtok,とrespとに平文で保存されていることがわかった.あとはこれをファイルに保存する.ファイルの保存はpam_get_authtok_verify関数の34行目に以下のようなコードを挿入することで行うことができる.なお,ファイルの先頭にはstdio.hとstdlib.hのインクルードが必要.

これにより
ユーザ名,1回目に打ち込んだパス,2回目のパス
というCSV形式でパスワードが保存される.
(先にファイルを作ってパーミッションを緩くしないとファイルに書き込まれないという問題ができたけど気にしない気にしない)
 
考察
実験から管理者であればパスワードを取得する機会があることがわかった.また,今回実験した方法以外にも様々な手法が考えられる.
最も簡単な対策としては,システムによってパスワードを変えることである.コマンドに対してはコマンドやシステムのハッシュを比較するなどの対策が考えられるが,これは攻撃に対する対症療法のようなもので,根本的な解決にはならない.
変なシステムは警戒して,できるだけ情報を渡さないように心がけよう….
 
参考文献
こうきん,”CentOSでRPMのソースを取得する”,http://kohkimakimoto.hatenablog.com/entry/2012/03/18/071637,2017/06/01閲覧
Linux-PAM,”A Linux-PAM pages”,http://www.linux-pam.org/,2017/06/02閲覧