私がこれをやっているとしましょう:
#!/bin/bash
content="foo"
pass="secret-password"
echo $content | ccrypt -f -k <(echo -n $pass)
プロセス代替ファイルに設定されている権限を信頼して、/dev/fd/*
その期間中にパスワードを安全に保つことはできますかccrypt
?
答え1
分析してみましょう。
content=$(cat -)
これはと同じですcontent=$(cat)
。使用されるものコマンドの置き換えパイプを使用bash
します。パイプの一端には、cat
標準入力から読み取った内容が記録されます。bash
もう一方の端はそれを読んで$content
。
ただし、その前に末尾の改行文字を削除し、NUL文字のブロックも削除します。任意のデータを変数に保存できるようにするには使用できず、次の操作をbash
実行する必要があります。zsh
content=$(cat; echo .); content=${content%.}
改行除去の問題を解決します。
保存するデータは、$content
スクリプトの標準入力を介して入力されます。これは(Linuxでは)パイプにコピーされるため、でも/proc/pid-of-your-script/fd/0
使用できます。/proc/pid-of-cat/fd/0
cat
bash
/proc/pid-of-cat/fd/1
/proc/pid-of-script/fd/fd-to-the-other-end-of-the-pipe
とにかくコンテンツは一度だけ使用されるため、$content
中間ステップを実行する必要はありません。
pass=$1
ここであなたは秘密について話しています鍵スクリプトの最初のパラメータから取得します。
秘密データをコマンドライン引数として渡すことはできません。コマンドラインパラメータは秘密ではありません。の出力に表示されますps -efwww
。 Linuxでは、/proc/pid/cmdline
そのファイルを含むファイルを誰でも読むことができます。デフォルトでは、Linuxでは/proc/pid
管理上同じeuidを持つプロセスにアクセスを制限できますが、動作やps
その他の問題に影響を与えるため、ほとんど実行されません。
一部のシステムでは、一部のプロセスアカウント/監査メカニズムを介して記録することもできます。
echo $content
エラーにはいくつかの理由があります。
echo
任意のデータと一緒に使用することはできません。環境によっては、...などの-n
引数やバックスラッシュなどの項目では正しく機能しません。-neneneene
- 引用符がない場合は、
$content
不要な分割+glob演算子を呼び出すことを意味し、ワイルドカード文字を$content
含めると$IFS
問題が発生する可能性があります。 - 追加の改行文字を追加します。
あなたが望むもの:
printf %s "$content"
そして、末尾の改行文字が早く削除されないようにしてください。
パイプの一部であるため、printf
子プロセスで実行され、標準出力はパイプになります。 Linuxでは、/proc/pid-of-that-child-process/fd/1
コンテンツへのアクセスが許可されます。そうだろう/proc/pid-of-ccript/0
。
存在する
ccrypt -f -k <(echo -n $pass)
echo
と引用されていない質問が再び発生します$pass
。
echo
(サブプロセスで再実行)パイプにパスワードを書き込みます。パイプのもう一方の端は fd で使用できます。Nとccrypt
銀やなどに<(...)
拡張されます。ファイルを開き(新しいfdで)、そのファイル(Linuxで)を再利用できます。/dev/fd/n
/proc/self/fd/n
ccrypt
/proc/pid-of-ccrypt/fd/that-fd
/proc/pid-of-ccrypt/fd/n
/proc/pid-of-echo/fd/1
コードの主な問題は、プロセス置換や他のパイプではなく、パスワードがコマンド(ここではスクリプト)のコマンドライン引数として提供されるという事実です。
プロセス置換には、$(...)
コマンド置換と|
。/dev/fd/x
ただし、同じeuid(またはルート)で実行されている他のプロセスは、とにかくそのプロセスのメモリを読み取り(デバッガが実行するように)そのパスワードを回復することができます(または同じソースからパスワードを取得することもできます)。
Linuxにはシンボリックリンクとダイナミックシンボリックリンク/dev/fd
があります。デフォルトでは、同じeuidを持つプロセスは読み取ることができます(より多くの制限が追加される可能性がありますが、プロセスにデバッガを接続できる人を制限するのと同じです)。/proc/self/fd
/proc/self
/proc/the-pid
/proc/pid/fd
パイプを指すfdの場合、/proc/pid/fd/that-fd
名前付きパイプのように動作します。したがって、他のプロセス(再度同じeuidまたはrootとして実行)がパイプの内容を盗む可能性があります。しかし、とにかくそれを行うことができれば、プロセスメモリの内容を直接読み取ることもできるので、これを防止しようとする必要はありません。
コマンドラインからパスワードを渡すのではなく、環境変数を介してパスワードを渡すことができます。環境はパラメータリストよりもプライベートです。 Linuxでは、/proc/pid/environ
同じeuid(またはeuid)を持つroot
プロセスでのみ読み取ることができます。
したがって、スクリプトは次のようになります。
#! /bin/sh -
exec ccrypt -f -E PASSWORD
そして電話してください
PASSWORD=secret-phrase the-script < data-to-encrypt