私はsetuidバイナリのセキュリティに触れています(明らかに私が見つけたすべてを作者に公開するため)。シェルスクリプトを呼び出して環境を削除しないため、ランダムなコード実行の脆弱性があると確信しています。 Bashについて考えましたが、export -f
実際に概念証明を行うことはできません。
基本的な問題は、何らかの理由でBASH_FUNC_foobar%%
(foobar
エクスポートされた関数がある場合)、一部の子プロセスの環境では不思議に消えることです。シェルでない場合でも動作します。
% env 'BASH_FUNC_foobar%%=() { echo pwd lol; }' env | grep BASH
BASH_FUNC_foobar%%=() { echo pwd lol; }
env | grep BASH
ただし、実際のプログラム名に変更して環境をダンプするように変更すると(デフォルトではsystem("env")
Cソースコードから)、変数は削除されます。sh
呼び出すコマンドを指定すると、同じことが発生します。しかし、奇妙なことに指定すると、bash
関数は正しく選択されます。
私のテストシステム/bin/sh
ではdash
。
一体何が起こったのでしょうか?この変数はなぜ消えますか?
答え1
多くのLinuxシステムでは、/bin/sh
これは実際に/bin/dash
。
すでに述べたようにコメントby @MichaelHomerは/bin/dash
環境を整理し、forを含む/^[a-zA-Z_][a-zA-Z_0-9]*=.*/
フォームの一部ではないすべての文字列を削除します。BASH_FUNC_foo%%=...
%%
これはdash
OpenBSD ksh
(およびそれに基づくもの)mksh
にのみ適用されます。他のシェルではこれを行いません。
たとえば、Debianでは/bin/sh
次のようになりますdash
。
$ env - '@#%=' 'foo%%=bar' /bin/sh -c /usr/bin/printenv
PWD=/your/cwd
$ env - '@#%=' 'foo%%=bar' /usr/bin/printenv
@#%=
foo%%=bar
$ env - '@#%=' 'foo%%=bar' /bin/bash -c /usr/bin/printenv
[...]
@#%=
foo%%=bar
ソース参照用に確認できますsrc/var.cdash
ソースから:
initvar();
for (envp = environ ; *envp ; envp++) {
p = endofname(*envp);
if (p != *envp && *p == '=') {
setvareq(*envp, VEXPORT|VTEXTFIXED);
}
}
dash
execが別のバイナリの場合、env
ここに渡された引数はexecve
変数のリストで(listvars(VEXPORT, VUNSET, 0)
マクロ呼び出しを介してenvironment()
)動的に設定されます。