プロセス交換時の機密データ

プロセス交換時の機密データ

私がこれをやっているとしましょう:

#!/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/0catbash/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 で使用できます。Nccrypt銀やなどに<(...)拡張されます。ファイルを開き(新しいfdで)、そのファイル(Linuxで)を再利用できます。/dev/fd/n/proc/self/fd/nccrypt/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 

関連情報