web-dev-qa-db-ja.com

すべての危険な文字がエスケープされたときのコマンドインジェクション?

OWASP 推奨 すべての特殊文字をエスケープするコマンドインジェクションに対する防御として(ホワイトリストアプローチを使用できない場合)。

私はこれを行う簡単なPHPスクリプトを書きました:

$input = $_GET['x'];
$dangerous = array("{", "}", "", "(", ")", "<", ">", "&", "*", "|", "=", "?", ";", "[", "]", "$", "–", "~", "!", ".", "%", "/", ":", "+", "'");

$input = str_replace("\\","\\\\",$input);
foreach ($dangerous as $char) {
    $input = str_replace($char,"\\$char",$input);
}

echo  passthru("echo '$input'");
echo "<br><br>executed: " . $input ;

ただし、'を入力として使用すると、エラー(Unterminated quoted string)。

これらの文字のエスケープをバイパスすることはできませんでしたが、無効な構文のために攻撃者がbashエラーを生成することは理想的ではないようです。

これらの特殊文字のエスケープをバイパスする方法はありますか?

ホワイトリストまたはescapeshellcmdのような既存のメカニズムを使用することをお勧めします。特殊文字のエスケープをバイパスするという一般的な考え方にもっと興味があります。

1
tim

バイパスを思いついた。

@Sjoerdが述べたように、バックスラッシュエスケープは一重引用符付き文字列では機能しないため、一重引用符付き文字列から抜け出すことができます。

「危険な」文字のリストには、バックティックやハッシュは含まれていません。これにより、次のようなペイロードが機能します。

' `hostname` #

またはurlencoded:

%27%20%60hostname%60%20%23

単一引用符は\'(通常の引用符として扱われ、'\'echoの最初の引数になります)になり、バッククォート内のコマンドは、echoに渡されたコマンド出力で実行されます。ハッシュはコメントとして扱われ、シェルは末尾の単一引用符を無視して、構文エラーを回避します。

3
Tom Hudson