SV.CODE_INJECTION.SHELL_EXEC

コマンド インジェクションの脆弱性

system() 関数または popen() 関数を外部の影響を受ける入力とともに使用する場合、攻撃プロセスの特権を使用して、悪意のあるユーザーは文字列を挿入して任意のコマンドとコードを実行することができます。たとえば、攻撃者はセミコロンを挿入して 1 つのコマンドを終了し、新しい関連のない実行コマンドを挿入することもできます。

脆弱性とリスク

コマンドインジェクションの影響を受けやすい system() 呼び出しまたは popen() 呼び出しは、次のようになることがあります。

  • 悪意のあるコードの実行
  • 危険にさらされたシステムにアクセスするための新しいユーザーアカウントの作成
  • 通常のユーザーより高度な特権レベルの任意のコマンドの実行

最悪の場合は、攻撃者は、ルートパーティションの内容の削除など、システムを制御する文字列を挿入することもできます。

軽減と防止

この指摘を回避するには、次のことを実行するのがベストです。

  • システム呼び出しで定数文字列のみを使用
  • コマンドを実行する前に承認コードを追加
  • 外部プロセスではなくライブラリ呼び出しを使用
  • ブラックリスト入力検証ではなくホワイトリスト入力検証を使用
  • 外部実行プログラムを実行するために関数の exec ファミリーを使用
  • ユーザーが外部実行プログラムに書き込むことはできないことを確認
  • 既存ライブラリへの呼び出しで機能をプログラムに直接実装

脆弱コード例

コピー
  char *constbuf = "bash";
  int main()
  {
       char buf[100];
       scanf("%s",buf);
       system("echo \"constant string: no warning\"");
  
       system(constbuf);
       system(buf);
      popen("echo OK","r");
      popen(constbuf, "r");
      popen(buf, "r");
      return 0;
 
 }

この例では、Klocwork は 9 行目で、system() 関数がユーザーによる影響を受ける可能性のあるコマンドラインを受け入れ、これが任意コードの実行を生じることになることを示す指摘レポートを生成します。類似した警告が 12 行目で関数 popen() について報告されています。いずれの場合も、攻撃者がコマンドを挿入して悪意のあるコードを実行し、システムを制御したり、ルートパーティションを削除することもできます。6 行目と 8 行目のシステムの関数呼び出しで、定数文字列およびライブラリ呼び出しを引数として使用するため、それらはコード挿入の可能性に対してオープンではなく、フラグは立てません。

関連チェッカー