2017-10-31 1 views
0

私は複数の議論で、プロセスリストからエコーするための引数を得ることができるので、passwdへのecho to pipeの使用は危険です。passwdにパイプ経由でパスワードをエコーするのはどれほど危険なのですか?

私は現在、sshを使用してパスワードをリモートから変更するツールを開発中です。私はusermodまたはchpasswdを使うためのルートアクセス権がないのでechoメソッドを使用します。

CMD:

echo -e 'old\nnew\nnew' | passwd 

はそれがいかに簡単かを確認するには - 私が試してみました。しかし、それらを得ることができませんでした。私は数回エコー経由でパスワードを変更したが、何も見えませんでした

#!/bin/bash 
filename=$1 

while true 
do 
    echo "$(pgrep -af passwd)" >> "$filename" 
    sleep 0.1 
done 

これは私の方法でした。私は睡眠0.1が問題かもしれないと思います。

これはプロセスリストから取得するのが簡単なので、この方法ではどのように使用するのが安全でないかです。

+0

他人*のパスワードを変更するには、root権限が必要です。端末の代わりに標準入力からデータを取得しても、それは変更されません。 – chepner

+0

それは動作します。やってみて。 – scagbackbone

答えて

2

使用しているシェルにechoが組み込まれているか、外部バイナリ(/ bin/echo)を使用しているかによって異なります。それが外部バイナリの場合、それはサブプロセスとして実行され、その引数リストにパスワードが明示的に表示されます(pspgrepなどを介して)。それが組み込みの場合、パイプラインのechoコマンドはサブプロセスとして実行されますが、親シェルと同じ表示引数リストを持つサブシェルになります(安全です)。

だから、おそらくですが、心配するいくつかの合併症があります。まず、ssh経由でリモートコンピュータでこれを実行している場合、そのデフォルトシェルが何であるか必ずしも知っているとは限りません。それがbashなら、あなたは大丈夫です。それがダッシュの場合、私はあなたに問題があると思う。次に、リモートシェルやechoコマンドについて心配する必要はありません。ローカルスクリプトからリモートのechoコマンドまでのすべてのステップについて心配する必要があります。あなたが使用している場合たとえば、:

ssh [email protected] "echo -e 'old\nnew\nnew' | passwd" 

を...リモートechoはおそらく(リモートシェルに応じて)安全ですが、@thatotherguyが指摘するように、パスワードは、リモートシェルの両方に表示されます(bash -c echo -e 'foo\nbar\nbar' | passwdsshプロセスの引数リストにがあります。

別の複雑さがあります:echoは、(-eのような)オプションの処理方法と出力文字列のエスケープ方法について一貫していません(例についてはthis questionを参照してください)。 printf(例:printf '%s\n' "$oldpass" "$newpass" "$newpass")を使用するほうがはるかに優れています。これはbashの組み込み関数です。あるいは、あなたがbashを使っていると確信が持てるなら、here-string(<<<string)を代わりに使うことができます。それは全くのエスケープを解釈することはありませんが、あなたはそれを解釈するためにはbashの$' '構文を使用することができます。

passwd <<<"$old"$'\n'"$new"$'\n'"$new" 

これは、すべての(/bin/echoのいずれかまたはサブシェル)でサブプロセスを伴わないので、プロセスの心配はありません表。

不確かなリモートシェルの問題とsshに現れてパスワードの両方を回避する別の可能性の標準入力の引数リストがssh経由でパスワードを渡すことです ':

ssh [email protected] passwd <<<"$old"$'\n'"$new"$'\n'"$new" 
3

あなたを起動した場合ssh、例えば経てecho|passwdコマンド:

client$ ssh example.com "echo -e 'foo\nbar\nbar' | passwd" 

、あなたが見てする必要があるプロセスがpasswdではなく、ユーザのログインシェルがレモにsshdによって呼び出さ側:

server$ until pgrep -af bash | grep passwd; do true; done 
8387 bash -c echo -e 'foo\nbar\nbar' | passwd 
+0

良い点;私は私の答えでそれを逃した。 –

関連する問題