4

C プログラムから、ファイル名をパラメータとしてシェル スクリプトを呼び出したいと考えています。ユーザーはファイル名を制御できます。Cは次のようなものです(初期化/エラーチェックは省略):

sprintf(buf, "/bin/sh script.sh \"%s\"", filename);
system(buf);

ターゲット デバイスは実際には組み込みシステムなので、悪意のあるユーザーを心配する必要はありません。明らかに、これは Web 環境での攻撃ベクトルになります。それでも、たとえば名前に逆引用符が含まれるファイル名がシステムにある場合、シェルが名前の展開を実行するため、コマンドは失敗します。コマンド置換を防ぐ方法はありますか?

4

4 に答える 4

3

fork() を呼び出してから execv() を呼び出すことで、いつでも system() を再実装できます。

http://www.opengroup.org/onlinepubs/000095399/functions/system.html

于 2010-10-27T19:22:12.627 に答える
0

これをCIとしてタグ付けしたので、Cの回答が提供されます。This is a file nameファイル名をエスケープする必要があります。シェルによって適切に処理される新しい文字列を作成して、生成This\ is\ a\ file\ nameまたはbad;rm *;filenameになるようなものを作成しbad\;rm\ \*\;filenameます。次に、それをシェルに渡すことができます。

これを回避する別の方法は、関数forkの1つを使用してシェルを直接実行することです。exec引数をプログラムに直接渡しても、シェルのコマンドラインが拡張または解釈されることはありません。

于 2010-10-27T19:24:02.170 に答える
0

システム関数で「unalias」をトリガーしてみてください。

于 2010-10-27T19:20:10.253 に答える
0

sharth が言ったように、systembutforkexecv自分自身を使用しないでください。しかし、どのようにして文字列を安全にシェルに渡せるようにするかという質問に答えるには (どうしても を使用したい場合system)、文字列をエスケープする必要があります。これを行う最も簡単な方法は、最初にすべての'(一重引用符) を'\''(一重引用符、バックスラッシュ、一重引用符、一重引用符) に置き換えて'から、文字列の先頭と末尾に (一重引用符) を追加することです。もう 1 つの非常に簡単な (しかし通常はあまり効率的ではない) 方法は、すべての文字の前にバックスラッシュを配置することですが、埋め込まれた改行を処理するために特別な引用符のトリックを行う必要があるため、最初の方法をお勧めします。

于 2010-10-27T19:35:07.740 に答える