web-dev-qa-db-ja.com

このBashコードはコードインジェクションに対して脆弱ですか?

jidoka の動作をエミュレートして、Bashでのエラー処理を強化するために「サイレント」という名前のlibreプログラムを書いています。

私の質問は、次のように、呼び出し側のプログラムが入力を二重引用符で囲んでいる場合、そのevalがコードインジェクションに対して脆弱かどうかです。

silently "function" "command \"${@}\""

静かにこのコードを持っている:

#! /bin/bash


mainFunction () {
    if [ "${function}" != "" ]; then
        function="${function}: "
    fi

    error=$(eval "${command}" 2>&1)

    if [ ${?} -ne 0 ]; then
        echo "${function}${error}" >&2
        exit "${exit}"
    fi
}


setArguments () {
    if [ "${1}" == "-try" ]; then
        function="${2}"
        command="${3}"
        exit="0"
    else
        function="${1}"
        command="${2}"
        exit="1"
    fi
}


setArguments "${@}"
mainFunction "${@}"

2つの簡単な観察があります。

  • evalの使用は非常に危険であり、変数${command}は効率的にサニタイズされていません。 (バッククォート、ピリオド、制御文字などを含めることができます)

  • bashを使用して賢明な操作を行うことは、脆弱性が多いため推奨されません。重要なスクリプトには、貧弱なShelldashなど)を使用することをお勧めします。 (またはPythonまたはPerlのようなより進化した言語)。

  • 予期しない動作の例:

    /path/to/silently Blah "'echo `date`;return 1'"
    Blah: Wed Oct 16 08:26:16 CEST 2019
    

    backticksの間のコマンドが実行される場合、セミコロンはコマンドの分離を行い(通常どおり)、return 1強制mainFunctionは、結果をエラーと見なして出力します。

    @ gitlab.comで公開したコードを使用すると、この結果は次のようになります。

    /path/to/silently Blah "'echo `date`;return 1'"
    silently: surplus arguments on: Blah 'echo Thu Oct 17 13:54:36 CEST 2019;return 1'
    Note that command must be quoted
    

    dateコマンドが実行され、結果がエラーテキストとして表示されます。

    それからあなたは試すことができます:

    /path/to/silently Blah "'echo `cat /etc/passwd`;return 1'"
    

bash を使用して賢明な操作を行うことは可能ですが、強い経験が必要です。私は個人的にそれをしないことをお勧めします!

2
F. Hauri

まず、ローカルシェルスクリプトへのコードインジェクションを心配する必要はありません。

これをリモートで実行している場合は、問題になる可能性があります。以下の例を試してみましたが、1つのWord以外の追加のコマンドを挿入する直接的な方法は見つかりませんでした。運用環境で許可されているコマンドもホワイトリストに登録する必要があることに注意してください。

例:サイレントに「コマンド\ "whoami \"」

#! /bin/bash
command="${@}"
result=$(eval "${command}" 2>&1)
echo "${result}"
0