ベストアンサー1
問題は、アプリケーションのコンテンツが$x
削除されておらず、攻撃者が制御できるデータが含まれている場合、シェルコードが最終的に特権昇格コンテキスト(setuidによって呼び出されるスクリプトなど)アプリケーションで使用できることです。 sudoersスクリプトまたは直接または間接的に使用されます。オフグリッドデータ(CGI、DHCPフック...)を処理します。
場合:
x='(PATH=2)'
それから:
x=$((1-$x)))
PATH
これを2
(攻撃者が制御する可能性のある相対パス)に設定すると、副作用があります。以下PATH
に置き換えることができます。 bash、zsh、またはksh(変数の数値定数のみを許可するダッシュまたはyashではない)でも同じことが起こります。LD_LIBRARY_PATH
IFS
x=$((1-x))
気づく:
x=$((1-$x))
$x
(POSIXによるオプション)(縮小)演算子を実装する一部のシェルでは、負の値に対して正しく機能しません--
(と同様に、これはシェルで算術式をx=-1
評価する必要があることを意味します)。拡張は算術評価の一部として行われるため、問題はありません(以前ではありません)。1--1
"$((1-x))"
x
bash
、zsh
およびksh
(dash
またはそうでないyash
)では、次のような場合x
:
x='a[0$(uname>&2)]'
$((1-$x))
その後、 or の拡張により$((1-x))
コマンドが実行されます( の場合は配列変数でなければなりませんが、たとえば使用できます)。uname
zsh
a
psvar
要約すると、初期化されていないか削除されていない外部データは、シェル算術式で使用しないでください。
$((...))
$[...]
算術評価は(inまたはとも呼ばれる)を介して実行できますが、組み込み関数bash
のzsh
シェル、配列のインデックス付け、構成などによって異なります。let
[
test
declare/typeset/export...
return
break
continue
exit
printf
print
((..))
[[...]]
ksh
// の配列索引付けで機能するため、変数名を引数として使用するすべての組み込み関数 ( / with , , , // , / with , ... )zsh
でも機能します。bash
[
test
-v
read
unset
export
typeset
readonly
print
printf
-v
getopts
数値テスト演算子のオペランドが組み込み関数[[...]]
の有無にかかわらず、算術式として扱われるという事実は、ORで一般に後者が優先される理由の1つです。[
test
bash
zsh
比較する:
$ a='x[1$(uname>&2)]' bash -c '[ "$a" -eq "$b" ]'
bash: line 0: [: x[1$(uname>&2)]: integer expression expected
(セキュリティ):
$ a='x[1$(uname>&2)]' bash -c '[[ "$a" -eq "$b" ]]'
Linux
(uname
実行されました)。
(ksh
、およびに問題[
があります。)[[ ... ]]
変数にリテラル10進整数が含まれていることを確認するには、POSIXlyを使用できます。
case $var in
("" | - | *[!0123456789-]* | ?*-*) echo >&2 not a valid number; exit 1;;
esac
一部のロケールでは、[0-9]
と[[:digit:]]
0123456789 以上が一致するため、あらゆる形式の入力検証/削除を避ける必要があります。
また、場合によっては、前にゼロの付いた数字が8進数(010
時々10、時には8)で処理されることに注意してください。上記のチェックでは、システムよりも大きいシステムを許可することもできます(またはサポートされている最大の整数を使用します)。どんなアプリケーションでも)。対応する整数を使用してください。たとえば、bashは18446744073709551616を0として扱います。なぜなら2 64だからです。したがって、上記のケースの説明に追加のチェックを追加する必要があるかもしれません。たとえば、次のようになります。
(0?* | -0?*)
echo >&2 'Only decimal numbers without leading 0 accepted'; exit 1;;
(-??????????* | [!-]?????????*)
echo >&2 'Only numbers from -999999999 to 999999999 supported'; exit 1;;
例:
$ export 'x=psvar[0$(uname>&2)]'
$ ksh93 -c 'echo "$((x))"'
Linux
ksh93: psvar: parameter not set
$ ksh93 -c '[ x -lt 2 ]'
Linux
ksh93: [: psvar: parameter not set
$ bash -c 'echo "$((x))"'
Linux
0
$ bash -c '[[ $x -lt 2 ]]'
Linux
$ bash -c 'typeset -i a; export a="$x"'
Linux
$ bash -c 'typeset -a a=([x]=1)'
Linux
$ bash -c '[ -v "$x" ]'
Linux
$ bash -c 'read "$x"' < /dev/null
Linux
$ env psvar= bash -c 'unset "$x"'
Linux
$ mksh -c '[[ $x -lt 2 ]]'
Linux
$ zsh -c 'echo "$((x))"'
Linux
0
$ zsh -c 'printf %d $x'
Linux
0
$ zsh -c 'integer x'
Linux
$ zsh -c 'exit $x'
Linux
追加資料:
- http://www.zsh.org/mla/workers/2014/msg01041.html(オリバーキーは
x[0$(...)]
私たちにこの質問をしました。) - http://thread.gmane.org/gmane.comp.standards.posix.austin.general/9971(
lynx news://news.gmane.io/gmane.comp.standards.posix.austin.general/9971
gmaneのWebインターフェースは現在中断されました。) - https://lists.gnu.org/archive/html/bug-bash/2014-12/msg00028.htmlコードの挿入につながる可能性があるもう1つの設計エラーです
bash
。 - bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスク変数を引用符で囲まないと、互いに悪化する可能性があります。