環境変数で関数を定義する機能自体がセキュリティリスクではないのはなぜですか?


9

私が理解しているように、一般に、環境変数に格納される情報を誰にでも提供しても安全だと考えられています。シェルショックの脆弱性はここでの問題です。これは、bashの新しいインスタンスが起動したときに環境変数内の関数定義の最後のコードが実行され、サーバー上で実行したいコードをだれにも実行させたくないということです。 。関数定義自体は明らかにセキュリティリスクではありませんが、コードを実行するには明示的に呼び出す必要があるため許可されています。

私の質問は、悪意のあるユーザーが悪意のあるコードを一般的なコマンドとして含む関数を単純に定義できずls、スクリプト(または実行されているもの)がいつかこのコマンドを使用することを期待できないのですか?

私が考えていることの例:

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...

回答:


10

これはセキュリティリスクです。これが、他のコンテキストに切り替えるとき(システムのリモート制御、ユーザーの変更など)にできない理由です。

必要な環境変数を作成できる場合、任意のコードを実行できる方法はいくつもあります。例として
考えてみましょう$LD_PRELOAD。その変数を設定できる場合は、ライブラリ関数を置き換えて、そこにコードを挿入できます。$DISPLAY変数を設定し、プログラムが接続するXディスプレイをリダイレクトして、アプリを制御できます。

これがsudo、すべての変数の環境を取り除くなどの理由です。sudoいくつかの選択変数のみを許可します。そして、それらの変数のうち、それらをサニタイズします($TERM変数を通過しますが、異常な文字が含まれている場合は通過しません)。


うわー、私がいつもBASHで実行するいくつかの巨大なスクリプトがsudoで開始したときに、特にパスの周りで奇妙な不可解なエラーが発生するのかと常に疑問に思っていました。問題は、環境変数を取り除くsudoに関する良い説明に感謝します。
Lizardx 2016

3

bashが/ bin / shの場合はそうです。これはボーンシェルの機能ではありませんし、POSIXシェルの機能でもないのではないでしょうか。

Bashは、その名前にもかかわらず、ボーンシェルよりも実際にはKorn派生シェルに近いものであり、その機能を備えた唯一のKornのようなシェルであり、私の意見では、実用的な利点がないキッチンシンク機能です。現代のシェルが共通して持っている、または言い換えれば、優れた実践に身を委ねているボーンシェル、posixシェル、またはksh88サブセットなどの標準のbash機能を回避する開発者は、ソフトウェアがオンのときにショックを受けますlinuxとmac、そして今は潜在的に脆弱です。これは、エクスプロイトの作者が意図にかかわらず、「バシズム」を自由に使用できるためです。/ bin / shとして呼び出された場合、他のKornシェル派生物と比べて互換性が大幅に改善され、bashがKornシェルよりもボーンシェルのように動作する場合は、/ bin / shがログインシェルまたはインタラクティブシェルである場合のみです。

私は、それがキッチンシンク機能であることを説得しようとします。2つのケースがあります。あなたは組み込みの開発者であり、ルーターなどのデバイスを作成します。利益が少ないので、これがbashのこの機能の使用を検討する理由であった場合は、代わりにFPATHとautoload、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-」を使用した場合、誰かに尋ねると、環境が破棄され、manページを確認すると、99.9%と表示されます。このシステム上の/ binに/ shのは、rootのログインシェルであるので、私は、その正しい方法をテストし、/ binに/ shがbashのであるしかし、この例のIの中試み.bash_profileを強化します。私は既存のrootの名前を変更しました(有効になっています)が、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スクリプトよりも優先されます。あなたはそれをかわすことはできません。


1
POSIXは、ドラフト2でエクスポート可能な関数を許可し、その後は許可しませんでした。機能は非常識です。
mikeserv 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.