読み取りを使用して入力したパスワードをスニッフィングし、コマンドライン引数として渡します。

読み取りを使用して入力したパスワードをスニッフィングし、コマンドライン引数として渡します。

パスワードを入力して表示したいです。read安全感はありません。

これを反現実的なシナリオに含めるために、ユーザーにパスワードの入力を求めるメッセージを表示し、7z1に次のコマンドを使用して暗号化されたアーカイブを作成させるとします。

read -s -p "Enter password: " pass && 7z a test_file.zip test_file -p"$pass"; unset pass

パスワードを漏らす最初の試みは、以下を設定することでした。審査ルール:

auditctl -a always,exit -F path=/bin/7z -F perm=x

もちろんread、andに関連するコマンドを実行すると、7z実行中にログエントリが表示されますausearch -f /bin/7z

time->Thu Jan 23 18:37:06 2020
type=PROCTITLE msg=audit(1579801026.734:2688): proctitle=2F62696E2F7368002F7573722F62696E2F377A006100746573745F66696C652E7A697000746573745F66696C65002D7074686973206973207665727920736563726574
type=PATH msg=audit(1579801026.734:2688): item=2 name="/lib64/ld-linux-x86-64.so.2" inode=1969104 dev=08:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=PATH msg=audit(1579801026.734:2688): item=1 name="/bin/sh" inode=1972625 dev=08:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=PATH msg=audit(1579801026.734:2688): item=0 name="/usr/bin/7z" inode=1998961 dev=08:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=CWD msg=audit(1579801026.734:2688): cwd="/home/mb/experiments"
type=EXECVE msg=audit(1579801026.734:2688): argc=6 a0="/bin/sh" a1="/usr/bin/7z" a2="a" a3="test_file.zip" a4="test_file" a5=2D7074686973206973207665727920736563726574
type=SYSCALL msg=audit(1579801026.734:2688): arch=c000003e syscall=59 success=yes exit=0 a0=563aa2479290 a1=563aa247d040 a2=563aa247fe10 a3=8 items=3 ppid=2690563 pid=2690868 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts17 ses=1 comm="7z" exe="/usr/bin/bash" key=(null)

このラインが最も有望に見えます。

type=EXECVE msg=audit(1579801026.734:2688): argc=6 a0="/bin/sh" a1="/usr/bin/7z" a2="a" a3="test_file.zip" a4="test_file" a5=2D7074686973206973207665727920736563726574

しかし、その文字列は2D7074686973206973207665727920736563726574私が入力したパスワードではありません。

私の質問は2つあります。

  • auditパスワードを取得するのに適したツールですか?それでは、仲裁規則を変更する必要がありますか?
  • auditこの他にパスワードを簡単に知る方法はありますか?

17zが自分でパスワードを求めるメッセージを表示できることを知っています

答え1

read(2)安全ではないのは、ファイルからデータを読み取るシステムコールではありません。そうではありませんread(1)(組み込みシェルは標準入力から1行を読みます)。安全ではないのは、コマンドラインにパスワードを渡すことです。

ユーザーがシェルが読み取るコンテンツを入力すると、そのreadコンテンツが端末とシェルの両方に表示されます。他のユーザーには見えません。使用中はread -sショルダーサーファーには見えません。

コマンドラインに渡された文字列は監査ログに表示されます。 (文字列が切り捨てられる可能性がありますが、わかりませんが、そうであれば、パスワードよりもはるかに長い文字列になります。)スペースなどの文字が含まれている場合は、hexでエンコードされます。構文解析が不明なログです。

$ echo 2D7074686973206973207665727920736563726574 | xxd -r -p; echo
-pthis is very secret
$ perl -l -e 'print pack "H*", @ARGV' 2D7074686973206973207665727920736563726574
-pthis is very secret

これがコマンドラインから秘密を伝えてはならない主な理由ではありません。最終的に、監査ログは管理者だけが表示できるはずであり、管理者は必要に応じてすべてを表示できます。ただし、ログに秘密を維持することは、より多くの人が後でアクセスする可能性があるため(たとえば、不適切なセキュリティバックアップを介して)悪くなります。

コマンドラインから秘密を渡すべきではない主な理由は、ほとんどのシステムでコマンドラインが他のユーザーにも表示されるためです。 (一部強化されたシステムはそうではありませんが、通常デフォルトではありません。ps) 7zプログラムは開始直後(内部コピーを作成できるようになると)パスワードを上書きしますが、これは危険期間を短縮するだけで脆弱性を排除しません。topcat /proc/*/cmdline

環境変数に秘密を渡すのは安全です。その環境は他のユーザーには表示されません。しかし、7zはこれをサポートしていないと思います。コマンドラインで表示されずにパスワードを渡すには、パスワードを入力として渡し、7zがstdin以外の端末から読み取る必要があります。あなたはそれを使用することができますexpectこれを行う(または予想されるTCLよりもPythonを好む場合、または午後の予想Perlで、またはexpectルビーなど)。テストされていません:

read -s -p "Enter password: " pass
pass=$pass expect \
    -c 'spawn 7z a -p test_file.zip test_file' \
    -c 'expect "assword:" {send $::env(pass)}' \
    -c 'expect eof' -c 'catch wait result'
unset pass

関連情報