
私が理解したのは、環境変数に保存される情報を誰でも提供できるようにするのが一般的に安全であると見なされます。 Shellshockの脆弱性は、新しいbashインスタンスの起動時に環境変数内の関数定義の末尾にあるコードが実行され、明らかに誰も実行できなくなるために問題になります。あなたのサーバーで彼らが好きなコードは何でも。関数定義自体は明らかにセキュリティリスクを示さず、コードを実行するには明示的に呼び出す必要があるため許可されます。
私の質問は、なぜ悪意のあるユーザーが単に関数を定義し、悪意のあるコードを一般的なコマンドとして含めた後、スクリプトls
(または実行中のすべての項目)がある時点でこのコマンドを使用したくないのですか?
私の考えの例:
$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...
答え1
これはセキュリティリスクです。これが通常、別のコンテキストに切り替えると(システムリモコン、ユーザー変更など)、これを行うことができない理由です。
必要な環境変数を生成できる場合は、任意のコードを実行する方法はいくつかあります。たとえば。
$LD_PRELOAD
その変数を設定できる場合は、ライブラリ関数を置き換えてコードをここに貼り付けることができます。この変数を設定$DISPLAY
し、プログラムが接続されているXディスプレイをリダイレクトしてアプリケーションを制御できます。
sudo
そのため、すべての変数の環境を削除したいのです。sudo
選択した変数はいくつか通過できます。これらの変数の場合、その変数を削除します(変数を渡します$TERM
が、異常な文字が含まれている場合は渡しません)。
答え2
私が言いたいのは、bashが/ bin / shのときです。これはBourneシェルの機能ではなく、Posixシェルの機能ではありません。実際、彼らはおそらくこの機能を明示的に無効にしようとします。
Bashは名前とその機能を持つ唯一のKorn様シェルであるという事実にもかかわらず、Bashは実際にはbourneシェルよりもkorn派生シェルに近いです。私の考えには実際の利点がないキッチンシンク機能です。標準のbash機能(bourneシェル、posixシェル、または最新のシェルに共通のksh88サブセット)を使用しない開発者、つまりソフトウェアの起動時にベストプラクティスと標準イディオムに固執する開発者は、Linuxにショックを受けました。エクスプロイト作成者は、自分の意図に関係なく「bashism」を自由に使用できるため、Macは現在脆弱になる可能性があります。互換性の観点から/ bin / shで呼び出されると、bashは/ bin / shがログインシェルまたは対話型シェルである場合にのみ、他のkornシェル派生製品よりもbourneシェルのように機能します。このスクリプトは、bashができるすべてのことを自由に実行でき、実際のkornシェル機能またはbash固有の機能を使用していると文句を言ったり警告したりしません。
これが台所の流しの機能であることを確信させようとします。 2つのシナリオがあります。あなたはルーター、ネットワーク接続ストレージなどを作成する組み込み開発者です。最初のものはより大きな環境であり、これはより多くのメモリなどを意味します。費用はより多くかかるが、利益は少ない。だから、これがbashのこの機能の使用を考慮する必要がある理由であれば、FPATHと自動ロード、ksh88機能を代わりに使用する必要はありませんか?環境で関数全体をバイト単位で渡すのではなく? ^$(.*)$ などをフィルタリングするなど、変数を誤って解析できるシェルスクリプトを入力する前に、環境を一括解析して整理することを検討することもできます。
これは変数が何であるかは重要ではなく、スクリプトは変数を参照または使用する必要はなく、まだ脆弱である可能性があることを強調します。
#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl
太陽の下の他のすべてと同様に、上記はPerlスクリプトと同じくらい安全でなければなりません。変数を使用しません。に変更
#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl
また、これがENVまたはそのようなものとは何の関係もないことは役に立ちません。 bashはユニークでなければならないので、誰もがやけどをします。 Bashバージョン2にこの問題があるという事実が私に要点を証明します。この機能を使った人は誰もいませんそうでなければそうする必要があるので、彼らの申請のためにいいえすでに周りに隠れています。これ長い。さらに悪いことは、これを避けることは基本的に不可能であるということです。特徴。たとえば、次のようになります。 'su -'を使って誰かに尋ねると、環境が削除されるという説明があります。マニュアルページを確認すると、99.9%の場合にすぎないことがわかります。このシステムでは、/bin/sh が root のログインシェルで、/bin/sh が bash なので、正しい方法をテストしました。しかし、、この例では、努力する私の.bash_profileを強化してください。既存の名前をルート(アクティブ化)に変更しましたが、私の考えはsuならおそらくsudoでしょう。とにかく次のように変更しました。
exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i
そのため、実際に環境を完全に廃棄し、最小限の環境を使用し、問題が発生しないようにする現在のプロセスの代わりにシェルを実行しました。次に、標準の例の代わりに試してみてください。
%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su
これは、特定の機能を解析することとは関係がなく、エクスプロイトがその機能を参照して使用できることを示しています。関数にルートかどうかをテストするロジックがあると想像できます。この場合は、かなり標準的なエスケープシーケンスを使用してターミナルウィンドウをアイコン化またはドッキングする修正された機能にすぎません。したがって、アイコンの削除をクリックするとDockshockが表示されます。しかし、それでどうなりますか?今これを試してみてください:
%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
何か合わせてみて?窓が床に吸い込まれます。後でこんな感じでした…
%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#
だからそれはすべてです!エクスポートされた関数は実際にはrcスクリプトよりも優先されます。あなたはそれから隠すことはできません。